diff --git a/.gitignore b/.gitignore index c315e61..3b508dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ rpcs.toml wallets.toml +createRollupManagerOutput.example.json +networks/local/test* # If you prefer the allow list template instead of the deny list, see community template: # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore @@ -22,3 +24,7 @@ wallets.toml # Go workspace file go.work +docker/gethData + +# Node +node_modules \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c97e0de --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,57 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "deploy rollup manager", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd", + "args": [ + "deploy-rm", + "-l1", "local", + "-w", "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "-wp", "testonly", + "-skip-confirmation", + "-i", "${workspaceFolder}/createRollupManagerParams.example.json", + "-o", "${workspaceFolder}/createRollupManagerOutput.example.json", + "-alias", "test_etrog", + "-scv", "etrog", + ] + }, + { + "name": "add rollup type", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd", + "args": [ + "add-rt", + "-l1", "local", + "-w", "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "-wp", "testonly", + "-skip-confirmation", + "-i", "${workspaceFolder}/addRollupTypeParams.example.json", + "-alias", "test_etrog", + "-scv", "etrog", + ] + }, + { + "name": "create rollup", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd", + "args": [ + "create-r", + "-l1", "local", + "-w", "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "-wp", "testonly", + "-skip-confirmation", + "-i", "${workspaceFolder}/createRollupParams.example.json", + "-alias", "test_etrog", + "-scv", "etrog", + ] + } + ] +} \ No newline at end of file diff --git a/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266.keystore b/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266.keystore new file mode 100644 index 0000000..96b662b --- /dev/null +++ b/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266.keystore @@ -0,0 +1 @@ +{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"d005030a7684f3adad2447cbb27f63039eec2224c451eaa445de0d90502b9f3d","cipherparams":{"iv":"dc07a54bc7e388efa89c34d42f2ebdb4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf2ec55ecae11171de575112cfb16963570533a9c46fb774473ceb11519eb24a"},"mac":"3eb180d405a5da6e462b2adc00091c14856c91d574bf27348714506357d6e177"},"id":"035454db-6b6d-477f-8a79-ce24c10b185f","version":3} \ No newline at end of file diff --git a/README.md b/README.md index a8f1205..71330c4 100644 --- a/README.md +++ b/README.md @@ -49,4 +49,65 @@ Unfortunately the base genesis file cannot be retrieved from L1. Therefore they - `-output API3.json` file where the genesis will be stored 4. Generate the network config section of the bridge service: `go run ./cmd bridge -l1 sepolia -rm cardona -r API3 -output API3Bridge.toml` -Note that step 1 only needs to be done once, if there are multiple CDKs attaced to the same rollup manager, with a single run it will be enough \ No newline at end of file +Note that step 1 only needs to be done once, if there are multiple CDKs attaced to the same rollup manager, with a single run it will be enough + +#### Generate docker image for fork7 + +1. Start the dimulated L1 `go run ./cmd start-l1` +2. Deploy rollup manager +```bash +go run ./cmd deploy-rm \ + -l1 local \ + -w 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 -wp testonly \ + -skip-confirmation \ + -i ./createRollupManagerParams.example.json \ + -o ./createRollupManagerOutput.example.json \ + -alias test_etrog \ + -scv etrog +``` +3. Add rollup type +```bash +go run ./cmd add-rt \ + -l1 local \ + -w 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 -wp testonly \ + -skip-confirmation \ + -i ./addRollupTypeParams.example.json \ + -alias test_etrog \ + -scv etrog +``` +4. Create rollup +```bash +go run ./cmd create-r \ + -l1 local \ + -w 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 -wp testonly \ + -skip-confirmation \ + -i ./createRollupParams.example.json \ + -alias test_etrog \ + -scv etrog +``` +5. Deploy and setup DAC +```bash +go run ./cmd deployset-dac \ + -l1 local \ + -w 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 -wp testonly \ + -skip-confirmation \ + -rm-alias test_etrog \ + -r-alias zkevm \ + -init +``` +6. Mint POL tokens for the sequencer +```bash +go run ./cmd mint \ + -l1 local \ + -w 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 -wp testonly \ + -skip-confirmation \ + -token 0x5fbdb2315678afecb367f032d93f642f64180aa3 \ + -amount 99999999999999999999999999999999999999999 +``` +7. Export L1 container `go run ./cmd export-l1 -image validium-fork7` +8. Generate genesis config: +```bash +go run ./cmd genesis -l1 local -rm test_etrog -r zkevm -output localtest.genesis.json +``` + +Now you can use the generated image `validium-fork7` and the genesis file `localtest.genesis.json` to test a cdk-validium-node using etrog diff --git a/addRollupTypeParams.example.json b/addRollupTypeParams.example.json new file mode 100644 index 0000000..94286b2 --- /dev/null +++ b/addRollupTypeParams.example.json @@ -0,0 +1,7 @@ +{ + "useMockVerifier": true, + "consensusType": "validium", + "forkID": 7, + "genesisRoot": "0x489e44072604e671274ea693d5309e797fb37a3e0d91e5b0f04639c251c05332", + "description": "This is a test. Validium_Etrog_Fork7" +} \ No newline at end of file diff --git a/cmd/addrolluptype.go b/cmd/addrolluptype.go new file mode 100644 index 0000000..7e9001a --- /dev/null +++ b/cmd/addrolluptype.go @@ -0,0 +1,235 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path" + + verifierelderberry "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/fflonkverifier" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/verifierrolluphelpermock" + verifieretrog "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/fflonkverifier" + "github.com/0xPolygon/cdk-contracts-tooling/rollup" + "github.com/0xPolygon/cdk-contracts-tooling/rollupmanager" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/urfave/cli/v2" +) + +const ( + mockVerifierFlagName = "mock-verifier" + addRollupTypeFileFlagName = "add-rollup-type-parameters-file" + rollupConsensus = "rollup" + validiumConsensus = "validium" +) + +var ( + addRollupTypeCommand = &cli.Command{ + Name: "add-rollup-type", + Aliases: []string{"add-rt"}, + Usage: "Deploy necessary implementations and add type to a rollup manager", + Action: addRollupTypeCmd, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + smartContractVersionFlag, + &cli.StringFlag{ + Name: rollupManagerAliasFlagName, + Aliases: []string{"alias"}, + Usage: "Name of the rollup manager where the rollup type will be added to", + Required: true, + }, + &cli.PathFlag{ + Name: addRollupTypeFileFlagName, + Aliases: []string{"params", "file-params", "i"}, + Usage: `TODO: description`, + Required: true, + }, + }, + } +) + +func addRollupTypeCmd(cliCtx *cli.Context) error { + // Load configs + baseDir, err := checkWorkingDir() + if err != nil { + return err + } + _, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + params, err := loadAddRollupTypeParams(cliCtx.String(addRollupTypeFileFlagName)) + if err != nil { + return err + } + rmAlias := cliCtx.String(rollupManagerAliasFlagName) + l1Network := cliCtx.String(l1FlagName) + rollupManagerPath := path.Join(baseDir, "networks", l1Network, rmAlias) + rm, err := rollupmanager.LoadFromFile(client, path.Join(rollupManagerPath, "rollupManager.json")) + if err != nil { + return err + } + if _, err := os.Stat(path.Join(baseDir, "genesis", params.GenesisRoot.Hex()+".json")); errors.Is(err, os.ErrNotExist) { + return fmt.Errorf( + "no genesis file found for root %s. Please add genesis file to the genesis directory", + params.GenesisRoot.Hex(), + ) + } + contractsVersion := cliCtx.String(smartContractVersionFlagName) + + // Check permissions + hasRole, err := rm.Contract.HasRole(nil, rollupmanager.ADD_ROLLUP_TYPE_ROLE, auth.From) + if err != nil { + return err + } + if !hasRole { + _, err = sendTxWithConfirmation( + cliCtx, client, fmt.Sprintf( + "Send tx to grant ADD_ROLLUP_TYPE_ROLE role to %s", + auth.From, + ), + func() (*types.Transaction, error) { + return rm.Contract.GrantRole(auth, rollupmanager.ADD_ROLLUP_TYPE_ROLE, auth.From) + }, + ) + if err != nil { + return err + } + } + + // if ((await rollupManagerContract.hasRole(ADD_ROLLUP_TYPE_ROLE, deployer.address)) == false) + // await rollupManagerContract.grantRole(ADD_ROLLUP_TYPE_ROLE, deployer.address); + + // Verifier + if params.VerifierImplementation != zeroAddr { + fmt.Println("using verifier:", params.VerifierImplementation) + } else { + fmt.Println("deploying verifier") + var deployFn func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) + if params.UseMockVerifier { + deployFn = func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) { + _, tx, _, err := verifierrolluphelpermock.DeployVerifierrolluphelpermock(auth, client) + return tx, err + } + } else { + switch contractsVersion { + case etrog: + deployFn = func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) { + _, tx, _, err := verifieretrog.DeployFflonkverifier(auth, client) + return tx, err + } + case elderbeerry: + deployFn = func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) { + _, tx, _, err := verifierelderberry.DeployFflonkverifier(auth, client) + return tx, err + } + } + } + addr, err := deploy( + cliCtx, auth, client, deployFn, + "Do you want to send the tx that will deploy the verifier?", + ) + if err != nil { + return err + } + fmt.Println("Verifier implementation deployed at:", addr) + params.VerifierImplementation = addr + } + + // Consensus + if params.ConsensusImplementation != zeroAddr { + fmt.Println("using consensus:", params.ConsensusImplementation) + } else { + consensus, err := rollup.GetConsensus( + contractsVersion, params.ConsensusType, client, auth, rm, nil, + ) + if err != nil { + return err + } + + addr, err := deploy( + cliCtx, auth, client, consensus.Deploy, + "Do you want to send the tx that will deploy the consensus?", + ) + if err != nil { + return err + } + fmt.Println("Consensus implementation deployed at:", addr) + params.ConsensusImplementation = addr + } + + // Last rollup type ID + rollupTypeCounterBeforeTx, err := rm.Contract.RollupTypeCount(nil) + if err != nil { + return err + } + + // Add rollup type + _, err = sendTxWithConfirmation( + cliCtx, client, fmt.Sprintf( + "Send add rollup type tx? Following params are going to be used:\n"+ + "- consensus implementation: %s\n"+ + "- verifier implementation: %s\n"+ + "- fork ID: %d\n"+ + "- rollup compatibility ID: 0\n"+ + "- genesis root: %s\n"+ + "- description: %s\n", + params.ConsensusImplementation, params.VerifierImplementation, + params.ForkID, params.GenesisRoot, params.Description, + ), + func() (*types.Transaction, error) { + return rm.Contract.AddNewRollupType( + auth, + params.ConsensusImplementation, params.VerifierImplementation, + params.ForkID, 0, params.GenesisRoot, params.Description, + ) + }, + ) + if err != nil { + return err + } + rollupTypeCounterAfterTx, err := rm.Contract.RollupTypeCount(nil) + if err != nil { + return err + } + if rollupTypeCounterBeforeTx == rollupTypeCounterAfterTx { + return errors.New("something went wrong, rollup type counter is still the same after sending the tx") + } + fmt.Println("Rollup type added with ID:", rollupTypeCounterAfterTx) + rt, err := rm.Contract.RollupTypeMap(nil, rollupTypeCounterAfterTx) + if err != nil { + return err + } + fmt.Println(common.Hash(rt.Genesis).Hex()) + // TODO: assert that the rt output matches the expected inputs + return nil +} + +type AddRollupTypeParams struct { + // If provided, will use this instead of deploying a new verifier implementation + VerifierImplementation common.Address `json:"verifierImplementation"` + // If true will deploy a mock verifier instead of a real one + UseMockVerifier bool `json:"useMockVerifier"` + // If provided, will use this instead of deploying a new consensus implementation + ConsensusImplementation common.Address `json:"consensusImplementation"` + // Consensus type. Supported values: [rollup, validium] + ConsensusType string `json:"consensusType"` + ForkID uint64 `json:"forkID"` + GenesisRoot common.Hash `json:"genesisRoot"` + Description string `json:"description"` +} + +func loadAddRollupTypeParams(file string) (*AddRollupTypeParams, error) { + data, err := os.ReadFile(file) + if err != nil { + return nil, err + } + var params AddRollupTypeParams + return ¶ms, json.Unmarshal(data, ¶ms) +} diff --git a/cmd/common.go b/cmd/common.go index c1bccfd..03b524e 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -1,23 +1,188 @@ package main import ( + "bufio" + "context" + "errors" "fmt" "os" "path" + "time" + + "github.com/0xPolygon/cdk-contracts-tooling/config" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/common/erc1967proxy" + "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/ethclient" + "github.com/urfave/cli/v2" ) const ( repoName = "cdk-contracts-tooling" ) +var ( + zeroAddr = common.Address{} +) + func checkWorkingDir() (string, error) { baseDir, err := os.Getwd() if err != nil { return "", err } - _, f := path.Split(baseDir) + dir, f := path.Split(baseDir) + if f == "cmd" { + os.Chdir(dir) + return checkWorkingDir() + } if f != repoName { return "", fmt.Errorf("run the command from the root of the (%s)", repoName) } return baseDir, nil } + +func askForConfirmation(cliCtx *cli.Context, msg string) error { + fmt.Println(msg, " (yes / no): ") + skip := cliCtx.Bool(skipConfirmationFlagName) + if skip { + fmt.Println("(CONFIRMATION SKIPPED)") + return nil + } + reader := bufio.NewReader(os.Stdin) + answer, err := reader.ReadString('\n') + if err != nil { + return err + } + if answer != "yes" { + return errors.New("confirmation rejected") + } + return nil +} + +func loadAuthAndClient(cliCtx *cli.Context) (common.Address, *bind.TransactOpts, *ethclient.Client, error) { + fmt.Println("loading RPC") + rpcs, err := config.LoadRPCs() + if err != nil { + return common.Address{}, nil, nil, err + } + l1Network := cliCtx.String(l1FlagName) + client, err := rpcs.GetClient(l1Network) + if err != nil { + return common.Address{}, nil, nil, err + } + chainID, err := rpcs.GetChainID(l1Network) + if err != nil { + return common.Address{}, nil, nil, err + } + + fmt.Println("loading wallet") + wallets, err := config.LoadWallets() + if err != nil { + return common.Address{}, nil, nil, err + } + walletAddr := cliCtx.String(walletFlagName) + walletPass := cliCtx.String(walletPasswordFlagName) + auth, err := wallets.GetAuth(walletAddr, walletPass, chainID) + if err != nil { + return common.Address{}, nil, nil, err + } + return common.HexToAddress(walletAddr), auth, client, nil +} + +// waitTxToBeMined boolean indicates if the tx was successful +func waitTxToBeMined(parentCtx context.Context, client *ethclient.Client, tx *types.Transaction, timeout time.Duration) (bool, error) { + ctx, cancel := context.WithTimeout(parentCtx, timeout) + defer cancel() + receipt, err := bind.WaitMined(ctx, client, tx) + if errors.Is(err, context.DeadlineExceeded) { + return false, err + } else if err != nil { + return false, err + } + return receipt.Status == types.ReceiptStatusSuccessful, nil +} + +func getTimeout(cliCtx *cli.Context) time.Duration { + timeout := cliCtx.Duration(timeoutFlagName) + if timeout == 0 { + return defaultTimeout + } + return timeout +} + +func deployProxy( + cliCtx *cli.Context, + auth *bind.TransactOpts, + client *ethclient.Client, + implementationAddr common.Address, + initializeParams []byte, +) (common.Address, error) { + return sendTxWithConfirmation( + cliCtx, client, + "Do you want to send the tx that will deploy the proxy?", + func() (*types.Transaction, error) { + _, tx, _, err := erc1967proxy.DeployErc1967proxy( + auth, + client, + implementationAddr, + initializeParams, + ) + return tx, err + }, + ) +} + +func sendTxWithConfirmation( + cliCtx *cli.Context, + client *ethclient.Client, + confirmationQuestion string, + sendTx func() (*types.Transaction, error), +) (common.Address, error) { + err := askForConfirmation(cliCtx, confirmationQuestion) + if err != nil { + return common.Address{}, err + } + fmt.Println("sending tx") + tx, err := sendTx() + if err != nil { + return common.Address{}, err + } + + fmt.Printf("Tx %s sent\n", tx.Hash()) + timeout := getTimeout(cliCtx) + fmt.Printf("Waiting for the tx to be mined, this will timeout after %s\n", timeout) + ok, err := waitTxToBeMined(cliCtx.Context, client, tx, timeout) + if err != nil { + return common.Address{}, err + } + if !ok { + return common.Address{}, errors.New("the transaction was mined, but it was not executed successfuly") + } + receipt, err := client.TransactionReceipt(cliCtx.Context, tx.Hash()) + if err != nil { + return common.Address{}, err + } + return receipt.ContractAddress, nil +} + +func deploy( + cliCtx *cli.Context, + auth *bind.TransactOpts, + client *ethclient.Client, + deploy func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error), + confirmationQuestion string, +) (common.Address, error) { + // Deploy verifier implementation + verifierImplAddr, err := sendTxWithConfirmation( + cliCtx, client, confirmationQuestion, + func() (*types.Transaction, error) { + return deploy(auth, client) + }, + ) + if err != nil { + return common.Address{}, err + } + + return verifierImplAddr, nil +} diff --git a/cmd/common_test.go b/cmd/common_test.go new file mode 100644 index 0000000..aaefa35 --- /dev/null +++ b/cmd/common_test.go @@ -0,0 +1,45 @@ +package main + +import ( + "context" + "os" + "path" + "testing" + + "github.com/0xPolygon/cdk-contracts-tooling/docker" + "github.com/ethereum/go-ethereum/ethclient" +) + +const ( + thisDir = "cmd" + walletAddr = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" + walletPass = "testonly" +) + +func TestMain(t *testing.M) { + baseDir, err := os.Getwd() + if err != nil { + panic(err) + } + _, f := path.Split(baseDir) + if f == thisDir { + err = os.Chdir("..") + if err != nil { + panic(err) + } + } + ctx := context.Background() + if err := docker.StartMockL1Docker(ctx); err != nil { + panic(err) + } + defer func() { + if err := docker.StopMockL1Docker(); err != nil { + panic(err) + } + }() + t.Run() +} + +func getClient() (*ethclient.Client, error) { + return ethclient.Dial("http://localhost:8545") +} diff --git a/cmd/createrollup.go b/cmd/createrollup.go new file mode 100644 index 0000000..16db9ca --- /dev/null +++ b/cmd/createrollup.go @@ -0,0 +1,158 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "path" + + "github.com/0xPolygon/cdk-contracts-tooling/rollupmanager" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/urfave/cli/v2" +) + +const ( + createRollupFileFlagName = "create-rollup-parameters-file" +) + +var ( + createRollupCommand = &cli.Command{ + Name: "create-rollup", + Aliases: []string{"create-r"}, + Usage: "Create a new rollup and attach it to a rollup manager", + Action: createRollupCmd, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + smartContractVersionFlag, + &cli.StringFlag{ + Name: rollupManagerAliasFlagName, + Aliases: []string{"alias"}, + Usage: "Name of the rollup manager that the rollup to be created will be attached to", + Required: true, + }, + &cli.PathFlag{ + Name: createRollupFileFlagName, + Aliases: []string{"params", "file-params", "i"}, + Usage: `TODO: description`, + Required: true, + }, + }, + } +) + +func createRollupCmd(cliCtx *cli.Context) error { + // Load configs + baseDir, err := checkWorkingDir() + if err != nil { + return err + } + _, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + params, err := loadCreateRollupRollupTypeParams(cliCtx.String(createRollupFileFlagName)) + if err != nil { + return err + } + rmAlias := cliCtx.String(rollupManagerAliasFlagName) + l1Network := cliCtx.String(l1FlagName) + rollupManagerPath := path.Join(baseDir, "networks", l1Network, rmAlias) + rm, err := rollupmanager.LoadFromFile(client, path.Join(rollupManagerPath, "rollupManager.json")) + if err != nil { + return err + } + + // Check permissions + hasRole, err := rm.Contract.HasRole(nil, rollupmanager.CREATE_ROLLUP_ROLE, auth.From) + if err != nil { + return err + } + if !hasRole { + _, err = sendTxWithConfirmation( + cliCtx, client, fmt.Sprintf( + "Send tx to grant CREATE_ROLLUP_ROLE role to %s", + auth.From, + ), + func() (*types.Transaction, error) { + return rm.Contract.GrantRole(auth, rollupmanager.CREATE_ROLLUP_ROLE, auth.From) + }, + ) + if err != nil { + return err + } + } + + // Create rollup + var ( + createRollupTx *types.Transaction + ) + _, err = sendTxWithConfirmation( + cliCtx, client, fmt.Sprintf( + "Send create rollup tx? Following params are going to be used:\n"+ + "- RollupTypeID: %d\n"+ + "- ChainID: %d\n"+ + "- AdminZkEVM: %s\n"+ + "- TrustedSequencer: %s\n"+ + "- GasTokenAddress: %s\n"+ + "- TrustedSequencerURL: %s\n"+ + "- NetworkName: %s\n", + params.RollupTypeID, params.ChainID, + params.AdminZkEVM, params.TrustedSequencer, params.GasTokenAddress, + params.TrustedSequencerURL, params.NetworkName, + ), + func() (*types.Transaction, error) { + createRollupTx, err = rm.Contract.CreateNewRollup( + auth, params.RollupTypeID, params.ChainID, + params.AdminZkEVM, params.TrustedSequencer, params.GasTokenAddress, + params.TrustedSequencerURL, params.NetworkName, + ) + return createRollupTx, err + }, + ) + if err != nil { + return err + } + rID, err := rm.Contract.ChainIDToRollupID(nil, params.ChainID) + if err != nil { + return err + } + rData, err := rm.Contract.RollupIDToRollupData(nil, rID) + if err != nil { + return err + } + fmt.Printf("Rollup deployed: %+v\n", rData) + fmt.Println("Adding rollup info to the networks directory") + rt, err := rm.Contract.RollupTypeMap(nil, 1) + if err != nil { + return err + } + fmt.Println(common.Hash(rt.Genesis).Hex()) + // TODO: assert that rollup has the expected params + return importRollupManager(cliCtx.Context, l1Network, rm.Address.Hex(), rmAlias) +} + +type CreateRollupParams struct { + RollupTypeID uint32 `json:"rollupTypeID"` + ChainID uint64 `json:"chainID"` + AdminZkEVM common.Address `json:"adminZkEVM"` + TrustedSequencer common.Address `json:"trustedSequencer"` + GasTokenAddress common.Address `json:"gasTokenAddress"` + TrustedSequencerURL string `json:"trustedSequencerURL"` + NetworkName string `json:"networkName"` + // Consensus type. Supported values: [rollup, validium] + ConsensusType string `json:"consensusType"` +} + +func loadCreateRollupRollupTypeParams(file string) (*CreateRollupParams, error) { + data, err := os.ReadFile(file) + if err != nil { + return nil, err + } + var params CreateRollupParams + return ¶ms, json.Unmarshal(data, ¶ms) +} diff --git a/cmd/dac.go b/cmd/dac.go new file mode 100644 index 0000000..815e48f --- /dev/null +++ b/cmd/dac.go @@ -0,0 +1,211 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "math/big" + "os" + "sort" + "strings" + + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/polygondatacommittee" + "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/ethclient" + "github.com/urfave/cli/v2" +) + +var ( + deployDACCommand = &cli.Command{ + Name: "deploy-dac", + Aliases: []string{}, + Usage: "Deploy the Data Availability smart contract", + Action: deployDACCmd, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + &cli.StringFlag{ + Name: implementationAddressFlagName, + Aliases: []string{"implementation", "impl"}, + Usage: `Smart contract address of a DAC implementation. If provided, it will be used for the proxy implementation instead of deploying a new one`, + Required: false, + }, + }, + } + setupDACCommand = &cli.Command{ + Name: "setup-dac", + Aliases: []string{}, + Usage: "Setup a Data Availability smart contract", + Action: setupDAC, + Flags: []cli.Flag{ + l1Flag, + addressFlag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + &cli.PathFlag{ + Name: setupFilePathFlagName, + Aliases: []string{"f"}, + Usage: `File path of a JSON that looks like {"requiredSingatures": X, "members": [{"address": "0x...", "url": "http://..."}]}`, + Required: true, + }, + }, + } +) + +func deployDACCmd(cliCtx *cli.Context) error { + _, err := checkWorkingDir() + if err != nil { + return err + } + _, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + + dacAddrStr := cliCtx.String(implementationAddressFlagName) + var dacImpl common.Address + if dacAddrStr != "" { + dacImpl = common.HexToAddress(dacAddrStr) + fmt.Printf("Using %s as DAC implementation (previously deployed)\n", dacImpl) + } else { + dacImpl, err = deployDACImpl(cliCtx, auth, client) + if err != nil { + return err + } + fmt.Println("DAC implementation deployed at", dacImpl) + } + _, err = deployDACProxy(cliCtx, auth, client, dacImpl) + return err +} + +func deployDACImpl( + cliCtx *cli.Context, + auth *bind.TransactOpts, + client *ethclient.Client, +) (common.Address, error) { + return sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "Do you want to send the tx that will deploy the DAC from the address %s?", + auth.From, + ), + func() (*types.Transaction, error) { + _, tx, _, err := polygondatacommittee.DeployPolygondatacommittee(auth, client) + return tx, err + }, + ) +} + +func deployDACProxy( + cliCtx *cli.Context, + auth *bind.TransactOpts, + client *ethclient.Client, + dacImpl common.Address, +) (common.Address, error) { + // Deploy proxy + dacABI, err := polygondatacommittee.PolygondatacommitteeMetaData.GetAbi() + if err != nil { + return common.Address{}, err + } + if dacABI == nil { + return common.Address{}, errors.New("GetABI returned nil") + } + initializeCallData, err := dacABI.Pack("initialize") + if err != nil { + return common.Address{}, err + } + proxyAddr, err := deployProxy( + cliCtx, + auth, + client, + dacImpl, + initializeCallData, + ) + if err != nil { + return common.Address{}, err + } + fmt.Println("DAC proxy deployed at", proxyAddr) + return proxyAddr, nil + +} + +func setupDAC(cliCtx *cli.Context) error { + _, err := checkWorkingDir() + if err != nil { + return err + } + walletAddr, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + + fmt.Println("loading setup file") + setupDACFilePath := cliCtx.String(setupFilePathFlagName) + data, err := os.ReadFile(setupDACFilePath) + if err != nil { + return err + } + var setup DACSetup + err = json.Unmarshal(data, &setup) + if err != nil { + return err + } + fmt.Printf(` +DAC Configuration: +required signatures %d / %d. +Members: %+v + +`, setup.RequiredSingatures, len(setup.Members), setup.Members, + ) + dacAddr := cliCtx.String(addressFlagName) + _, err = sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "Do you want to send the tx that will setup the DAC deployed at %s from the address %s with the configuration shown above?", + dacAddr, walletAddr, + ), + func() (*types.Transaction, error) { + dac, err := polygondatacommittee.NewPolygondatacommittee(common.HexToAddress(dacAddr), client) + if err != nil { + return nil, err + } + addrs, urls := setup.MembersAndAddrsForSetup() + tx, err := dac.SetupCommittee(auth, big.NewInt(setup.RequiredSingatures), urls, addrs) + return tx, err + }, + ) + + return err +} + +type DACMember struct { + Address common.Address `json:"address"` + URL string `json:"url"` +} + +type DACSetup struct { + RequiredSingatures int64 `json:"requiredSingatures"` + Members []DACMember `json:"members"` +} + +func (s DACSetup) Len() int { return len(s.Members) } +func (s DACSetup) Less(i, j int) bool { + return strings.ToUpper(s.Members[i].Address.Hex()) < strings.ToUpper(s.Members[j].Address.Hex()) +} +func (s DACSetup) Swap(i, j int) { s.Members[i], s.Members[j] = s.Members[j], s.Members[i] } + +func (d *DACSetup) MembersAndAddrsForSetup() (addrsBytes []byte, urls []string) { + sort.Sort(d) + for _, m := range d.Members { + addrsBytes = append(addrsBytes, m.Address.Bytes()...) + urls = append(urls, m.URL) + } + return +} diff --git a/cmd/dac_test.go b/cmd/dac_test.go new file mode 100644 index 0000000..b56ba91 --- /dev/null +++ b/cmd/dac_test.go @@ -0,0 +1,110 @@ +package main + +import ( + "encoding/json" + "math/big" + "os" + "os/exec" + "strings" + "testing" + + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/polygondatacommittee" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestSetupDAC(t *testing.T) { + // Deploy DAC + deployCmdArgs := []string{ + "run", "./cmd", "deploy-dac", + "-l1", "local", + "-w", walletAddr, + "-wp", walletPass, + "-skip-confirmation", + } + out, err := exec.Command("go", deployCmdArgs...).CombinedOutput() + require.NoError(t, err, string(out)) + _, msgImpl, _ := strings.Cut(string(out), "DAC implementation deployed at ") + implementationAddr, _, _ := strings.Cut(msgImpl, "\n") + _, dacAddr, _ := strings.Cut(string(out), "DAC proxy deployed at ") + dacAddr, _, _ = strings.Cut(dacAddr, "\n") + client, err := getClient() + require.NoError(t, err) + dac, err := polygondatacommittee.NewPolygondatacommittee(common.HexToAddress(dacAddr), client) + require.NoError(t, err) + owner, err := dac.Owner(nil) + require.NoError(t, err) + require.Equal(t, common.HexToAddress(walletAddr), owner) + + // Setup DAC + setup := DACSetup{ + RequiredSingatures: 1, + Members: []DACMember{ + { + Address: common.HexToAddress("0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9"), + URL: "http://foo.bar", + }, + { + Address: common.HexToAddress("0xFFFFd3AccA5a467e9e704C703E8D87F634fB0Fc9"), + URL: "http://bar.foo", + }, + }, + } + setupFile, err := os.CreateTemp("", "") + require.NoError(t, err) + setupData, err := json.Marshal(setup) + require.NoError(t, err) + err = os.WriteFile(setupFile.Name(), setupData, 0644) + require.NoError(t, err) + setupCmdArgs := []string{ + "run", "./cmd", "setup-dac", + "-l1", "local", + "-w", walletAddr, + "-wp", walletPass, + "-a", dacAddr, + "-f", setupFile.Name(), + "-skip-confirmation", + } + out, err = exec.Command("go", setupCmdArgs...).CombinedOutput() + require.NoError(t, err, string(out)) + assertDACSetup(t, setup, dac) + + // Deploy new DAC with existing implementation + deployCmdArgs = append(deployCmdArgs, "-implementation", implementationAddr) + out, err = exec.Command("go", deployCmdArgs...).CombinedOutput() + require.NoError(t, err, string(out)) + _, dacAddr2, _ := strings.Cut(string(out), "DAC proxy deployed at ") + dacAddr2, _, _ = strings.Cut(dacAddr2, "\n") + require.NotEqual(t, dacAddr, dacAddr2) + + // Setup new DAC + var found bool + for i := 0; i < len(setupCmdArgs); i++ { + if setupCmdArgs[i] == dacAddr { + setupCmdArgs[i] = dacAddr2 + found = true + break + } + } + require.True(t, found) + out, err = exec.Command("go", setupCmdArgs...).CombinedOutput() + require.NoError(t, err, string(out)) + dac, err = polygondatacommittee.NewPolygondatacommittee(common.HexToAddress(dacAddr2), client) + require.NoError(t, err) + assertDACSetup(t, setup, dac) +} + +func assertDACSetup(t *testing.T, setup DACSetup, dac *polygondatacommittee.Polygondatacommittee) { + reqSigsSC, err := dac.RequiredAmountOfSignatures(nil) + require.NoError(t, err) + require.Equal(t, setup.RequiredSingatures, reqSigsSC.Int64()) + nMembers, err := dac.GetAmountOfMembers(nil) + require.NoError(t, err) + require.Equal(t, len(setup.Members), int(nMembers.Int64())) + for i, member := range setup.Members { + memberSC, err := dac.Members(nil, big.NewInt(int64(i))) + require.NoError(t, err) + require.Equal(t, member.URL, memberSC.Url) + require.Equal(t, member.Address, memberSC.Addr) + } +} diff --git a/cmd/deployops.go b/cmd/deployops.go new file mode 100644 index 0000000..cefccc8 --- /dev/null +++ b/cmd/deployops.go @@ -0,0 +1,179 @@ +package main + +import ( + "errors" + "fmt" + "math/big" + "sync" + + "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmdeployer" + "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/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rlp" + "github.com/urfave/cli/v2" + "golang.org/x/crypto/sha3" +) + +// hasherPool holds LegacyKeccak256 hashers for rlpHash. +var hasherPool = sync.Pool{ + New: func() interface{} { return sha3.NewLegacyKeccak256() }, +} + +type scalableSigner struct{} + +func (s scalableSigner) ChainID() *big.Int { + return nil +} + +func (s scalableSigner) Equal(s2 types.Signer) bool { + _, ok := s2.(types.FrontierSigner) + return ok +} + +func (fs scalableSigner) Sender(tx *types.Transaction) (common.Address, error) { + if tx.Type() != types.LegacyTxType { + return common.Address{}, types.ErrTxTypeNotSupported + } + v, r, s := tx.RawSignatureValues() + return recoverPlain(fs.Hash(tx), r, s, v, false) +} + +// SignatureValues returns signature values. This signature +// needs to be in the [R || S || V] format where V is 0 or 1. +func (fs scalableSigner) SignatureValues(tx *types.Transaction, sig []byte) (r, s, v *big.Int, err error) { + if tx.Type() != types.LegacyTxType { + return nil, nil, nil, types.ErrTxTypeNotSupported + } + r, s, v = hardcodedSignature() + return r, s, v, nil +} + +// rlpHash encodes x and hashes the encoded bytes. +func rlpHash(x interface{}) (h common.Hash) { + sha := hasherPool.Get().(crypto.KeccakState) + defer hasherPool.Put(sha) + sha.Reset() + rlp.Encode(sha, x) + sha.Read(h[:]) + return h +} + +// Hash returns the hash to be signed by the sender. +// It does not uniquely identify the transaction. +func (fs scalableSigner) Hash(tx *types.Transaction) common.Hash { + return rlpHash([]interface{}{ + tx.Nonce(), + tx.GasPrice(), + tx.Gas(), + tx.To(), + tx.Value(), + tx.Data(), + }) +} + +func (fs scalableSigner) SignerFn(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + return tx.WithSignature(scalableSigner{}, nil) +} + +func hardcodedSignature() (r, s, v *big.Int) { + // values from https://github.com/0xPolygonHermez/zkevm-contracts/blob/main/deployment/helpers/deployment-helpers.ts#L36 + r = big.NewInt(24865583584) // 0x00000000000000000000000000000000000000000000000000000005ca1ab1e0 + s = big.NewInt(1554098974) // 0x000000000000000000000000000000000000000000000000000000005ca1ab1e + v = new(big.Int).SetBytes([]byte{27}) + return r, s, v +} + +func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (common.Address, error) { + if Vb.BitLen() > 8 { + return common.Address{}, types.ErrInvalidSig + } + V := byte(Vb.Uint64() - 27) + if !crypto.ValidateSignatureValues(V, R, S, homestead) { + return common.Address{}, types.ErrInvalidSig + } + // encode the signature in uncompressed format + r, s := R.Bytes(), S.Bytes() + sig := make([]byte, crypto.SignatureLength) + copy(sig[32-len(r):32], r) + copy(sig[64-len(s):64], s) + sig[64] = V + // recover the public key from the signature + pub, err := crypto.Ecrecover(sighash[:], sig) + if err != nil { + return common.Address{}, err + } + if len(pub) == 0 || pub[0] != 4 { + return common.Address{}, errors.New("invalid public key") + } + var addr common.Address + copy(addr[:], crypto.Keccak256(pub[1:])[12:]) + return addr, nil +} + +func create2Deployment( + cliCtx *cli.Context, + client *ethclient.Client, + auth *bind.TransactOpts, + polgonZKEVMDeployerContract *polygonzkevmdeployer.Polygonzkevmdeployer, + polgonZKEVMDeployerContractAddr common.Address, + salt [32]byte, + deployTransaction []byte, + dataCall []byte, + confirmationQuestion string, +) (common.Address, error) { + // Precalculate addr + initHash := crypto.Keccak256(deployTransaction) + fmt.Println("INIT HASH:", "0x"+common.Bytes2Hex(initHash)) + precalculatedAddressDeployed := crypto.CreateAddress2(polgonZKEVMDeployerContractAddr, salt, initHash) + + // Check if already deployed + code, err := client.CodeAt(cliCtx.Context, precalculatedAddressDeployed, nil) + if err != nil { + return common.Address{}, err + } + if len(code) > 0 { + fmt.Println("already deployed") + return precalculatedAddressDeployed, nil + } + + // Deploy + if len(dataCall) > 0 { + // Using create2 and call + _, err = sendTxWithConfirmation( + cliCtx, client, confirmationQuestion, + func() (*types.Transaction, error) { + tx, err := polgonZKEVMDeployerContract.DeployDeterministicAndCall(auth, big.NewInt(0), salt, deployTransaction, dataCall) + return tx, err + }, + ) + if err != nil { + return common.Address{}, err + } + } else { + // Using create2 + _, err = sendTxWithConfirmation( + cliCtx, client, confirmationQuestion, + func() (*types.Transaction, error) { + tx, err := polgonZKEVMDeployerContract.DeployDeterministic(auth, big.NewInt(0), salt, deployTransaction) + return tx, err + }, + ) + if err != nil { + return common.Address{}, err + } + } + + // Check if already deployed + code, err = client.CodeAt(cliCtx.Context, precalculatedAddressDeployed, nil) + if err != nil { + return common.Address{}, err + } + if len(code) == 0 { + return common.Address{}, fmt.Errorf("no code at the precalculated addr %s after sending the tx", precalculatedAddressDeployed) + } + + return precalculatedAddressDeployed, nil +} diff --git a/cmd/deployrollupmanager.go b/cmd/deployrollupmanager.go new file mode 100644 index 0000000..6615c7c --- /dev/null +++ b/cmd/deployrollupmanager.go @@ -0,0 +1,709 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "math/big" + "os" + + "github.com/0xPolygon/cdk-contracts-tooling/contracts/common/proxyadmin" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/common/transparentupgradableproxy" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/erc20permitmock" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonrollupmanagernotupgraded" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmbridgev2" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmdeployer" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmglobalexitrootv2" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmtimelock" + "github.com/0xPolygon/cdk-contracts-tooling/rollupmanager" + "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/crypto" + "github.com/urfave/cli/v2" +) + +const ( + deployParametersFileFlagName = "rollup-manager-parameters-file" +) + +var ( + deployRollupManagerCommand = &cli.Command{ + Name: "deploy-rollup-manager", + Aliases: []string{"deploy-rm", "drm"}, + Usage: "Deploy the Rollup Manager smart contract", + Action: deployRollupManager, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + smartContractVersionFlag, + &cli.PathFlag{ + Name: deployParametersFileFlagName, + Aliases: []string{"params", "file-params", "i"}, + Usage: `TODO: description`, + Required: true, + }, + outputFlag, + &cli.StringFlag{ + Name: rollupManagerAliasFlagName, + Aliases: []string{"alias"}, + Usage: "Name that will be used to store the rollup manager info once deployed, alias of the uLxLy being imported", + Required: true, + }, + }, + } +) + +func deployRollupManager(cliCtx *cli.Context) error { + _, err := checkWorkingDir() + if err != nil { + return err + } + walletAddr, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + + // Load params + params, output, err := loadDeployRollupManagerFiles( + cliCtx.Path(deployParametersFileFlagName), + cliCtx.Path(outputFileFlagName), + ) + if err != nil { + return err + } + if output.DeploymentCompleted { + return errors.New( + "the provided output file indicates that the deployment is completed. " + + "Use a different file if you want to do a new deployment", + ) + } + defer storeOutputFile(cliCtx.Path(outputFileFlagName), output) + output.Salt = params.Salt + output.TrustedAggregator = params.TrustedAggregator + output.Admin = params.Admin + output.DeployerAddress = walletAddr + if output.PolTokenAddress == zeroAddr && params.PolTokenAddress != zeroAddr { + output.PolTokenAddress = params.PolTokenAddress + } + + // Deploy POL + if output.PolTokenAddress == zeroAddr { + fmt.Println("Deploying POL token") + polTokenAddr, err := sendTxWithConfirmation( + cliCtx, client, + "Do you want to send the tx that will deploy the POL token?", + func() (*types.Transaction, error) { + _, tx, _, err := erc20permitmock.DeployErc20permitmock( + auth, client, "Pol Token", "POL", + walletAddr, big.NewInt(20000000), + ) + return tx, err + }, + ) + if err != nil { + return err + } + fmt.Println("POL deployed at ", polTokenAddr) + output.PolTokenAddress = polTokenAddr + } else { + fmt.Println("Using already deployed POL token at", output.PolTokenAddress) + } + + // Deploy PolygonZkEVMDeployer + fmt.Println("Deploying PolygonZkEVMDeployer...") + _, tx, _, err := polygonzkevmdeployer.DeployPolygonzkevmdeployer( + &bind.TransactOpts{ + NoSend: true, + Nonce: big.NewInt(0), + Signer: scalableSigner{}.SignerFn, + GasLimit: 1_000_000, // gas limit 1M + GasPrice: big.NewInt(100_000_000_000), // gas price 100 gWEI + + }, + client, params.Admin, + ) + if err != nil { + return err + } + + // check if already deployed + deterministicSender, err := scalableSigner{}.Sender(tx) + if err != nil { + return err + } + zkevmDeployerAddr := crypto.CreateAddress(deterministicSender, 0) + + code, err := client.CodeAt(cliCtx.Context, zkevmDeployerAddr, nil) + if err != nil { + return err + } + if len(code) > 0 { + fmt.Println("PolygonZkEVMDeployer was already deployed") + } else { + // Fund deployer + neededFunds := big.NewInt(0).Mul(tx.GasPrice(), big.NewInt(int64(tx.Gas()))) + dsBalance, err := client.BalanceAt(cliCtx.Context, deterministicSender, nil) + if err != nil { + return err + } + if dsBalance.Cmp(neededFunds) == -1 { + _, err = sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "The address used for the deterministic deployment %s doesn't have enough funds for the tx. Send %s ETH from %s?", + deterministicSender, neededFunds.String(), walletAddr, + ), + func() (*types.Transaction, error) { + nonce, err := client.PendingNonceAt(cliCtx.Context, walletAddr) + if err != nil { + return nil, err + } + gasPrice, err := client.SuggestGasPrice(cliCtx.Context) + if err != nil { + return nil, err + } + fundTx := types.NewTransaction(nonce, deterministicSender, neededFunds, 21000, gasPrice, nil) + fundTx, err = auth.Signer(walletAddr, fundTx) + if err != nil { + return nil, err + } + err = client.SendTransaction(cliCtx.Context, fundTx) + return fundTx, err + }, + ) + if err != nil { + return err + } + } + // Deploy deployer + actualDeployerAddr, err := sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "Do you want to send the tx that will deploy the PolygonZkEVMDeployer with owner %s? Note that this tx will be sent from %s", + params.Admin.Hex(), deterministicSender, + ), + func() (*types.Transaction, error) { + err := client.SendTransaction(cliCtx.Context, tx) + return tx, err + }, + ) + if err != nil { + return err + } + if zkevmDeployerAddr != actualDeployerAddr { + return fmt.Errorf("unexpcted deployer addr. Expected %s, actual: %s", zkevmDeployerAddr, actualDeployerAddr) + } + } + deployer, err := polygonzkevmdeployer.NewPolygonzkevmdeployer(zkevmDeployerAddr, client) + if err != nil { + return err + } + fmt.Println("PolygonZkEVMDeployer addr:", zkevmDeployerAddr) + output.ZkEVMDeployerContract = zkevmDeployerAddr + + // Deploy proxy admin + fmt.Println("Deploying proxy admin...") + proxyABI, err := proxyadmin.ProxyadminMetaData.GetAbi() + if err != nil { + return err + } + if proxyABI == nil { + return errors.New("GetABI returned nil") + } + dataCallAdmin, err := proxyABI.Pack("transferOwnership", walletAddr) + if err != nil { + return err + } + _, proxyTx, _, err := proxyadmin.DeployProxyadmin( + &bind.TransactOpts{ + NoSend: true, + From: auth.From, // Irrelevant, we just want tx data + Signer: auth.Signer, // Irrelevant, we just want tx data + }, + client, + ) + if err != nil { + return err + } + proxyAdminAddr, err := create2Deployment( + cliCtx, client, auth, deployer, zkevmDeployerAddr, params.Salt, proxyTx.Data(), dataCallAdmin, + fmt.Sprintf( + "Do you want to send the tx that will deploy the proxy (using the deployer)? Admin of the proxy will be set to %s", + walletAddr, + ), + ) + if err != nil { + return err + } + proxy, err := proxyadmin.NewProxyadmin(proxyAdminAddr, client) + if err != nil { + return err + } + fmt.Println("proxy admin addr:", proxyAdminAddr) + output.ProxyAdminAddress = proxyAdminAddr + + // Deploy implementation PolygonZkEVMBridge + fmt.Println("Deploying PolygonZkEVMBridge implementation...") + auth.GasLimit = 5500000 // gas limit with create are mess up D: + _, bridgeImplTx, _, err := polygonzkevmbridgev2.DeployPolygonzkevmbridgev2( + &bind.TransactOpts{ + NoSend: true, + From: auth.From, // Irrelevant, we just want tx data + Signer: auth.Signer, // Irrelevant, we just want tx data + }, + client, + ) + if err != nil { + return err + } + bridgeImplementationAddr, err := create2Deployment( + cliCtx, client, auth, deployer, zkevmDeployerAddr, params.Salt, bridgeImplTx.Data(), nil, + fmt.Sprintf( + "Do you want to send the tx that will deploy the proxy (using the deployer)? Admin of the proxy will be set to %s", + walletAddr, + ), + ) + if err != nil { + return err + } + auth.GasLimit = 0 + bridgeImplementation, err := polygonzkevmbridgev2.NewPolygonzkevmbridgev2(bridgeImplementationAddr, client) + if err != nil { + return err + } + // Sanity check, just checking the right code was deployed on the expected addr + checkCounter, err := bridgeImplementation.DepositCount(nil) + if err != nil { + return err + } + if checkCounter.Cmp(big.NewInt(0)) != 0 { + return fmt.Errorf("counter should be 0 but it's %s", checkCounter.String()) + } + fmt.Println("bridge implementation addr:", bridgeImplementationAddr) + + // Useless tx to match zkevm-contracts scripts + _, err = sendTxWithConfirmation( + cliCtx, client, + "Do you want to send a useless tx just to increase the nonce (required step to move forward)?", + func() (*types.Transaction, error) { + nonce, err := client.PendingNonceAt(cliCtx.Context, walletAddr) + if err != nil { + return nil, err + } + gasPrice, err := client.SuggestGasPrice(cliCtx.Context) + if err != nil { + return nil, err + } + fundTx := types.NewTransaction(nonce, auth.From, big.NewInt(0), 21000, gasPrice, nil) + fundTx, err = auth.Signer(walletAddr, fundTx) + if err != nil { + return nil, err + } + err = client.SendTransaction(cliCtx.Context, fundTx) + return fundTx, err + }, + ) + if err != nil { + return err + } + + // Deploy PolygonZkEVMTimelock + fmt.Println("Deploying PolygonZkEVMTimelock...") + currentNonce, err := client.NonceAt(cliCtx.Context, walletAddr, nil) + if err != nil { + return err + } + // Nonce globalExitRoot: currentNonce + 1 (deploy bridge proxy) + 1(impl globalExitRoot) + // + 1 (deployTimelock) + 1 (transfer Ownership Admin) = +4 + nonceProxyGlobalExitRoot := currentNonce + 4 + fmt.Println("nonceProxyGlobalExitRoot: ", nonceProxyGlobalExitRoot) + // nonceProxyRollupManager :Nonce globalExitRoot + 1 (proxy globalExitRoot) + 1 (impl rollupManager) = +2 + nonceProxyRollupManager := nonceProxyGlobalExitRoot + 2 + precalculateGlobalExitRootAddress := crypto.CreateAddress(walletAddr, nonceProxyGlobalExitRoot) + precalculateRollupManager := crypto.CreateAddress(walletAddr, nonceProxyRollupManager) + + // Deploy timelock + var timelockAddr common.Address + if output.TimelockContractAddress != zeroAddr && + output.PolygonRollupManager != zeroAddr && + output.PolygonZkEVMGlobalExitRootAddress != zeroAddr { + timelockAddr = output.TimelockContractAddress + fmt.Println("using already deployed timelock", timelockAddr) + } else { + if output.TimelockContractAddress != zeroAddr { + fmt.Println("I'm afraid we can't recover this situation. Time to change the salt") + } + // If both are not deployed, it's better to deploy them both again + output.TimelockContractAddress = zeroAddr + output.PolygonRollupManager = zeroAddr + output.PolygonZkEVMGlobalExitRootAddress = zeroAddr + + timelockAdmins := []common.Address{params.TimelockAdminAddress} + timelockAddr, err = sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "Do you want to send the tx that will deploy the PolygonZkEVMTimelock with admin %s? This timelock will be used for the Rollup Manager with precalculated address %s", + params.TimelockAdminAddress, precalculateRollupManager, + ), + func() (*types.Transaction, error) { + _, tx, _, err := polygonzkevmtimelock.DeployPolygonzkevmtimelock( + auth, client, big.NewInt(params.MinDelayTimelock), timelockAdmins, timelockAdmins, params.TimelockAdminAddress, precalculateRollupManager, + ) + return tx, err + }, + ) + if err != nil { + return err + } + // Sanity check + timelock, err := polygonzkevmtimelock.NewPolygonzkevmtimelock(timelockAddr, client) + if err != nil { + return err + } + actualRMAddr, err := timelock.PolygonZkEVM(nil) + if err != nil { + return err + } + if precalculateRollupManager != actualRMAddr { + return fmt.Errorf("timelock rollup manager was expected to be %s instead of %s", precalculateRollupManager, actualRMAddr) + } + fmt.Println("PolygonZkEVMTimelock addr", timelockAddr) + output.TimelockContractAddress = timelockAddr + } + + // Transfer ownership of the proxyAdmin to timelock + proxyOwner, err := proxy.Owner(nil) + if err != nil { + return err + } + if proxyOwner != timelockAddr { + _, err = sendTxWithConfirmation( + cliCtx, client, + "Do you want to send the tx that will transfer the ownership of the proxy to the timelock?", + func() (*types.Transaction, error) { + return proxy.TransferOwnership(auth, timelockAddr) + }, + ) + if err != nil { + return err + } + newProxyOwner, err := proxy.Owner(nil) + if err != nil { + return err + } + if timelockAddr != newProxyOwner { + return fmt.Errorf( + "owner of the proxy should be the timelock (%s), but it's %s", + timelockAddr, newProxyOwner, + ) + } + } + + // Deploy PolygonZkEVMBridgeV2 proxy + fmt.Println("Deploying PolygonZkEVMBridgeV2 proxy...") + _, bridgeProxyTx, _, err := transparentupgradableproxy.DeployTransparentupgradableproxy( + &bind.TransactOpts{ + NoSend: true, + From: auth.From, // Irrelevant, we just want tx data + Signer: auth.Signer, // Irrelevant, we just want tx data + }, + client, + bridgeImplementationAddr, + proxyAdminAddr, + []byte{}, + ) + if err != nil { + return err + } + + bridgeABI, err := polygonzkevmbridgev2.Polygonzkevmbridgev2MetaData.GetAbi() + if err != nil { + return err + } + if bridgeABI == nil { + return errors.New("GetABI returned nil") + } + dataCallProxy, err := bridgeABI.Pack("initialize", + uint32(0), // networkIDMainnet + common.Address{}, // gasTokenAddressMainnet" + uint32(0), // gasTokenNetworkMainnet + precalculateGlobalExitRootAddress, + precalculateRollupManager, + []byte{}, // gasTokenMetadata + ) + if err != nil { + return err + } + bridgeProxyAddr, err := create2Deployment( + cliCtx, client, auth, deployer, zkevmDeployerAddr, params.Salt, bridgeProxyTx.Data(), dataCallProxy, + fmt.Sprintf( + "Do you want to send the tx that will deploy the proxy (using the deployer)? Admin of the proxy will be set to %s", + walletAddr, + ), + ) + if err != nil { + return err + } + bridge, err := polygonzkevmbridgev2.NewPolygonzkevmbridgev2(bridgeProxyAddr, client) + if err != nil { + return err + } + actualGERAddr, err := bridge.GlobalExitRootManager(nil) + if err != nil { + return err + } + if precalculateGlobalExitRootAddress != actualGERAddr { + return fmt.Errorf("GER addr should be %s instead of %s", precalculateGlobalExitRootAddress, actualGERAddr) + } + actualRMAddr, err := bridge.PolygonRollupManager(nil) + if err != nil { + return err + } + if precalculateRollupManager != actualRMAddr { + return fmt.Errorf("rollup Manager addr should be %s instead of %s", precalculateRollupManager, actualRMAddr) + } + fmt.Println("PolygonZkEVMBridgeV2 proxy addr:", bridgeProxyAddr) + output.PolygonZkEVMBridgeAddress = bridgeProxyAddr + + // Deploy PolygonZkEVMGlobalExitRootV2 proxy + fmt.Println("Deploying PolygonZkEVMGlobalExitRootV2 proxy...") + if output.PolygonZkEVMGlobalExitRootAddress != zeroAddr { + fmt.Println("PolygonZkEVMGlobalExitRootV2 already deployed") + } else { + // Deploy GER implementation + gerImplAddr, err := sendTxWithConfirmation( + cliCtx, client, + "Do you want to send the tx that will deploy the PolygonZkEVMGlobalExitRootV2 implementation?", + func() (*types.Transaction, error) { + _, tx, _, err := polygonzkevmglobalexitrootv2.DeployPolygonzkevmglobalexitrootv2( + auth, + client, + precalculateRollupManager, + bridgeProxyAddr, + ) + return tx, err + }, + ) + if err != nil { + return err + } + + // Deploy GER proxy + GERProxyAddr, err := deployProxy( + cliCtx, + auth, + client, + gerImplAddr, + []byte{}, + ) + if err != nil { + return err + } + if GERProxyAddr != precalculateGlobalExitRootAddress { + return fmt.Errorf( + "GER was expected to be deployed at %s, but was deployed at %s instead", + precalculateGlobalExitRootAddress, GERProxyAddr, + ) + } + ger, err := polygonzkevmglobalexitrootv2.NewPolygonzkevmglobalexitrootv2(GERProxyAddr, client) + if err != nil { + return err + } + actualRMAddr, err := ger.RollupManager(nil) + if err != nil { + return err + } + if actualRMAddr != precalculateRollupManager { + return fmt.Errorf("rollup manager addr is %s but should be %s", actualRMAddr, precalculateRollupManager) + } + actualBridgeAddr, err := ger.BridgeAddress(nil) + if err != nil { + return err + } + if actualBridgeAddr != bridgeProxyAddr { + return fmt.Errorf("bridge addr is %s but should be %s", actualBridgeAddr, bridgeProxyAddr) + } + fmt.Println("PolygonZkEVMGlobalExitRootV2 proxy deployed at", GERProxyAddr) + output.PolygonZkEVMGlobalExitRootAddress = GERProxyAddr + } + + if params.UseDeployerAsAdminForRollupManager { + fmt.Println("Using deployer as admin of the rollup manager insetad of the timelock!") + timelockAddr = walletAddr + } + + // Deploy PolygonRollupManagerNotUpgraded proxy + fmt.Println("Deploying PolygonRollupManagerNotUpgraded proxy...") + if output.PolygonRollupManager != zeroAddr { + fmt.Println("PolygonRollupManagerNotUpgraded already deployed") + } else { + // Deploy PolygonRollupManagerNotUpgraded implementation + rmImplAddr, err := sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "Do you want to send the tx that will deploy the PolygonRollupManagerNotUpgraded implementation? "+ + "Following values are going to be used:\n"+ + "trustedAggregator: %s\n"+ + "pendingStateTimeout: %d\n"+ + "trustedAggregatorTimeout: %d\n"+ + "admin: %s\n"+ + "timelockAddressRollupManager: %s\n"+ + "emergencyCouncilAddress: %s\n"+ + "PolygonZkEVMGlobalExitRootAddress: %s\n"+ + "PolTokenAddress: %s\n"+ + "bridgeProxyAddr: %s\n", + params.TrustedAggregator, params.PendingStateTimeout, params.TrustedAggregatorTimeout, + params.Admin, timelockAddr, params.EmergencyCouncilAddress, + output.PolygonZkEVMGlobalExitRootAddress, output.PolTokenAddress, bridgeProxyAddr, + ), + + func() (*types.Transaction, error) { + _, tx, _, err := polygonrollupmanagernotupgraded.DeployPolygonrollupmanagernotupgraded( + auth, + client, + output.PolygonZkEVMGlobalExitRootAddress, + output.PolTokenAddress, + bridgeProxyAddr, + ) + return tx, err + }, + ) + if err != nil { + return err + } + // Deploy PolygonRollupManagerNotUpgraded proxy + rmABI, err := polygonrollupmanagernotupgraded.PolygonrollupmanagernotupgradedMetaData.GetAbi() + if err != nil { + return err + } + if rmABI == nil { + return errors.New("GetABI returned nil") + } + initializeData, err := rmABI.Pack( + "initialize", + params.TrustedAggregator, + params.PendingStateTimeout, + params.TrustedAggregatorTimeout, + params.Admin, + timelockAddr, + params.EmergencyCouncilAddress, + zeroAddr, zeroAddr, uint64(0), uint64(0), // unused parameters + ) + if err != nil { + return err + } + RMProxyAddr, err := deployProxy( + cliCtx, + auth, + client, + rmImplAddr, + initializeData, + ) + if err != nil { + return err + } + if RMProxyAddr != precalculateRollupManager { + return fmt.Errorf( + "rollup Manager was expected to be deployed at %s, but was deployed at %s instead", + precalculateRollupManager, RMProxyAddr, + ) + } + rm, err := polygonrollupmanagernotupgraded.NewPolygonrollupmanagernotupgraded(RMProxyAddr, client) + if err != nil { + return err + } + actualBridgeAddr, err := rm.BridgeAddress(nil) + if err != nil { + return err + } + if actualBridgeAddr != bridgeProxyAddr { + return fmt.Errorf("bridge addr is %s but should be %s", actualBridgeAddr, bridgeProxyAddr) + } + fmt.Println("PolygonRollupManagerNotUpgraded proxy deployed at", RMProxyAddr) + output.PolygonRollupManager = RMProxyAddr + + rmInfo, err := rollupmanager.LoadFromL1(cliCtx.Context, client, RMProxyAddr) + if err != nil { + return err + } + output.DeploymentBlockNumber = rmInfo.CreationBlock + } + + // TODO: checks, a lot of checks and asserts https://github.com/0xPolygonHermez/zkevm-contracts/blob/main/deployment/v2/3_deployContracts.ts#L488 + + output.DeploymentCompleted = true + l1Network := cliCtx.String(l1FlagName) + alias := cliCtx.String(rollupManagerAliasFlagName) + return importRollupManager(cliCtx.Context, l1Network, output.PolygonRollupManager.Hex(), alias) +} + +type DeployRollupManagerParams struct { + UseDeployerAsAdminForRollupManager bool `json:"useDeployerAsAdminForRollupManager"` + TimelockAdminAddress common.Address `json:"timelockAdminAddress"` + MinDelayTimelock int64 `json:"minDelayTimelock"` + Salt common.Hash `json:"salt"` + InitialZkEVMDeployerOwner common.Address `json:"initialZkEVMDeployerOwner"` + Admin common.Address `json:"admin"` + TrustedAggregator common.Address `json:"trustedAggregator"` + TrustedAggregatorTimeout uint64 `json:"trustedAggregatorTimeout"` + PendingStateTimeout uint64 `json:"pendingStateTimeout"` + EmergencyCouncilAddress common.Address `json:"emergencyCouncilAddress"` + PolTokenAddress common.Address `json:"polTokenAddress"` +} + +type DeployRollupManagerOutput struct { + DeploymentCompleted bool `json:"deploymentCompleted"` + PolygonRollupManager common.Address `json:"polygonRollupManager"` + PolygonZkEVMBridgeAddress common.Address `json:"polygonZkEVMBridgeAddress"` + PolygonZkEVMGlobalExitRootAddress common.Address `json:"polygonZkEVMGlobalExitRootAddress"` + PolTokenAddress common.Address `json:"polTokenAddress"` + ZkEVMDeployerContract common.Address `json:"zkEVMDeployerContract"` + DeployerAddress common.Address `json:"deployerAddress"` + TimelockContractAddress common.Address `json:"timelockContractAddress"` + DeploymentBlockNumber uint64 `json:"deploymentBlockNumber"` + Admin common.Address `json:"admin"` + TrustedAggregator common.Address `json:"trustedAggregator"` + ProxyAdminAddress common.Address `json:"proxyAdminAddress"` + Salt common.Hash `json:"salt"` +} + +func loadDeployRollupManagerFiles(paramsFile, outputFile string) (*DeployRollupManagerParams, *DeployRollupManagerOutput, error) { + data, err := os.ReadFile(paramsFile) + if err != nil { + return nil, nil, err + } + var params DeployRollupManagerParams + err = json.Unmarshal(data, ¶ms) + if err != nil { + return nil, nil, err + } + output, err := loadRollupManagerOutput(outputFile) + if err != nil { + return nil, nil, err + } + return ¶ms, output, nil +} + +func loadRollupManagerOutput(outputFile string) (*DeployRollupManagerOutput, error) { + data, err := os.ReadFile(outputFile) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return &DeployRollupManagerOutput{}, nil + } + return nil, err + } + var output DeployRollupManagerOutput + return &output, json.Unmarshal(data, &output) +} + +func storeOutputFile(outputFile string, output *DeployRollupManagerOutput) error { + outputData, err := json.MarshalIndent(output, "", " ") + if err != nil { + return err + } + return os.WriteFile(outputFile, outputData, 0644) +} diff --git a/cmd/deployrollupmanager_test.go b/cmd/deployrollupmanager_test.go new file mode 100644 index 0000000..981974c --- /dev/null +++ b/cmd/deployrollupmanager_test.go @@ -0,0 +1,115 @@ +package main + +import ( + "context" + "encoding/json" + "os" + "os/exec" + "path" + "testing" + + "github.com/0xPolygon/cdk-contracts-tooling/docker" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDeployRollupManagerEtrog(t *testing.T) { + const ( + inputFileDeployRM = "./createRollupManagerParams.example.json" + outputFileDeployRM = "./createRollupManagerOutput.example.json" + inputFileAddRT = "./addRollupTypeParams.example.json" + inputFileCreateR = "./createRollupParams.example.json" + alias = "test_etrog" + ) + // Clean before start. This test needs a fresh L1 so the addressess used have deterministic nonces + ctx := context.Background() + if err := docker.StopMockL1Docker(); err != nil { + panic(err) + } + if err := docker.StartMockL1Docker(ctx); err != nil { + panic(err) + } + require.NoError(t, os.RemoveAll(outputFileDeployRM)) + require.NoError(t, os.RemoveAll(path.Join("networks", "local", alias))) + + // Deploy RollupManager + deployCmdArgs := []string{ + "run", "./cmd", "deploy-rm", + "-l1", "local", + "-w", walletAddr, + "-wp", walletPass, + "-skip-confirmation", + "-i", inputFileDeployRM, + "-o", outputFileDeployRM, + "-alias", alias, + "-scv", "etrog", + } + out, err := exec.Command("go", deployCmdArgs...).CombinedOutput() + require.NoError(t, err, string(out)) + + // This values are generated by: + // 1. git clone https://github.com/0xPolygonHermez/zkevm-contracts.git && cd zkevm-contracts + // 2. git checkout v4.0.0-fork.7 + // 3. npm i + // 4. npm run docker:contracts # This step will fail, but got to a point where is good enough for the purpose + // 5. cat docker/deploymentOutput/deploy_output.json + deployOutputFromContractsRepo := ` + { + "polygonRollupManager": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "polygonZkEVMBridgeAddress": "0xFe12ABaa190Ef0c8638Ee0ba9F828BF41368Ca0E", + "polygonZkEVMGlobalExitRootAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "polTokenAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", + "zkEVMDeployerContract": "0xFbD07134824dDEa24E4ae414c18ecbFa98169A24", + "deployerAddress": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "timelockContractAddress": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", + "deploymentBlockNumber": 43, + "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "trustedAggregator": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "proxyAdminAddress": "0xfADB60b5059e31614e02083fF6C021a24C31c891", + "salt": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ` + var expectedOutpu DeployRollupManagerOutput + require.NoError(t, json.Unmarshal( + []byte(deployOutputFromContractsRepo), &expectedOutpu, + )) + actualOutput, err := loadRollupManagerOutput(outputFileDeployRM) + require.NoError(t, err) + + // DeploymentCompleted doesn't exist on the contracts repo + require.True(t, actualOutput.DeploymentCompleted) + actualOutput.DeploymentCompleted = false + // Deployment block is the only thing that is not deterministic + assert.Greater(t, actualOutput.DeploymentBlockNumber, uint64(0)) + actualOutput.DeploymentBlockNumber = expectedOutpu.DeploymentBlockNumber + // Check all the other fields + assert.Equal(t, expectedOutpu, *actualOutput) + + // Add rollup type + addCmdArgs := []string{ + "run", "./cmd", "add-rt", + "-l1", "local", + "-w", walletAddr, + "-wp", walletPass, + "-skip-confirmation", + "-i", inputFileAddRT, + "-scv", "etrog", + "-alias", alias, + } + out, err = exec.Command("go", addCmdArgs...).CombinedOutput() + require.NoError(t, err, string(out)) + + // Create rollup + createCmdArgs := []string{ + "run", "./cmd", "create-r", + "-l1", "local", + "-w", walletAddr, + "-wp", walletPass, + "-skip-confirmation", + "-i", inputFileCreateR, + "-scv", "etrog", + "-alias", alias, + } + out, err = exec.Command("go", createCmdArgs...).CombinedOutput() + require.NoError(t, err, string(out)) +} diff --git a/cmd/docker.go b/cmd/docker.go new file mode 100644 index 0000000..9f1a2e0 --- /dev/null +++ b/cmd/docker.go @@ -0,0 +1,66 @@ +package main + +import ( + "fmt" + + "github.com/0xPolygon/cdk-contracts-tooling/docker" + "github.com/urfave/cli/v2" +) + +const ( + startMockL1FlagName = "start-mock-l1" + stopMockL1FlagName = "stop-mock-l1" + exportMockL1FlagName = "export-mock-l1" + imageFlagName = "docker-image-name" + defaultImageName = "cdk-mock-l1" +) + +var ( + startMockL1Command = &cli.Command{ + Name: startMockL1FlagName, + Aliases: []string{"start-l1"}, + Usage: "Starts an L1 network (dockerized geth in dev mode). The first 20 accounts of the menmonic `test test test test test test test test test test test junk` will be funded", + Action: startMockL1, + Flags: []cli.Flag{}, + } + stopMockL1Command = &cli.Command{ + Name: stopMockL1FlagName, + Aliases: []string{"stop-l1"}, + Usage: "Stops the L1 mock", + Action: stopMockL1, + Flags: []cli.Flag{}, + } + exportMockL1Command = &cli.Command{ + Name: exportMockL1FlagName, + Aliases: []string{"export-l1"}, + Usage: "Create a docekr image with the same state as the running or the last run mock L1. If the mock is still running it will be shut down", + Action: exportMockL1, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: imageFlagName, + Aliases: []string{"image", "image-name", "name"}, + Usage: fmt.Sprintf("Name of the resulting docker image. Defaults to `%s`", defaultImageName), + Required: false, + }, + }, + } +) + +func startMockL1(cliCtx *cli.Context) error { + return docker.StartMockL1Docker(cliCtx.Context) +} + +func stopMockL1(cliCtx *cli.Context) error { + return docker.StopMockL1Docker() +} + +func exportMockL1(cliCtx *cli.Context) error { + if err := docker.StopMockL1Docker(); err != nil { + return err + } + imageName := cliCtx.String(imageFlagName) + if imageName == "" { + imageName = defaultImageName + } + return docker.BuildL1FromMock(imageName) +} diff --git a/cmd/flags.go b/cmd/flags.go index 5df722d..e1eb4c7 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -1,12 +1,28 @@ package main import ( + "fmt" + "time" + "github.com/urfave/cli/v2" ) const ( - l1FlagName = "l1-network" - outputFileFlagName = "output" + l1FlagName = "l1-network" + outputFileFlagName = "output" + walletFlagName = "wallet" + walletPasswordFlagName = "wallet-password" + addressFlagName = "address" + skipConfirmationFlagName = "skip-confirmation" + timeoutFlagName = "timeout" + setupFilePathFlagName = "setup-file" + implementationAddressFlagName = "implementation-address" + smartContractVersionFlagName = "smart-contract-version" + amountFlagName = "amount" + + defaultTimeout = time.Minute * 10 + etrog = "etrog" + elderbeerry = "elderberry" ) var ( @@ -16,10 +32,77 @@ var ( Usage: "L1 network, such as sepolia, local, goerli, mainnet, ... Should match an entry on the rpcs.toml file", Required: true, } - outputFlag = &cli.StringFlag{ + outputFlag = &cli.PathFlag{ Name: outputFileFlagName, Aliases: []string{"o"}, Usage: "Output file", Required: true, } + addressFlag = &cli.StringFlag{ + Name: addressFlagName, + Aliases: []string{"a", "addr"}, + Usage: "Address of the smart contract", + Required: true, + } + walletFlag = &cli.StringFlag{ + Name: walletFlagName, + Aliases: []string{"w"}, + Usage: "Address of a wallet registered at wallets.toml", + Required: true, + } + walletPasswordFlag = &cli.StringFlag{ + Name: walletPasswordFlagName, + Aliases: []string{"wp", "pass", "password"}, + Usage: "Password of the specified wallet. This is optional, it can be inputed through CLI later on. Only applies for password protected wallets", + Required: false, + } + skipConfirmationFlag = &cli.BoolFlag{ + Name: skipConfirmationFlagName, + Aliases: []string{"skip"}, + Usage: "Skip confirmation promt", + Required: false, + } + timeoutFlag = &cli.DurationFlag{ + Name: timeoutFlagName, + Aliases: []string{"to"}, + Usage: fmt.Sprintf("Time after which a given operation within a command will fail. Defaults to %s", defaultTimeout), + Required: false, + } + smartContractVersionFlag = &cli.StringFlag{ + Name: smartContractVersionFlagName, + Aliases: []string{"scv", "contract-version"}, + Usage: fmt.Sprintf( + `Version of the smart contracts to be used. Supported options: ["%s", "%s"]`, + etrog, elderbeerry, + ), + Required: true, + Action: func(ctx *cli.Context, input string) error { + switch input { + case "etrog": + return nil + case "elderberry": + return nil + default: + return fmt.Errorf( + `unsupported %s flag value. Supported options are: ["%s", "%s"]`, + smartContractVersionFlagName, etrog, elderbeerry, + ) + } + }, + } + rollupManagerFlag = &cli.StringFlag{ + Name: rollupManagerAliasFlagName, + Aliases: []string{"rm"}, + Usage: fmt.Sprintf( + "Name of the rollup manager to which the rollup belongs. Needs to match an already imported rollup manager (can be done by running the %s command)", + importRollupManagerCommandName, + ), + Required: true, + } + amountFlag = &cli.StringFlag{ + Name: amountFlagName, + Aliases: []string{"a"}, + Usage: "Amount of tokens expressed in base 10 string", + Required: true, + } ) diff --git a/cmd/importrollup.go b/cmd/importrollup.go index 485099c..9050a66 100644 --- a/cmd/importrollup.go +++ b/cmd/importrollup.go @@ -26,15 +26,7 @@ var ( Action: importRollup, Flags: []cli.Flag{ l1Flag, - &cli.StringFlag{ - Name: rollupManagerAliasFlagName, - Aliases: []string{"rm"}, - Usage: fmt.Sprintf( - "Name of the rollup manager to which the rollup belongs. Needs to match an already imported rollup manager (can be done by running the %s command)", - importRollupManagerCommandName, - ), - Required: true, - }, + rollupManagerFlag, &cli.Uint64Flag{ Name: chainIDFlagName, Aliases: []string{"id", "chainid", "chain-id"}, @@ -78,7 +70,7 @@ func importRollup(cliCtx *cli.Context) error { fmt.Println("fetching on-chain info for the rollup") chainID := cliCtx.Uint64(chainIDFlagName) - r, err := rollup.LoadFromL1ByChainID(client, rm, chainID) + r, err := rollup.LoadFromL1ByChainID(cliCtx.Context, client, rm, chainID) if err != nil { return err } diff --git a/cmd/importrollupmanager.go b/cmd/importrollupmanager.go index a7977ee..3d446af 100644 --- a/cmd/importrollupmanager.go +++ b/cmd/importrollupmanager.go @@ -27,7 +27,7 @@ var ( Name: importRollupManagerCommandName, Aliases: []string{"import-rm"}, Usage: "Import a rollup manager smart contract, adding a new uLxLy into the network files", - Action: importRollupManager, + Action: importRollupManagerCmd, Flags: []cli.Flag{ l1Flag, &cli.StringFlag{ @@ -46,7 +46,15 @@ var ( } ) -func importRollupManager(cliCtx *cli.Context) error { +func importRollupManagerCmd(cliCtx *cli.Context) error { + l1Network := cliCtx.String(l1FlagName) + addrStr := cliCtx.String(rollupManagerAddressFlagName) + alias := cliCtx.String(rollupManagerAliasFlagName) + + return importRollupManager(cliCtx.Context, l1Network, addrStr, alias) +} + +func importRollupManager(ctx context.Context, l1Network, addrStr, alias string) error { baseDir, err := checkWorkingDir() if err != nil { return err @@ -57,22 +65,19 @@ func importRollupManager(cliCtx *cli.Context) error { if err != nil { return err } - l1Network := cliCtx.String(l1FlagName) client, err := rpcs.GetClient(l1Network) if err != nil { return err } fmt.Println("fetching on-chain info for the rollup manager") - addrStr := cliCtx.String(rollupManagerAddressFlagName) addr := common.HexToAddress(addrStr) - rm, err := rollupmanager.LoadFromL1(client, addr) + rm, err := rollupmanager.LoadFromL1(ctx, client, addr) if err != nil { return err } fmt.Println("storing info for the rollup manager") - alias := cliCtx.String(rollupManagerAliasFlagName) rollupManagerPath := path.Join(baseDir, "networks", l1Network, alias) err = os.MkdirAll(rollupManagerPath, 0744) if err != nil { @@ -88,7 +93,7 @@ func importRollupManager(cliCtx *cli.Context) error { } fmt.Println("importing attached rollups") - rollups, err := rm.GetAttachedRollups(context.TODO()) + rollups, err := rm.GetAttachedRollups(ctx) if err != nil { return err } @@ -99,7 +104,7 @@ func importRollupManager(cliCtx *cli.Context) error { } for chainID, name := range rollups { fmt.Println("importing rollup ", name, " with chainID ", chainID) - r, err := rollup.LoadFromL1ByChainID(client, rm, chainID) + r, err := rollup.LoadFromL1ByChainID(ctx, client, rm, chainID) if err != nil { return err } diff --git a/cmd/main.go b/cmd/main.go index 94dec4c..b0554c7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -22,6 +22,18 @@ func main() { importRollupCommand, nodeGenesisCommand, bridgeConfigCommand, + deployDACCommand, + setupDACCommand, + startMockL1Command, + stopMockL1Command, + exportMockL1Command, + deployRollupManagerCommand, + addRollupTypeCommand, + createRollupCommand, + setDAPCommand, + deployAndsetDACCommand, + approveToken, + mintToken, } err := app.Run(os.Args) diff --git a/cmd/tokens.go b/cmd/tokens.go new file mode 100644 index 0000000..5652a9a --- /dev/null +++ b/cmd/tokens.go @@ -0,0 +1,147 @@ +package main + +import ( + "fmt" + "math/big" + + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/erc20permitmock" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/urfave/cli/v2" +) + +const ( + spenderAddrFlagName = "spender-address" +) + +var ( + approveToken = &cli.Command{ + Name: "approve-token", + Aliases: []string{"approve"}, + Usage: "Approve tokens", + Action: approveERC20, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + amountFlag, + &cli.StringFlag{ + Name: implementationAddressFlagName, + Aliases: []string{"implementation", "impl", "token", "t"}, + Usage: `Smart contract address of the ERC20`, + Required: true, + }, + &cli.StringFlag{ + Name: spenderAddrFlagName, + Aliases: []string{"spender", "s"}, + Usage: `Address that will be able too spend the tokens on behalf of the holder`, + Required: true, + }, + }, + } + mintToken = &cli.Command{ + Name: "mint-token", + Aliases: []string{"mint"}, + Usage: "Mint tokens", + Action: mintERC20, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + amountFlag, + &cli.StringFlag{ + Name: implementationAddressFlagName, + Aliases: []string{"implementation", "impl", "token", "t"}, + Usage: `Smart contract address of the ERC20`, + Required: true, + }, + &cli.StringFlag{ + Name: spenderAddrFlagName, + Aliases: []string{"spender", "s"}, + Usage: `Address that will be able too spend the tokens on behalf of the holder. If not provided, the tokens will be minted to the wallet address`, + Required: false, + }, + }, + } +) + +func approveERC20(cliCtx *cli.Context) error { + _, err := checkWorkingDir() + if err != nil { + return err + } + _, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + + erc20AddrStr := cliCtx.String(implementationAddressFlagName) + erc20Addr := common.HexToAddress(erc20AddrStr) + spenderAddrStr := cliCtx.String(spenderAddrFlagName) + spenderAddr := common.HexToAddress(spenderAddrStr) + amountStr := cliCtx.String(amountFlagName) + amount, ok := new(big.Int).SetString(amountStr, 10) + if !ok { + return fmt.Errorf("error decoding flag %s, it should be a base 10 integer", amountFlagName) + } + _, err = sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "Do you want to send the tx that will approve %s tokens of the contract %s to be spent by %s?", + amountStr, erc20Addr, spenderAddr, + ), + func() (*types.Transaction, error) { + erc20, err := erc20permitmock.NewErc20permitmock(erc20Addr, client) + if err != nil { + return nil, err + } + return erc20.Approve(auth, spenderAddr, amount) + }, + ) + return err +} + +func mintERC20(cliCtx *cli.Context) error { + _, err := checkWorkingDir() + if err != nil { + return err + } + _, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + + erc20AddrStr := cliCtx.String(implementationAddressFlagName) + erc20Addr := common.HexToAddress(erc20AddrStr) + spenderAddrStr := cliCtx.String(spenderAddrFlagName) + var spenderAddr common.Address + if spenderAddrStr != "" { + spenderAddr = common.HexToAddress(spenderAddrStr) + } else { + spenderAddr = auth.From + } + amountStr := cliCtx.String(amountFlagName) + amount, ok := new(big.Int).SetString(amountStr, 10) + if !ok || amount == nil { + return fmt.Errorf("error decoding flag %s, it should be a base 10 integer", amountFlagName) + } + _, err = sendTxWithConfirmation( + cliCtx, client, + fmt.Sprintf( + "Do you want to send the tx that will mint %s tokens of the contract %s to be spent by %s?", + amountStr, erc20Addr, spenderAddr, + ), + func() (*types.Transaction, error) { + erc20, err := erc20permitmock.NewErc20permitmock(erc20Addr, client) + if err != nil { + return nil, err + } + return erc20.Mint(auth, spenderAddr, amount) + }, + ) + return err +} diff --git a/cmd/validiumops.go b/cmd/validiumops.go new file mode 100644 index 0000000..f413d4a --- /dev/null +++ b/cmd/validiumops.go @@ -0,0 +1,176 @@ +package main + +import ( + "fmt" + "math/big" + "path" + + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/polygondatacommittee" + "github.com/0xPolygon/cdk-contracts-tooling/rollup" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/urfave/cli/v2" +) + +const ( + dapAddrFlagName = "data-availability-protocol-addr" + initEmptyFlagName = "initialize-empty" +) + +var ( + setDAPCommand = &cli.Command{ + Name: "set-data-availablity-protocol", + Aliases: []string{"set-dap", "set-da"}, + Usage: "Setup the data availability protocol to a deployed validium", + Action: setDAP, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + &cli.StringFlag{ + Name: dapAddrFlagName, + Aliases: []string{"dap-addr", "addr"}, + Usage: `Smart contract address of a Data Availability Protocol deployment`, + Required: true, + }, + &cli.StringFlag{ + Name: rollupManagerAliasFlagName, + Aliases: []string{"rm-alias"}, + Usage: "Name of the rollup manager where the rollup belongs", + Required: true, + }, + &cli.StringFlag{ + Name: rollupAliasFlagName, + Aliases: []string{"r-alias"}, + Usage: "Name of the rollup where the DAP will be setup to", + Required: true, + }, + }, + } + deployAndsetDACCommand = &cli.Command{ + Name: "deploy-and-set-data-availablity-committee", + Aliases: []string{"deployset-dac"}, + Usage: "Deploy a DAC and set it as the data availability protocol to a deployed validium", + Action: deployAndSetDAC, + Flags: []cli.Flag{ + l1Flag, + walletFlag, + walletPasswordFlag, + skipConfirmationFlag, + timeoutFlag, + &cli.StringFlag{ + Name: rollupManagerAliasFlagName, + Aliases: []string{"rm-alias"}, + Usage: "Name of the rollup manager where the rollup belongs", + Required: true, + }, + &cli.StringFlag{ + Name: rollupAliasFlagName, + Aliases: []string{"r-alias"}, + Usage: "Name of the rollup where the DAP will be setup to", + Required: true, + }, + &cli.BoolFlag{ + Name: initEmptyFlagName, + Aliases: []string{"init"}, + Usage: "If set to true, the DAC will be initialized with an empty committee (0/0)", + Required: false, + }, + }, + } +) + +func setDAP(cliCtx *cli.Context) error { + // Load configs + baseDir, err := checkWorkingDir() + if err != nil { + return err + } + _, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + rmAlias := cliCtx.String(rollupManagerAliasFlagName) + rAlias := cliCtx.String(rollupAliasFlagName) + l1Network := cliCtx.String(l1FlagName) + rollupPath := path.Join(baseDir, "networks", l1Network, rmAlias, "rollups", rAlias+".json") + r, err := rollup.LoadFromFile(client, rollupPath) + if err != nil { + return err + } + dap := common.HexToAddress(cliCtx.String(dapAddrFlagName)) + + // Set DAP + _, err = sendTxWithConfirmation( + cliCtx, client, fmt.Sprintf( + "Send tx to set the data availability protocol of validium %s to the protocol deployed at %s?", + r.Address, dap, + ), + func() (*types.Transaction, error) { + return r.SetDataAvailabilityProtocol(auth, dap) + }, + ) + return err +} + +func deployAndSetDAC(cliCtx *cli.Context) error { + // Load configs + baseDir, err := checkWorkingDir() + if err != nil { + return err + } + _, auth, client, err := loadAuthAndClient(cliCtx) + if err != nil { + return err + } + rmAlias := cliCtx.String(rollupManagerAliasFlagName) + rAlias := cliCtx.String(rollupAliasFlagName) + l1Network := cliCtx.String(l1FlagName) + rollupPath := path.Join(baseDir, "networks", l1Network, rmAlias, "rollups", rAlias+".json") + r, err := rollup.LoadFromFile(client, rollupPath) + if err != nil { + return err + } + + // Deploy DAC + dacImpl, err := deployDACImpl(cliCtx, auth, client) + if err != nil { + return err + } + dacProxy, err := deployDACProxy(cliCtx, auth, client, dacImpl) + if err != nil { + return err + } + + // Init DAC + if cliCtx.Bool(initEmptyFlagName) { + _, err = sendTxWithConfirmation( + cliCtx, client, + "Initialise the deployed DAC with an empty committee (0/0)?", + func() (*types.Transaction, error) { + dac, err := polygondatacommittee.NewPolygondatacommittee(dacProxy, client) + if err != nil { + return nil, err + } + return dac.SetupCommittee(auth, big.NewInt(0), nil, nil) + }, + ) + if err != nil { + return err + } + } + + // Set DAP + _, err = sendTxWithConfirmation( + cliCtx, client, fmt.Sprintf( + "Send tx to set the data availability protocol of validium %s to the protocol deployed at %s?", + r.Address, dacProxy, + ), + func() (*types.Transaction, error) { + return r.SetDataAvailabilityProtocol(auth, dacProxy) + }, + ) + return err +} diff --git a/config/wallets.go b/config/wallets.go index d912156..2ae52d2 100644 --- a/config/wallets.go +++ b/config/wallets.go @@ -1 +1,82 @@ package config + +import ( + "bufio" + "crypto/ecdsa" + "fmt" + "math/big" + "os" + "path/filepath" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/crypto" +) + +type Wallets struct { + Wallets map[string]WalletConfig +} + +type WalletConfig struct { + Type walletType + FilePath string + PrivateKey string +} + +type walletType string + +const ( + wtText walletType = "PlainTextPrivateKey" + wtFile walletType = "EncryptedFile" +) + +func LoadWallets() (*Wallets, error) { + var w Wallets + return &w, LoadFromFile("./wallets.toml", &w) +} + +func (w *Wallets) GetPrivateKey(address, pass string) (*ecdsa.PrivateKey, error) { + wallet, ok := w.Wallets[address] + if !ok { + return nil, fmt.Errorf("there is no wallet config for address %s. Please add it to wallets.toml", address) + } + switch wallet.Type { + case wtText: + return crypto.HexToECDSA(strings.TrimPrefix(wallet.PrivateKey, "0x")) + case wtFile: + return loadKeyFromFile(wallet.FilePath, pass) + default: + return nil, fmt.Errorf("unsupported wallet type: %s. Should be one of [%s, %s]", wallet.Type, wtText, wtFile) + } +} + +func (w *Wallets) GetAuth(address, pass string, chainID uint64) (*bind.TransactOpts, error) { + pk, err := w.GetPrivateKey(address, pass) + if err != nil { + return nil, err + } + return bind.NewKeyedTransactorWithChainID(pk, new(big.Int).SetUint64(chainID)) +} + +// loadKeyFromFile creates an instance of a keystore key from a keystore file +func loadKeyFromFile(path, pass string) (*ecdsa.PrivateKey, error) { + keystoreEncrypted, err := os.ReadFile(filepath.Clean(path)) + if err != nil { + return nil, err + } + if pass == "" { + reader := bufio.NewReader(os.Stdin) + fmt.Printf("Enter password for the encrypted private key at: %s\n\nINPUT PASSWORD:", path) + pass, err = reader.ReadString('\n') + if err != nil { + return nil, err + } + pass = strings.TrimSuffix(pass, "\n") + } + key, err := keystore.DecryptKey(keystoreEncrypted, pass) + if err != nil { + return nil, err + } + return key.PrivateKey, nil +} diff --git a/contracts/common/abi/erc1967proxy.abi b/contracts/common/abi/erc1967proxy.abi new file mode 100644 index 0000000..f676814 --- /dev/null +++ b/contracts/common/abi/erc1967proxy.abi @@ -0,0 +1,71 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] \ No newline at end of file diff --git a/contracts/common/abi/proxyadmin.abi b/contracts/common/abi/proxyadmin.abi new file mode 100644 index 0000000..4b26557 --- /dev/null +++ b/contracts/common/abi/proxyadmin.abi @@ -0,0 +1,151 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] \ No newline at end of file diff --git a/contracts/common/abi/transparentupgradableproxy.abi b/contracts/common/abi/transparentupgradableproxy.abi new file mode 100644 index 0000000..b87d131 --- /dev/null +++ b/contracts/common/abi/transparentupgradableproxy.abi @@ -0,0 +1,146 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] \ No newline at end of file diff --git a/contracts/common/bin/erc1967proxy.bin b/contracts/common/bin/erc1967proxy.bin new file mode 100644 index 0000000..d81a2e2 --- /dev/null +++ b/contracts/common/bin/erc1967proxy.bin @@ -0,0 +1 @@ +60806040526040516104ee3803806104ee833981016040819052610022916102de565b61002e82826000610035565b50506103fb565b61003e83610061565b60008251118061004b5750805b1561005c5761005a83836100a1565b505b505050565b61006a816100cd565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606100c683836040518060600160405280602781526020016104c760279139610180565b9392505050565b6001600160a01b0381163b61013f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080856001600160a01b03168560405161019d91906103ac565b600060405180830381855af49150503d80600081146101d8576040519150601f19603f3d011682016040523d82523d6000602084013e6101dd565b606091505b5090925090506101ef868383876101f9565b9695505050505050565b60608315610268578251600003610261576001600160a01b0385163b6102615760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610136565b5081610272565b610272838361027a565b949350505050565b81511561028a5781518083602001fd5b8060405162461bcd60e51b815260040161013691906103c8565b634e487b7160e01b600052604160045260246000fd5b60005b838110156102d55781810151838201526020016102bd565b50506000910152565b600080604083850312156102f157600080fd5b82516001600160a01b038116811461030857600080fd5b60208401519092506001600160401b038082111561032557600080fd5b818501915085601f83011261033957600080fd5b81518181111561034b5761034b6102a4565b604051601f8201601f19908116603f01168101908382118183101715610373576103736102a4565b8160405282815288602084870101111561038c57600080fd5b61039d8360208301602088016102ba565b80955050505050509250929050565b600082516103be8184602087016102ba565b9190910192915050565b60208152600082518060208401526103e78160408501602087016102ba565b601f01601f19169190910160400192915050565b60be806104096000396000f3fe608060405236601057600e6013565b005b600e5b601f601b6021565b6065565b565b600060607f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b3660008037600080366000845af43d6000803e8080156083573d6000f35b3d6000fdfea2646970667358221220ffbfbaa210c1b5f5ca62a5eba67b7d993e0bdf919f51500f790fb7acf2fd784c64736f6c63430008140033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564 \ No newline at end of file diff --git a/contracts/common/bin/proxyadmin.bin b/contracts/common/bin/proxyadmin.bin new file mode 100644 index 0000000..486f7cd --- /dev/null +++ b/contracts/common/bin/proxyadmin.bin @@ -0,0 +1 @@ +608060405234801561000f575f80fd5b506100193361001e565b61006d565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6108338061007a5f395ff3fe608060405260043610610079575f3560e01c80639623609d1161004c5780639623609d1461012357806399a88ec414610136578063f2fde38b14610155578063f3b7dead14610174575f80fd5b8063204e1c7a1461007d578063715018a6146100c55780637eff275e146100db5780638da5cb5b146100fa575b5f80fd5b348015610088575f80fd5b5061009c6100973660046105e8565b610193565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d0575f80fd5b506100d9610244565b005b3480156100e6575f80fd5b506100d96100f536600461060a565b610257565b348015610105575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff1661009c565b6100d961013136600461066e565b6102e0565b348015610141575f80fd5b506100d961015036600461060a565b610371565b348015610160575f80fd5b506100d961016f3660046105e8565b6103cd565b34801561017f575f80fd5b5061009c61018e3660046105e8565b610489565b5f805f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b5f60405180830381855afa9150503d805f8114610215576040519150601f19603f3d011682016040523d82523d5f602084013e61021a565b606091505b509150915081610228575f80fd5b8080602001905181019061023c919061075b565b949350505050565b61024c6104d3565b6102555f610553565b565b61025f6104d3565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b5f604051808303815f87803b1580156102c6575f80fd5b505af11580156102d8573d5f803e3d5ffd5b505050505050565b6102e86104d3565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061033e9086908690600401610776565b5f604051808303818588803b158015610355575f80fd5b505af1158015610367573d5f803e3d5ffd5b5050505050505050565b6103796104d3565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102af565b6103d56104d3565b73ffffffffffffffffffffffffffffffffffffffff811661047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61048681610553565b50565b5f805f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610474565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610486575f80fd5b5f602082840312156105f8575f80fd5b8135610603816105c7565b9392505050565b5f806040838503121561061b575f80fd5b8235610626816105c7565b91506020830135610636816105c7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f805f60608486031215610680575f80fd5b833561068b816105c7565b9250602084013561069b816105c7565b9150604084013567ffffffffffffffff808211156106b7575f80fd5b818601915086601f8301126106ca575f80fd5b8135818111156106dc576106dc610641565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561072257610722610641565b8160405282815289602084870101111561073a575f80fd5b826020860160208301375f6020848301015280955050505050509250925092565b5f6020828403121561076b575f80fd5b8151610603816105c7565b73ffffffffffffffffffffffffffffffffffffffff831681525f602060408184015283518060408501525f5b818110156107be578581018301518582016060015282016107a2565b505f6060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea26469706673582212203083a4ccc2e42eed60bd19037f2efa77ed086dc7a5403f75bebb995dcba2221c64736f6c63430008140033 \ No newline at end of file diff --git a/contracts/common/bin/transparentupgradableproxy.bin b/contracts/common/bin/transparentupgradableproxy.bin new file mode 100644 index 0000000..a9c16ee --- /dev/null +++ b/contracts/common/bin/transparentupgradableproxy.bin @@ -0,0 +1 @@ +608060405260405162000f6838038062000f68833981016040819052620000269162000415565b82816200003582825f6200004c565b50620000439050826200007d565b50505062000540565b6200005783620000ee565b5f82511180620000645750805b1562000078576200007683836200012f565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f620000be5f8051602062000f21833981519152546001600160a01b031690565b604080516001600160a01b03928316815291841660208301520160405180910390a1620000eb816200015e565b50565b620000f981620001fb565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b606062000157838360405180606001604052806027815260200162000f416027913962000292565b9392505050565b6001600160a01b038116620001c95760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b805f8051602062000f218339815191525b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381163b6200026a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401620001c0565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc620001da565b60605f80856001600160a01b031685604051620002b09190620004ef565b5f60405180830381855af49150503d805f8114620002ea576040519150601f19603f3d011682016040523d82523d5f602084013e620002ef565b606091505b50909250905062000303868383876200030d565b9695505050505050565b60608315620003805782515f0362000378576001600160a01b0385163b620003785760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620001c0565b50816200038c565b6200038c838362000394565b949350505050565b815115620003a55781518083602001fd5b8060405162461bcd60e51b8152600401620001c091906200050c565b80516001600160a01b0381168114620003d8575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f5b838110156200040d578181015183820152602001620003f3565b50505f910152565b5f805f6060848603121562000428575f80fd5b6200043384620003c1565b92506200044360208501620003c1565b60408501519092506001600160401b038082111562000460575f80fd5b818601915086601f83011262000474575f80fd5b815181811115620004895762000489620003dd565b604051601f8201601f19908116603f01168101908382118183101715620004b457620004b4620003dd565b81604052828152896020848701011115620004cd575f80fd5b620004e0836020830160208801620003f1565b80955050505050509250925092565b5f825162000502818460208701620003f1565b9190910192915050565b602081525f82518060208401526200052c816040850160208701620003f1565b601f01601f19169190910160400192915050565b6109d3806200054e5f395ff3fe60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f80fd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f80fd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f80fd5b5061006a6100fd366004610854565b610228565b34801561010d575f80fd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f80375f80365f845af43d5f803e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610977602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f808573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090b565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610926565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f80fd5b919050565b5f60208284031215610864575f80fd5b6104e28261082c565b5f805f6040848603121561087f575f80fd5b6108888461082c565b9250602084013567ffffffffffffffff808211156108a4575f80fd5b818601915086601f8301126108b7575f80fd5b8135818111156108c5575f80fd5b8760208285010111156108d6575f80fd5b6020830194508093505050509250925092565b5f5b838110156109035781810151838201526020016108eb565b50505f910152565b5f825161091c8184602087016108e9565b9190910192915050565b602081525f82518060208401526109448160408501602087016108e9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212202ac98acbfbb3d3ac1b74050e18c4e76db25a3ff2801ec69bf85d0c61414d502b64736f6c63430008140033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564 \ No newline at end of file diff --git a/contracts/common/erc1967proxy/erc1967proxy.go b/contracts/common/erc1967proxy/erc1967proxy.go new file mode 100644 index 0000000..f4994e0 --- /dev/null +++ b/contracts/common/erc1967proxy/erc1967proxy.go @@ -0,0 +1,668 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc1967proxy + +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 +) + +// Erc1967proxyMetaData contains all meta data concerning the Erc1967proxy contract. +var Erc1967proxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60806040526040516104ee3803806104ee833981016040819052610022916102de565b61002e82826000610035565b50506103fb565b61003e83610061565b60008251118061004b5750805b1561005c5761005a83836100a1565b505b505050565b61006a816100cd565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606100c683836040518060600160405280602781526020016104c760279139610180565b9392505050565b6001600160a01b0381163b61013f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080856001600160a01b03168560405161019d91906103ac565b600060405180830381855af49150503d80600081146101d8576040519150601f19603f3d011682016040523d82523d6000602084013e6101dd565b606091505b5090925090506101ef868383876101f9565b9695505050505050565b60608315610268578251600003610261576001600160a01b0385163b6102615760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610136565b5081610272565b610272838361027a565b949350505050565b81511561028a5781518083602001fd5b8060405162461bcd60e51b815260040161013691906103c8565b634e487b7160e01b600052604160045260246000fd5b60005b838110156102d55781810151838201526020016102bd565b50506000910152565b600080604083850312156102f157600080fd5b82516001600160a01b038116811461030857600080fd5b60208401519092506001600160401b038082111561032557600080fd5b818501915085601f83011261033957600080fd5b81518181111561034b5761034b6102a4565b604051601f8201601f19908116603f01168101908382118183101715610373576103736102a4565b8160405282815288602084870101111561038c57600080fd5b61039d8360208301602088016102ba565b80955050505050509250929050565b600082516103be8184602087016102ba565b9190910192915050565b60208152600082518060208401526103e78160408501602087016102ba565b601f01601f19169190910160400192915050565b60be806104096000396000f3fe608060405236601057600e6013565b005b600e5b601f601b6021565b6065565b565b600060607f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b3660008037600080366000845af43d6000803e8080156083573d6000f35b3d6000fdfea2646970667358221220ffbfbaa210c1b5f5ca62a5eba67b7d993e0bdf919f51500f790fb7acf2fd784c64736f6c63430008140033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", +} + +// Erc1967proxyABI is the input ABI used to generate the binding from. +// Deprecated: Use Erc1967proxyMetaData.ABI instead. +var Erc1967proxyABI = Erc1967proxyMetaData.ABI + +// Erc1967proxyBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use Erc1967proxyMetaData.Bin instead. +var Erc1967proxyBin = Erc1967proxyMetaData.Bin + +// DeployErc1967proxy deploys a new Ethereum contract, binding an instance of Erc1967proxy to it. +func DeployErc1967proxy(auth *bind.TransactOpts, backend bind.ContractBackend, _logic common.Address, _data []byte) (common.Address, *types.Transaction, *Erc1967proxy, error) { + parsed, err := Erc1967proxyMetaData.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(Erc1967proxyBin), backend, _logic, _data) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Erc1967proxy{Erc1967proxyCaller: Erc1967proxyCaller{contract: contract}, Erc1967proxyTransactor: Erc1967proxyTransactor{contract: contract}, Erc1967proxyFilterer: Erc1967proxyFilterer{contract: contract}}, nil +} + +// Erc1967proxy is an auto generated Go binding around an Ethereum contract. +type Erc1967proxy struct { + Erc1967proxyCaller // Read-only binding to the contract + Erc1967proxyTransactor // Write-only binding to the contract + Erc1967proxyFilterer // Log filterer for contract events +} + +// Erc1967proxyCaller is an auto generated read-only Go binding around an Ethereum contract. +type Erc1967proxyCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Erc1967proxyTransactor is an auto generated write-only Go binding around an Ethereum contract. +type Erc1967proxyTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Erc1967proxyFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type Erc1967proxyFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Erc1967proxySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type Erc1967proxySession struct { + Contract *Erc1967proxy // 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 +} + +// Erc1967proxyCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type Erc1967proxyCallerSession struct { + Contract *Erc1967proxyCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// Erc1967proxyTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type Erc1967proxyTransactorSession struct { + Contract *Erc1967proxyTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Erc1967proxyRaw is an auto generated low-level Go binding around an Ethereum contract. +type Erc1967proxyRaw struct { + Contract *Erc1967proxy // Generic contract binding to access the raw methods on +} + +// Erc1967proxyCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type Erc1967proxyCallerRaw struct { + Contract *Erc1967proxyCaller // Generic read-only contract binding to access the raw methods on +} + +// Erc1967proxyTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type Erc1967proxyTransactorRaw struct { + Contract *Erc1967proxyTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewErc1967proxy creates a new instance of Erc1967proxy, bound to a specific deployed contract. +func NewErc1967proxy(address common.Address, backend bind.ContractBackend) (*Erc1967proxy, error) { + contract, err := bindErc1967proxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Erc1967proxy{Erc1967proxyCaller: Erc1967proxyCaller{contract: contract}, Erc1967proxyTransactor: Erc1967proxyTransactor{contract: contract}, Erc1967proxyFilterer: Erc1967proxyFilterer{contract: contract}}, nil +} + +// NewErc1967proxyCaller creates a new read-only instance of Erc1967proxy, bound to a specific deployed contract. +func NewErc1967proxyCaller(address common.Address, caller bind.ContractCaller) (*Erc1967proxyCaller, error) { + contract, err := bindErc1967proxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &Erc1967proxyCaller{contract: contract}, nil +} + +// NewErc1967proxyTransactor creates a new write-only instance of Erc1967proxy, bound to a specific deployed contract. +func NewErc1967proxyTransactor(address common.Address, transactor bind.ContractTransactor) (*Erc1967proxyTransactor, error) { + contract, err := bindErc1967proxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &Erc1967proxyTransactor{contract: contract}, nil +} + +// NewErc1967proxyFilterer creates a new log filterer instance of Erc1967proxy, bound to a specific deployed contract. +func NewErc1967proxyFilterer(address common.Address, filterer bind.ContractFilterer) (*Erc1967proxyFilterer, error) { + contract, err := bindErc1967proxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &Erc1967proxyFilterer{contract: contract}, nil +} + +// bindErc1967proxy binds a generic wrapper to an already deployed contract. +func bindErc1967proxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := Erc1967proxyMetaData.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 (_Erc1967proxy *Erc1967proxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Erc1967proxy.Contract.Erc1967proxyCaller.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 (_Erc1967proxy *Erc1967proxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Erc1967proxy.Contract.Erc1967proxyTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Erc1967proxy *Erc1967proxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Erc1967proxy.Contract.Erc1967proxyTransactor.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 (_Erc1967proxy *Erc1967proxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Erc1967proxy.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 (_Erc1967proxy *Erc1967proxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Erc1967proxy.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Erc1967proxy *Erc1967proxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Erc1967proxy.Contract.contract.Transact(opts, method, params...) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_Erc1967proxy *Erc1967proxyTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _Erc1967proxy.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_Erc1967proxy *Erc1967proxySession) Fallback(calldata []byte) (*types.Transaction, error) { + return _Erc1967proxy.Contract.Fallback(&_Erc1967proxy.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_Erc1967proxy *Erc1967proxyTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _Erc1967proxy.Contract.Fallback(&_Erc1967proxy.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Erc1967proxy *Erc1967proxyTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Erc1967proxy.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Erc1967proxy *Erc1967proxySession) Receive() (*types.Transaction, error) { + return _Erc1967proxy.Contract.Receive(&_Erc1967proxy.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Erc1967proxy *Erc1967proxyTransactorSession) Receive() (*types.Transaction, error) { + return _Erc1967proxy.Contract.Receive(&_Erc1967proxy.TransactOpts) +} + +// Erc1967proxyAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the Erc1967proxy contract. +type Erc1967proxyAdminChangedIterator struct { + Event *Erc1967proxyAdminChanged // 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 *Erc1967proxyAdminChangedIterator) 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(Erc1967proxyAdminChanged) + 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(Erc1967proxyAdminChanged) + 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 *Erc1967proxyAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Erc1967proxyAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Erc1967proxyAdminChanged represents a AdminChanged event raised by the Erc1967proxy contract. +type Erc1967proxyAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_Erc1967proxy *Erc1967proxyFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*Erc1967proxyAdminChangedIterator, error) { + + logs, sub, err := _Erc1967proxy.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &Erc1967proxyAdminChangedIterator{contract: _Erc1967proxy.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_Erc1967proxy *Erc1967proxyFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *Erc1967proxyAdminChanged) (event.Subscription, error) { + + logs, sub, err := _Erc1967proxy.contract.WatchLogs(opts, "AdminChanged") + 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(Erc1967proxyAdminChanged) + if err := _Erc1967proxy.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_Erc1967proxy *Erc1967proxyFilterer) ParseAdminChanged(log types.Log) (*Erc1967proxyAdminChanged, error) { + event := new(Erc1967proxyAdminChanged) + if err := _Erc1967proxy.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// Erc1967proxyBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the Erc1967proxy contract. +type Erc1967proxyBeaconUpgradedIterator struct { + Event *Erc1967proxyBeaconUpgraded // 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 *Erc1967proxyBeaconUpgradedIterator) 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(Erc1967proxyBeaconUpgraded) + 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(Erc1967proxyBeaconUpgraded) + 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 *Erc1967proxyBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Erc1967proxyBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Erc1967proxyBeaconUpgraded represents a BeaconUpgraded event raised by the Erc1967proxy contract. +type Erc1967proxyBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_Erc1967proxy *Erc1967proxyFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*Erc1967proxyBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _Erc1967proxy.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &Erc1967proxyBeaconUpgradedIterator{contract: _Erc1967proxy.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_Erc1967proxy *Erc1967proxyFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *Erc1967proxyBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _Erc1967proxy.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(Erc1967proxyBeaconUpgraded) + if err := _Erc1967proxy.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_Erc1967proxy *Erc1967proxyFilterer) ParseBeaconUpgraded(log types.Log) (*Erc1967proxyBeaconUpgraded, error) { + event := new(Erc1967proxyBeaconUpgraded) + if err := _Erc1967proxy.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// Erc1967proxyUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the Erc1967proxy contract. +type Erc1967proxyUpgradedIterator struct { + Event *Erc1967proxyUpgraded // 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 *Erc1967proxyUpgradedIterator) 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(Erc1967proxyUpgraded) + 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(Erc1967proxyUpgraded) + 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 *Erc1967proxyUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Erc1967proxyUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Erc1967proxyUpgraded represents a Upgraded event raised by the Erc1967proxy contract. +type Erc1967proxyUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_Erc1967proxy *Erc1967proxyFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*Erc1967proxyUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _Erc1967proxy.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &Erc1967proxyUpgradedIterator{contract: _Erc1967proxy.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_Erc1967proxy *Erc1967proxyFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *Erc1967proxyUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _Erc1967proxy.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(Erc1967proxyUpgraded) + if err := _Erc1967proxy.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_Erc1967proxy *Erc1967proxyFilterer) ParseUpgraded(log types.Log) (*Erc1967proxyUpgraded, error) { + event := new(Erc1967proxyUpgraded) + if err := _Erc1967proxy.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contracts/common/generate.sh b/contracts/common/generate.sh new file mode 100755 index 0000000..3d73a99 --- /dev/null +++ b/contracts/common/generate.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +gen() { + local package=$1 + + abigen --bin bin/${package}.bin --abi abi/${package}.abi --pkg=${package} --out=${package}/${package}.go +} + +genNoBin() { + local package=$1 + + abigen --abi abi/${package}.abi --pkg=${package} --out=${package}/${package}.go +} + +gen proxyadmin +gen erc1967proxy +gen transparentupgradableproxy diff --git a/contracts/common/proxyadmin/proxyadmin.go b/contracts/common/proxyadmin/proxyadmin.go new file mode 100644 index 0000000..5e2ae1c --- /dev/null +++ b/contracts/common/proxyadmin/proxyadmin.go @@ -0,0 +1,554 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package proxyadmin + +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 +) + +// ProxyadminMetaData contains all meta data concerning the Proxyadmin contract. +var ProxyadminMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contractTransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractTransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractTransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractTransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractTransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b506100193361001e565b61006d565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6108338061007a5f395ff3fe608060405260043610610079575f3560e01c80639623609d1161004c5780639623609d1461012357806399a88ec414610136578063f2fde38b14610155578063f3b7dead14610174575f80fd5b8063204e1c7a1461007d578063715018a6146100c55780637eff275e146100db5780638da5cb5b146100fa575b5f80fd5b348015610088575f80fd5b5061009c6100973660046105e8565b610193565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d0575f80fd5b506100d9610244565b005b3480156100e6575f80fd5b506100d96100f536600461060a565b610257565b348015610105575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff1661009c565b6100d961013136600461066e565b6102e0565b348015610141575f80fd5b506100d961015036600461060a565b610371565b348015610160575f80fd5b506100d961016f3660046105e8565b6103cd565b34801561017f575f80fd5b5061009c61018e3660046105e8565b610489565b5f805f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b5f60405180830381855afa9150503d805f8114610215576040519150601f19603f3d011682016040523d82523d5f602084013e61021a565b606091505b509150915081610228575f80fd5b8080602001905181019061023c919061075b565b949350505050565b61024c6104d3565b6102555f610553565b565b61025f6104d3565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b5f604051808303815f87803b1580156102c6575f80fd5b505af11580156102d8573d5f803e3d5ffd5b505050505050565b6102e86104d3565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061033e9086908690600401610776565b5f604051808303818588803b158015610355575f80fd5b505af1158015610367573d5f803e3d5ffd5b5050505050505050565b6103796104d3565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102af565b6103d56104d3565b73ffffffffffffffffffffffffffffffffffffffff811661047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61048681610553565b50565b5f805f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610474565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610486575f80fd5b5f602082840312156105f8575f80fd5b8135610603816105c7565b9392505050565b5f806040838503121561061b575f80fd5b8235610626816105c7565b91506020830135610636816105c7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f805f60608486031215610680575f80fd5b833561068b816105c7565b9250602084013561069b816105c7565b9150604084013567ffffffffffffffff808211156106b7575f80fd5b818601915086601f8301126106ca575f80fd5b8135818111156106dc576106dc610641565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561072257610722610641565b8160405282815289602084870101111561073a575f80fd5b826020860160208301375f6020848301015280955050505050509250925092565b5f6020828403121561076b575f80fd5b8151610603816105c7565b73ffffffffffffffffffffffffffffffffffffffff831681525f602060408184015283518060408501525f5b818110156107be578581018301518582016060015282016107a2565b505f6060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea26469706673582212203083a4ccc2e42eed60bd19037f2efa77ed086dc7a5403f75bebb995dcba2221c64736f6c63430008140033", +} + +// ProxyadminABI is the input ABI used to generate the binding from. +// Deprecated: Use ProxyadminMetaData.ABI instead. +var ProxyadminABI = ProxyadminMetaData.ABI + +// ProxyadminBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ProxyadminMetaData.Bin instead. +var ProxyadminBin = ProxyadminMetaData.Bin + +// DeployProxyadmin deploys a new Ethereum contract, binding an instance of Proxyadmin to it. +func DeployProxyadmin(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Proxyadmin, error) { + parsed, err := ProxyadminMetaData.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(ProxyadminBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Proxyadmin{ProxyadminCaller: ProxyadminCaller{contract: contract}, ProxyadminTransactor: ProxyadminTransactor{contract: contract}, ProxyadminFilterer: ProxyadminFilterer{contract: contract}}, nil +} + +// Proxyadmin is an auto generated Go binding around an Ethereum contract. +type Proxyadmin struct { + ProxyadminCaller // Read-only binding to the contract + ProxyadminTransactor // Write-only binding to the contract + ProxyadminFilterer // Log filterer for contract events +} + +// ProxyadminCaller is an auto generated read-only Go binding around an Ethereum contract. +type ProxyadminCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyadminTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ProxyadminTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyadminFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ProxyadminFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyadminSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ProxyadminSession struct { + Contract *Proxyadmin // 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 +} + +// ProxyadminCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ProxyadminCallerSession struct { + Contract *ProxyadminCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ProxyadminTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ProxyadminTransactorSession struct { + Contract *ProxyadminTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ProxyadminRaw is an auto generated low-level Go binding around an Ethereum contract. +type ProxyadminRaw struct { + Contract *Proxyadmin // Generic contract binding to access the raw methods on +} + +// ProxyadminCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ProxyadminCallerRaw struct { + Contract *ProxyadminCaller // Generic read-only contract binding to access the raw methods on +} + +// ProxyadminTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ProxyadminTransactorRaw struct { + Contract *ProxyadminTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewProxyadmin creates a new instance of Proxyadmin, bound to a specific deployed contract. +func NewProxyadmin(address common.Address, backend bind.ContractBackend) (*Proxyadmin, error) { + contract, err := bindProxyadmin(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Proxyadmin{ProxyadminCaller: ProxyadminCaller{contract: contract}, ProxyadminTransactor: ProxyadminTransactor{contract: contract}, ProxyadminFilterer: ProxyadminFilterer{contract: contract}}, nil +} + +// NewProxyadminCaller creates a new read-only instance of Proxyadmin, bound to a specific deployed contract. +func NewProxyadminCaller(address common.Address, caller bind.ContractCaller) (*ProxyadminCaller, error) { + contract, err := bindProxyadmin(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ProxyadminCaller{contract: contract}, nil +} + +// NewProxyadminTransactor creates a new write-only instance of Proxyadmin, bound to a specific deployed contract. +func NewProxyadminTransactor(address common.Address, transactor bind.ContractTransactor) (*ProxyadminTransactor, error) { + contract, err := bindProxyadmin(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ProxyadminTransactor{contract: contract}, nil +} + +// NewProxyadminFilterer creates a new log filterer instance of Proxyadmin, bound to a specific deployed contract. +func NewProxyadminFilterer(address common.Address, filterer bind.ContractFilterer) (*ProxyadminFilterer, error) { + contract, err := bindProxyadmin(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ProxyadminFilterer{contract: contract}, nil +} + +// bindProxyadmin binds a generic wrapper to an already deployed contract. +func bindProxyadmin(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ProxyadminMetaData.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 (_Proxyadmin *ProxyadminRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Proxyadmin.Contract.ProxyadminCaller.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 (_Proxyadmin *ProxyadminRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Proxyadmin.Contract.ProxyadminTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Proxyadmin *ProxyadminRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Proxyadmin.Contract.ProxyadminTransactor.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 (_Proxyadmin *ProxyadminCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Proxyadmin.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 (_Proxyadmin *ProxyadminTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Proxyadmin.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Proxyadmin *ProxyadminTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Proxyadmin.Contract.contract.Transact(opts, method, params...) +} + +// GetProxyAdmin is a free data retrieval call binding the contract method 0xf3b7dead. +// +// Solidity: function getProxyAdmin(address proxy) view returns(address) +func (_Proxyadmin *ProxyadminCaller) GetProxyAdmin(opts *bind.CallOpts, proxy common.Address) (common.Address, error) { + var out []interface{} + err := _Proxyadmin.contract.Call(opts, &out, "getProxyAdmin", proxy) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetProxyAdmin is a free data retrieval call binding the contract method 0xf3b7dead. +// +// Solidity: function getProxyAdmin(address proxy) view returns(address) +func (_Proxyadmin *ProxyadminSession) GetProxyAdmin(proxy common.Address) (common.Address, error) { + return _Proxyadmin.Contract.GetProxyAdmin(&_Proxyadmin.CallOpts, proxy) +} + +// GetProxyAdmin is a free data retrieval call binding the contract method 0xf3b7dead. +// +// Solidity: function getProxyAdmin(address proxy) view returns(address) +func (_Proxyadmin *ProxyadminCallerSession) GetProxyAdmin(proxy common.Address) (common.Address, error) { + return _Proxyadmin.Contract.GetProxyAdmin(&_Proxyadmin.CallOpts, proxy) +} + +// GetProxyImplementation is a free data retrieval call binding the contract method 0x204e1c7a. +// +// Solidity: function getProxyImplementation(address proxy) view returns(address) +func (_Proxyadmin *ProxyadminCaller) GetProxyImplementation(opts *bind.CallOpts, proxy common.Address) (common.Address, error) { + var out []interface{} + err := _Proxyadmin.contract.Call(opts, &out, "getProxyImplementation", proxy) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetProxyImplementation is a free data retrieval call binding the contract method 0x204e1c7a. +// +// Solidity: function getProxyImplementation(address proxy) view returns(address) +func (_Proxyadmin *ProxyadminSession) GetProxyImplementation(proxy common.Address) (common.Address, error) { + return _Proxyadmin.Contract.GetProxyImplementation(&_Proxyadmin.CallOpts, proxy) +} + +// GetProxyImplementation is a free data retrieval call binding the contract method 0x204e1c7a. +// +// Solidity: function getProxyImplementation(address proxy) view returns(address) +func (_Proxyadmin *ProxyadminCallerSession) GetProxyImplementation(proxy common.Address) (common.Address, error) { + return _Proxyadmin.Contract.GetProxyImplementation(&_Proxyadmin.CallOpts, proxy) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Proxyadmin *ProxyadminCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Proxyadmin.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Proxyadmin *ProxyadminSession) Owner() (common.Address, error) { + return _Proxyadmin.Contract.Owner(&_Proxyadmin.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Proxyadmin *ProxyadminCallerSession) Owner() (common.Address, error) { + return _Proxyadmin.Contract.Owner(&_Proxyadmin.CallOpts) +} + +// ChangeProxyAdmin is a paid mutator transaction binding the contract method 0x7eff275e. +// +// Solidity: function changeProxyAdmin(address proxy, address newAdmin) returns() +func (_Proxyadmin *ProxyadminTransactor) ChangeProxyAdmin(opts *bind.TransactOpts, proxy common.Address, newAdmin common.Address) (*types.Transaction, error) { + return _Proxyadmin.contract.Transact(opts, "changeProxyAdmin", proxy, newAdmin) +} + +// ChangeProxyAdmin is a paid mutator transaction binding the contract method 0x7eff275e. +// +// Solidity: function changeProxyAdmin(address proxy, address newAdmin) returns() +func (_Proxyadmin *ProxyadminSession) ChangeProxyAdmin(proxy common.Address, newAdmin common.Address) (*types.Transaction, error) { + return _Proxyadmin.Contract.ChangeProxyAdmin(&_Proxyadmin.TransactOpts, proxy, newAdmin) +} + +// ChangeProxyAdmin is a paid mutator transaction binding the contract method 0x7eff275e. +// +// Solidity: function changeProxyAdmin(address proxy, address newAdmin) returns() +func (_Proxyadmin *ProxyadminTransactorSession) ChangeProxyAdmin(proxy common.Address, newAdmin common.Address) (*types.Transaction, error) { + return _Proxyadmin.Contract.ChangeProxyAdmin(&_Proxyadmin.TransactOpts, proxy, newAdmin) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Proxyadmin *ProxyadminTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Proxyadmin.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Proxyadmin *ProxyadminSession) RenounceOwnership() (*types.Transaction, error) { + return _Proxyadmin.Contract.RenounceOwnership(&_Proxyadmin.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Proxyadmin *ProxyadminTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _Proxyadmin.Contract.RenounceOwnership(&_Proxyadmin.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Proxyadmin *ProxyadminTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Proxyadmin.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Proxyadmin *ProxyadminSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Proxyadmin.Contract.TransferOwnership(&_Proxyadmin.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Proxyadmin *ProxyadminTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Proxyadmin.Contract.TransferOwnership(&_Proxyadmin.TransactOpts, newOwner) +} + +// Upgrade is a paid mutator transaction binding the contract method 0x99a88ec4. +// +// Solidity: function upgrade(address proxy, address implementation) returns() +func (_Proxyadmin *ProxyadminTransactor) Upgrade(opts *bind.TransactOpts, proxy common.Address, implementation common.Address) (*types.Transaction, error) { + return _Proxyadmin.contract.Transact(opts, "upgrade", proxy, implementation) +} + +// Upgrade is a paid mutator transaction binding the contract method 0x99a88ec4. +// +// Solidity: function upgrade(address proxy, address implementation) returns() +func (_Proxyadmin *ProxyadminSession) Upgrade(proxy common.Address, implementation common.Address) (*types.Transaction, error) { + return _Proxyadmin.Contract.Upgrade(&_Proxyadmin.TransactOpts, proxy, implementation) +} + +// Upgrade is a paid mutator transaction binding the contract method 0x99a88ec4. +// +// Solidity: function upgrade(address proxy, address implementation) returns() +func (_Proxyadmin *ProxyadminTransactorSession) Upgrade(proxy common.Address, implementation common.Address) (*types.Transaction, error) { + return _Proxyadmin.Contract.Upgrade(&_Proxyadmin.TransactOpts, proxy, implementation) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_Proxyadmin *ProxyadminTransactor) UpgradeAndCall(opts *bind.TransactOpts, proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _Proxyadmin.contract.Transact(opts, "upgradeAndCall", proxy, implementation, data) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_Proxyadmin *ProxyadminSession) UpgradeAndCall(proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _Proxyadmin.Contract.UpgradeAndCall(&_Proxyadmin.TransactOpts, proxy, implementation, data) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_Proxyadmin *ProxyadminTransactorSession) UpgradeAndCall(proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _Proxyadmin.Contract.UpgradeAndCall(&_Proxyadmin.TransactOpts, proxy, implementation, data) +} + +// ProxyadminOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Proxyadmin contract. +type ProxyadminOwnershipTransferredIterator struct { + Event *ProxyadminOwnershipTransferred // 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 *ProxyadminOwnershipTransferredIterator) 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(ProxyadminOwnershipTransferred) + 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(ProxyadminOwnershipTransferred) + 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 *ProxyadminOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProxyadminOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProxyadminOwnershipTransferred represents a OwnershipTransferred event raised by the Proxyadmin contract. +type ProxyadminOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Proxyadmin *ProxyadminFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ProxyadminOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Proxyadmin.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ProxyadminOwnershipTransferredIterator{contract: _Proxyadmin.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Proxyadmin *ProxyadminFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ProxyadminOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Proxyadmin.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(ProxyadminOwnershipTransferred) + if err := _Proxyadmin.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Proxyadmin *ProxyadminFilterer) ParseOwnershipTransferred(log types.Log) (*ProxyadminOwnershipTransferred, error) { + event := new(ProxyadminOwnershipTransferred) + if err := _Proxyadmin.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contracts/common/transparentupgradableproxy/transparentupgradableproxy.go b/contracts/common/transparentupgradableproxy/transparentupgradableproxy.go new file mode 100644 index 0000000..2fb3e04 --- /dev/null +++ b/contracts/common/transparentupgradableproxy/transparentupgradableproxy.go @@ -0,0 +1,773 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package transparentupgradableproxy + +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 +) + +// TransparentupgradableproxyMetaData contains all meta data concerning the Transparentupgradableproxy contract. +var TransparentupgradableproxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405260405162000f6838038062000f68833981016040819052620000269162000415565b82816200003582825f6200004c565b50620000439050826200007d565b50505062000540565b6200005783620000ee565b5f82511180620000645750805b1562000078576200007683836200012f565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f620000be5f8051602062000f21833981519152546001600160a01b031690565b604080516001600160a01b03928316815291841660208301520160405180910390a1620000eb816200015e565b50565b620000f981620001fb565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b606062000157838360405180606001604052806027815260200162000f416027913962000292565b9392505050565b6001600160a01b038116620001c95760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b805f8051602062000f218339815191525b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381163b6200026a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401620001c0565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc620001da565b60605f80856001600160a01b031685604051620002b09190620004ef565b5f60405180830381855af49150503d805f8114620002ea576040519150601f19603f3d011682016040523d82523d5f602084013e620002ef565b606091505b50909250905062000303868383876200030d565b9695505050505050565b60608315620003805782515f0362000378576001600160a01b0385163b620003785760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620001c0565b50816200038c565b6200038c838362000394565b949350505050565b815115620003a55781518083602001fd5b8060405162461bcd60e51b8152600401620001c091906200050c565b80516001600160a01b0381168114620003d8575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f5b838110156200040d578181015183820152602001620003f3565b50505f910152565b5f805f6060848603121562000428575f80fd5b6200043384620003c1565b92506200044360208501620003c1565b60408501519092506001600160401b038082111562000460575f80fd5b818601915086601f83011262000474575f80fd5b815181811115620004895762000489620003dd565b604051601f8201601f19908116603f01168101908382118183101715620004b457620004b4620003dd565b81604052828152896020848701011115620004cd575f80fd5b620004e0836020830160208801620003f1565b80955050505050509250925092565b5f825162000502818460208701620003f1565b9190910192915050565b602081525f82518060208401526200052c816040850160208701620003f1565b601f01601f19169190910160400192915050565b6109d3806200054e5f395ff3fe60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f80fd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f80fd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f80fd5b5061006a6100fd366004610854565b610228565b34801561010d575f80fd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f80375f80365f845af43d5f803e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610977602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f808573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090b565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610926565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f80fd5b919050565b5f60208284031215610864575f80fd5b6104e28261082c565b5f805f6040848603121561087f575f80fd5b6108888461082c565b9250602084013567ffffffffffffffff808211156108a4575f80fd5b818601915086601f8301126108b7575f80fd5b8135818111156108c5575f80fd5b8760208285010111156108d6575f80fd5b6020830194508093505050509250925092565b5f5b838110156109035781810151838201526020016108eb565b50505f910152565b5f825161091c8184602087016108e9565b9190910192915050565b602081525f82518060208401526109448160408501602087016108e9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212202ac98acbfbb3d3ac1b74050e18c4e76db25a3ff2801ec69bf85d0c61414d502b64736f6c63430008140033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", +} + +// TransparentupgradableproxyABI is the input ABI used to generate the binding from. +// Deprecated: Use TransparentupgradableproxyMetaData.ABI instead. +var TransparentupgradableproxyABI = TransparentupgradableproxyMetaData.ABI + +// TransparentupgradableproxyBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TransparentupgradableproxyMetaData.Bin instead. +var TransparentupgradableproxyBin = TransparentupgradableproxyMetaData.Bin + +// DeployTransparentupgradableproxy deploys a new Ethereum contract, binding an instance of Transparentupgradableproxy to it. +func DeployTransparentupgradableproxy(auth *bind.TransactOpts, backend bind.ContractBackend, _logic common.Address, admin_ common.Address, _data []byte) (common.Address, *types.Transaction, *Transparentupgradableproxy, error) { + parsed, err := TransparentupgradableproxyMetaData.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(TransparentupgradableproxyBin), backend, _logic, admin_, _data) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Transparentupgradableproxy{TransparentupgradableproxyCaller: TransparentupgradableproxyCaller{contract: contract}, TransparentupgradableproxyTransactor: TransparentupgradableproxyTransactor{contract: contract}, TransparentupgradableproxyFilterer: TransparentupgradableproxyFilterer{contract: contract}}, nil +} + +// Transparentupgradableproxy is an auto generated Go binding around an Ethereum contract. +type Transparentupgradableproxy struct { + TransparentupgradableproxyCaller // Read-only binding to the contract + TransparentupgradableproxyTransactor // Write-only binding to the contract + TransparentupgradableproxyFilterer // Log filterer for contract events +} + +// TransparentupgradableproxyCaller is an auto generated read-only Go binding around an Ethereum contract. +type TransparentupgradableproxyCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentupgradableproxyTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TransparentupgradableproxyTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentupgradableproxyFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TransparentupgradableproxyFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentupgradableproxySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TransparentupgradableproxySession struct { + Contract *Transparentupgradableproxy // 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 +} + +// TransparentupgradableproxyCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TransparentupgradableproxyCallerSession struct { + Contract *TransparentupgradableproxyCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TransparentupgradableproxyTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TransparentupgradableproxyTransactorSession struct { + Contract *TransparentupgradableproxyTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TransparentupgradableproxyRaw is an auto generated low-level Go binding around an Ethereum contract. +type TransparentupgradableproxyRaw struct { + Contract *Transparentupgradableproxy // Generic contract binding to access the raw methods on +} + +// TransparentupgradableproxyCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TransparentupgradableproxyCallerRaw struct { + Contract *TransparentupgradableproxyCaller // Generic read-only contract binding to access the raw methods on +} + +// TransparentupgradableproxyTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TransparentupgradableproxyTransactorRaw struct { + Contract *TransparentupgradableproxyTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTransparentupgradableproxy creates a new instance of Transparentupgradableproxy, bound to a specific deployed contract. +func NewTransparentupgradableproxy(address common.Address, backend bind.ContractBackend) (*Transparentupgradableproxy, error) { + contract, err := bindTransparentupgradableproxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Transparentupgradableproxy{TransparentupgradableproxyCaller: TransparentupgradableproxyCaller{contract: contract}, TransparentupgradableproxyTransactor: TransparentupgradableproxyTransactor{contract: contract}, TransparentupgradableproxyFilterer: TransparentupgradableproxyFilterer{contract: contract}}, nil +} + +// NewTransparentupgradableproxyCaller creates a new read-only instance of Transparentupgradableproxy, bound to a specific deployed contract. +func NewTransparentupgradableproxyCaller(address common.Address, caller bind.ContractCaller) (*TransparentupgradableproxyCaller, error) { + contract, err := bindTransparentupgradableproxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TransparentupgradableproxyCaller{contract: contract}, nil +} + +// NewTransparentupgradableproxyTransactor creates a new write-only instance of Transparentupgradableproxy, bound to a specific deployed contract. +func NewTransparentupgradableproxyTransactor(address common.Address, transactor bind.ContractTransactor) (*TransparentupgradableproxyTransactor, error) { + contract, err := bindTransparentupgradableproxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TransparentupgradableproxyTransactor{contract: contract}, nil +} + +// NewTransparentupgradableproxyFilterer creates a new log filterer instance of Transparentupgradableproxy, bound to a specific deployed contract. +func NewTransparentupgradableproxyFilterer(address common.Address, filterer bind.ContractFilterer) (*TransparentupgradableproxyFilterer, error) { + contract, err := bindTransparentupgradableproxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TransparentupgradableproxyFilterer{contract: contract}, nil +} + +// bindTransparentupgradableproxy binds a generic wrapper to an already deployed contract. +func bindTransparentupgradableproxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TransparentupgradableproxyMetaData.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 (_Transparentupgradableproxy *TransparentupgradableproxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Transparentupgradableproxy.Contract.TransparentupgradableproxyCaller.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 (_Transparentupgradableproxy *TransparentupgradableproxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.TransparentupgradableproxyTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Transparentupgradableproxy *TransparentupgradableproxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.TransparentupgradableproxyTransactor.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 (_Transparentupgradableproxy *TransparentupgradableproxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Transparentupgradableproxy.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 (_Transparentupgradableproxy *TransparentupgradableproxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.contract.Transact(opts, method, params...) +} + +// Admin is a paid mutator transaction binding the contract method 0xf851a440. +// +// Solidity: function admin() returns(address admin_) +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactor) Admin(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Transparentupgradableproxy.contract.Transact(opts, "admin") +} + +// Admin is a paid mutator transaction binding the contract method 0xf851a440. +// +// Solidity: function admin() returns(address admin_) +func (_Transparentupgradableproxy *TransparentupgradableproxySession) Admin() (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Admin(&_Transparentupgradableproxy.TransactOpts) +} + +// Admin is a paid mutator transaction binding the contract method 0xf851a440. +// +// Solidity: function admin() returns(address admin_) +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorSession) Admin() (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Admin(&_Transparentupgradableproxy.TransactOpts) +} + +// ChangeAdmin is a paid mutator transaction binding the contract method 0x8f283970. +// +// Solidity: function changeAdmin(address newAdmin) returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactor) ChangeAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _Transparentupgradableproxy.contract.Transact(opts, "changeAdmin", newAdmin) +} + +// ChangeAdmin is a paid mutator transaction binding the contract method 0x8f283970. +// +// Solidity: function changeAdmin(address newAdmin) returns() +func (_Transparentupgradableproxy *TransparentupgradableproxySession) ChangeAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.ChangeAdmin(&_Transparentupgradableproxy.TransactOpts, newAdmin) +} + +// ChangeAdmin is a paid mutator transaction binding the contract method 0x8f283970. +// +// Solidity: function changeAdmin(address newAdmin) returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorSession) ChangeAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.ChangeAdmin(&_Transparentupgradableproxy.TransactOpts, newAdmin) +} + +// Implementation is a paid mutator transaction binding the contract method 0x5c60da1b. +// +// Solidity: function implementation() returns(address implementation_) +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactor) Implementation(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Transparentupgradableproxy.contract.Transact(opts, "implementation") +} + +// Implementation is a paid mutator transaction binding the contract method 0x5c60da1b. +// +// Solidity: function implementation() returns(address implementation_) +func (_Transparentupgradableproxy *TransparentupgradableproxySession) Implementation() (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Implementation(&_Transparentupgradableproxy.TransactOpts) +} + +// Implementation is a paid mutator transaction binding the contract method 0x5c60da1b. +// +// Solidity: function implementation() returns(address implementation_) +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorSession) Implementation() (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Implementation(&_Transparentupgradableproxy.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _Transparentupgradableproxy.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_Transparentupgradableproxy *TransparentupgradableproxySession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.UpgradeTo(&_Transparentupgradableproxy.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.UpgradeTo(&_Transparentupgradableproxy.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _Transparentupgradableproxy.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxySession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.UpgradeToAndCall(&_Transparentupgradableproxy.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.UpgradeToAndCall(&_Transparentupgradableproxy.TransactOpts, newImplementation, data) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _Transparentupgradableproxy.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxySession) Fallback(calldata []byte) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Fallback(&_Transparentupgradableproxy.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Fallback(&_Transparentupgradableproxy.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Transparentupgradableproxy.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxySession) Receive() (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Receive(&_Transparentupgradableproxy.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Transparentupgradableproxy *TransparentupgradableproxyTransactorSession) Receive() (*types.Transaction, error) { + return _Transparentupgradableproxy.Contract.Receive(&_Transparentupgradableproxy.TransactOpts) +} + +// TransparentupgradableproxyAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the Transparentupgradableproxy contract. +type TransparentupgradableproxyAdminChangedIterator struct { + Event *TransparentupgradableproxyAdminChanged // 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 *TransparentupgradableproxyAdminChangedIterator) 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(TransparentupgradableproxyAdminChanged) + 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(TransparentupgradableproxyAdminChanged) + 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 *TransparentupgradableproxyAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TransparentupgradableproxyAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TransparentupgradableproxyAdminChanged represents a AdminChanged event raised by the Transparentupgradableproxy contract. +type TransparentupgradableproxyAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*TransparentupgradableproxyAdminChangedIterator, error) { + + logs, sub, err := _Transparentupgradableproxy.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &TransparentupgradableproxyAdminChangedIterator{contract: _Transparentupgradableproxy.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *TransparentupgradableproxyAdminChanged) (event.Subscription, error) { + + logs, sub, err := _Transparentupgradableproxy.contract.WatchLogs(opts, "AdminChanged") + 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(TransparentupgradableproxyAdminChanged) + if err := _Transparentupgradableproxy.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) ParseAdminChanged(log types.Log) (*TransparentupgradableproxyAdminChanged, error) { + event := new(TransparentupgradableproxyAdminChanged) + if err := _Transparentupgradableproxy.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TransparentupgradableproxyBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the Transparentupgradableproxy contract. +type TransparentupgradableproxyBeaconUpgradedIterator struct { + Event *TransparentupgradableproxyBeaconUpgraded // 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 *TransparentupgradableproxyBeaconUpgradedIterator) 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(TransparentupgradableproxyBeaconUpgraded) + 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(TransparentupgradableproxyBeaconUpgraded) + 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 *TransparentupgradableproxyBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TransparentupgradableproxyBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TransparentupgradableproxyBeaconUpgraded represents a BeaconUpgraded event raised by the Transparentupgradableproxy contract. +type TransparentupgradableproxyBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*TransparentupgradableproxyBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _Transparentupgradableproxy.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &TransparentupgradableproxyBeaconUpgradedIterator{contract: _Transparentupgradableproxy.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *TransparentupgradableproxyBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _Transparentupgradableproxy.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(TransparentupgradableproxyBeaconUpgraded) + if err := _Transparentupgradableproxy.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) ParseBeaconUpgraded(log types.Log) (*TransparentupgradableproxyBeaconUpgraded, error) { + event := new(TransparentupgradableproxyBeaconUpgraded) + if err := _Transparentupgradableproxy.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TransparentupgradableproxyUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the Transparentupgradableproxy contract. +type TransparentupgradableproxyUpgradedIterator struct { + Event *TransparentupgradableproxyUpgraded // 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 *TransparentupgradableproxyUpgradedIterator) 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(TransparentupgradableproxyUpgraded) + 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(TransparentupgradableproxyUpgraded) + 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 *TransparentupgradableproxyUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TransparentupgradableproxyUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TransparentupgradableproxyUpgraded represents a Upgraded event raised by the Transparentupgradableproxy contract. +type TransparentupgradableproxyUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*TransparentupgradableproxyUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _Transparentupgradableproxy.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &TransparentupgradableproxyUpgradedIterator{contract: _Transparentupgradableproxy.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *TransparentupgradableproxyUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _Transparentupgradableproxy.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(TransparentupgradableproxyUpgraded) + if err := _Transparentupgradableproxy.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_Transparentupgradableproxy *TransparentupgradableproxyFilterer) ParseUpgraded(log types.Log) (*TransparentupgradableproxyUpgraded, error) { + event := new(TransparentupgradableproxyUpgraded) + if err := _Transparentupgradableproxy.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/createRollupManagerParams.example.json b/createRollupManagerParams.example.json new file mode 100644 index 0000000..12da3ce --- /dev/null +++ b/createRollupManagerParams.example.json @@ -0,0 +1,12 @@ +{ + "useDeployerAsAdminForRollupManager": true, + "timelockAdminAddress": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "minDelayTimelock": 3600, + "salt": "0x0000000000000000000000000000000000000000000000000000000000000000", + "initialZkEVMDeployerOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "trustedAggregator": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "trustedAggregatorTimeout": 604799, + "pendingStateTimeout": 604799, + "emergencyCouncilAddress": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" +} \ No newline at end of file diff --git a/createRollupParams.example.json b/createRollupParams.example.json new file mode 100644 index 0000000..74ab347 --- /dev/null +++ b/createRollupParams.example.json @@ -0,0 +1,10 @@ +{ + "rollupTypeID": 1, + "chainID": 1001, + "adminZkEVM": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "trustedSequencer": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "gasTokenAddress": "0x0000000000000000000000000000000000000000", + "trustedSequencerURL": "http://zkevm-json-rpc:8123", + "networkName": "zkevm", + "consensusType": "validium" +} diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..bdcb88e --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,8 @@ +FROM ethereum/client-go:v1.13.14 + +EXPOSE 8545 +EXPOSE 9545 + +COPY gethData / + +ENTRYPOINT ["geth", "--rpc.allow-unprotected-txs", "--http", "--http.addr", "0.0.0.0", "--http.corsdomain", "*", "--http.vhosts", "*", "--ws", "--ws.origins", "*", "--ws.addr", "0.0.0.0", "--dev", "--dev.period", "1", "--datadir", "/geth_data"] \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..f5225be --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,32 @@ +version: "3.3" +services: + cdk-mock-l1: + container_name: cdk-mock-l1 + image: ethereum/client-go:v1.13.14 + user: "${UID}:${GID}" + ports: + - "8545:8545" + volumes: + - ./gethData/geth_data:/geth_data + entrypoint: + - geth + - --rpc.allow-unprotected-txs + - --http + - --http.addr + - "0.0.0.0" + - --dev + - --dev.period + - "1" + - --datadir + - /geth_data + + cdk-l1-funder: + network_mode: host + container_name: cdk-l1-funder + image: node:16 + depends_on: + - cdk-mock-l1 + volumes: + - ${PWD}/fundAccount:/home/node/project + working_dir: /home/node/project + command: /bin/sh -c "npm i && node fundAccounts.js" diff --git a/docker/docker.go b/docker/docker.go new file mode 100644 index 0000000..a997419 --- /dev/null +++ b/docker/docker.go @@ -0,0 +1,125 @@ +package docker + +import ( + "context" + "errors" + "fmt" + "math/big" + "os" + "os/exec" + "path" + "strconv" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" +) + +func StartMockL1Docker(ctx context.Context) error { + var err error + err = os.Chdir("./docker") + if err != nil { + return err + } + defer func() { err = os.Chdir("..") }() + + err = os.RemoveAll("gethData") + if err != nil { + return err + } + err = os.MkdirAll(path.Join("gethData", "geth_data"), 0744) + if err != nil { + return err + } + os.Geteuid() + gid := os.Getegid() + uid := os.Geteuid() + err = os.Setenv("GID", strconv.Itoa(gid)) + if err != nil { + return err + } + err = os.Setenv("UID", strconv.Itoa(uid)) + if err != nil { + return err + } + err = exec.Command("docker", "compose", "up", "-d", "cdk-mock-l1").Run() + if err != nil { + return fmt.Errorf("error running dockerized geth: %s", err) + } + client, err := ethclient.Dial("http://localhost:8545") + if err != nil { + return fmt.Errorf("error dialing dockerized geth: %s", err) + } + var l1Started bool + for i := 0; i < 10; i++ { + bn, _ := client.BlockNumber(ctx) + if bn > 1 { + l1Started = true + break + } + time.Sleep(time.Second) + } + if !l1Started { + return errors.New("mock L1 network failed to start") + } + + fundCmd := exec.Command("docker", "compose", "up", "cdk-l1-funder") + currentDir, err := os.Getwd() + if err != nil { + return err + } + fundCmd.Dir = currentDir + err = fundCmd.Run() + if err != nil { + return fmt.Errorf("error running funding script: %s", err) + } + var accountHasBalance bool + for i := 0; i < 10; i++ { + balance, err := client.BalanceAt(ctx, common.HexToAddress("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"), nil) + if err != nil { + return fmt.Errorf("error getting balance: %s", err) + } + if balance.Cmp(big.NewInt(0)) == 1 { + accountHasBalance = true + break + } + time.Sleep(time.Second) + } + if !accountHasBalance { + return errors.New("failed to fund account") + } + + return err +} + +func StopMockL1Docker() error { + var err error + err = os.Chdir("./docker") + if err != nil { + return err + } + defer func() { err = os.Chdir("..") }() + + return exec.Command("docker", "compose", "down").Run() +} + +func BuildL1FromMock(imageName string) error { + var err error + err = os.Chdir("./docker") + if err != nil { + return err + } + defer func() { err = os.Chdir("..") }() + + err = exec.Command("docker", "compose", "down").Run() + if err != nil { + return err + } + + err = exec.Command("docker", "build", "-t", imageName, ".").Run() + if err != nil { + return err + } + + return err +} diff --git a/docker/fundAccount/fundAccounts.js b/docker/fundAccount/fundAccounts.js new file mode 100644 index 0000000..cd1627d --- /dev/null +++ b/docker/fundAccount/fundAccounts.js @@ -0,0 +1,37 @@ +/* eslint-disable no-await-in-loop */ + +const ethers = require('ethers'); + +const MNEMONIC = 'test test test test test test test test test test test junk'; +const DEFAULT_NUM_ACCOUNTS = 20; + +async function main() { + const currentProvider = ethers.getDefaultProvider('http://localhost:8545'); + const signerNode = await currentProvider.getSigner(); + const numAccountsToFund = process.env.NUM_ACCOUNTS || DEFAULT_NUM_ACCOUNTS; + + for (let i = 0; i < numAccountsToFund; i++) { + const pathWallet = `m/44'/60'/0'/0/${i}`; + const accountWallet = ethers.HDNodeWallet.fromMnemonic( + ethers.Mnemonic.fromPhrase(MNEMONIC), + pathWallet, + ); + + const params = [{ + from: await signerNode.getAddress(), + to: accountWallet.address, + value: '0x3635C9ADC5DEA00000', + }]; + const tx = await currentProvider.send('eth_sendTransaction', params); + if (i === numAccountsToFund - 1) { + await currentProvider.waitForTransaction(tx); + } + } +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/docker/fundAccount/package-lock.json b/docker/fundAccount/package-lock.json new file mode 100644 index 0000000..41e2e47 --- /dev/null +++ b/docker/fundAccount/package-lock.json @@ -0,0 +1,160 @@ +{ + "name": "fundaccount", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "fundaccount", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "ethers": "^6.11.1" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/ethers": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.11.1.tgz", + "integrity": "sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + }, + "dependencies": { + "@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, + "@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "requires": { + "@noble/hashes": "1.3.2" + } + }, + "@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" + }, + "@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "ethers": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.11.1.tgz", + "integrity": "sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==", + "requires": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "requires": {} + } + } +} diff --git a/docker/fundAccount/package.json b/docker/fundAccount/package.json new file mode 100644 index 0000000..ef10122 --- /dev/null +++ b/docker/fundAccount/package.json @@ -0,0 +1,14 @@ +{ + "name": "fundaccount", + "version": "1.0.0", + "description": "", + "main": "fundAccounts.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "ethers": "^6.11.1" + } +} diff --git a/genesis/0x489e44072604e671274ea693d5309e797fb37a3e0d91e5b0f04639c251c05332.json b/genesis/0x489e44072604e671274ea693d5309e797fb37a3e0d91e5b0f04639c251c05332.json new file mode 100644 index 0000000..9afe825 --- /dev/null +++ b/genesis/0x489e44072604e671274ea693d5309e797fb37a3e0d91e5b0f04639c251c05332.json @@ -0,0 +1,89 @@ +[ + { + "contractName": "PolygonZkEVMDeployer", + "balance": "0", + "nonce": "4", + "address": "0xFbD07134824dDEa24E4ae414c18ecbFa98169A24", + "bytecode": "0x60806040526004361061006e575f3560e01c8063715018a61161004c578063715018a6146100e25780638da5cb5b146100f6578063e11ae6cb1461011f578063f2fde38b14610132575f80fd5b80632b79805a146100725780634a94d487146100875780636d07dbf81461009a575b5f80fd5b610085610080366004610908565b610151565b005b6100856100953660046109a2565b6101c2565b3480156100a5575f80fd5b506100b96100b43660046109f5565b610203565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ed575f80fd5b50610085610215565b348015610101575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff166100b9565b61008561012d366004610a15565b610228565b34801561013d575f80fd5b5061008561014c366004610a61565b61028e565b61015961034a565b5f6101658585856103ca565b90506101718183610527565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101ca61034a565b6101d583838361056a565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b905f90a1505050565b5f61020e8383610598565b9392505050565b61021d61034a565b6102265f6105a4565b565b61023061034a565b5f61023c8484846103ca565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b61029661034a565b73ffffffffffffffffffffffffffffffffffffffff811661033e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610347816105a4565b50565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610335565b5f83471015610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610335565b81515f0361049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610335565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff811661020e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610335565b606061020e83835f6040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610618565b6060610590848484604051806060016040528060298152602001610b0860299139610618565b949350505050565b5f61020e83833061072d565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610335565b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516106d29190610a9c565b5f6040518083038185875af1925050503d805f811461070c576040519150601f19603f3d011682016040523d82523d5f602084013e610711565b606091505b509150915061072287838387610756565b979650505050505050565b5f604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156107eb5782515f036107e45773ffffffffffffffffffffffffffffffffffffffff85163b6107e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610335565b5081610590565b61059083838151156108005781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103359190610ab7565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112610870575f80fd5b813567ffffffffffffffff8082111561088b5761088b610834565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108d1576108d1610834565b816040528381528660208588010111156108e9575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f806080858703121561091b575f80fd5b8435935060208501359250604085013567ffffffffffffffff80821115610940575f80fd5b61094c88838901610861565b93506060870135915080821115610961575f80fd5b5061096e87828801610861565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff8116811461099d575f80fd5b919050565b5f805f606084860312156109b4575f80fd5b6109bd8461097a565b9250602084013567ffffffffffffffff8111156109d8575f80fd5b6109e486828701610861565b925050604084013590509250925092565b5f8060408385031215610a06575f80fd5b50508035926020909101359150565b5f805f60608486031215610a27575f80fd5b8335925060208401359150604084013567ffffffffffffffff811115610a4b575f80fd5b610a5786828701610861565b9150509250925092565b5f60208284031215610a71575f80fd5b61020e8261097a565b5f5b83811015610a94578181015183820152602001610a7c565b50505f910152565b5f8251610aad818460208701610a7a565b9190910192915050565b602081525f8251806020840152610ad5816040850160208701610a7a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220330b94dc698c4d290bf55c23f13b473cde6a6bae0030cb902de18af54e35839f64736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + { + "contractName": "ProxyAdmin", + "balance": "0", + "nonce": "1", + "address": "0xfADB60b5059e31614e02083fF6C021a24C31c891", + "bytecode": "0x608060405260043610610079575f3560e01c80639623609d1161004c5780639623609d1461012357806399a88ec414610136578063f2fde38b14610155578063f3b7dead14610174575f80fd5b8063204e1c7a1461007d578063715018a6146100c55780637eff275e146100db5780638da5cb5b146100fa575b5f80fd5b348015610088575f80fd5b5061009c6100973660046105e8565b610193565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d0575f80fd5b506100d9610244565b005b3480156100e6575f80fd5b506100d96100f536600461060a565b610257565b348015610105575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff1661009c565b6100d961013136600461066e565b6102e0565b348015610141575f80fd5b506100d961015036600461060a565b610371565b348015610160575f80fd5b506100d961016f3660046105e8565b6103cd565b34801561017f575f80fd5b5061009c61018e3660046105e8565b610489565b5f805f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b5f60405180830381855afa9150503d805f8114610215576040519150601f19603f3d011682016040523d82523d5f602084013e61021a565b606091505b509150915081610228575f80fd5b8080602001905181019061023c919061075b565b949350505050565b61024c6104d3565b6102555f610553565b565b61025f6104d3565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b5f604051808303815f87803b1580156102c6575f80fd5b505af11580156102d8573d5f803e3d5ffd5b505050505050565b6102e86104d3565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061033e9086908690600401610776565b5f604051808303818588803b158015610355575f80fd5b505af1158015610367573d5f803e3d5ffd5b5050505050505050565b6103796104d3565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102af565b6103d56104d3565b73ffffffffffffffffffffffffffffffffffffffff811661047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61048681610553565b50565b5f805f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610474565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610486575f80fd5b5f602082840312156105f8575f80fd5b8135610603816105c7565b9392505050565b5f806040838503121561061b575f80fd5b8235610626816105c7565b91506020830135610636816105c7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f805f60608486031215610680575f80fd5b833561068b816105c7565b9250602084013561069b816105c7565b9150604084013567ffffffffffffffff808211156106b7575f80fd5b818601915086601f8301126106ca575f80fd5b8135818111156106dc576106dc610641565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561072257610722610641565b8160405282815289602084870101111561073a575f80fd5b826020860160208301375f6020848301015280955050505050509250925092565b5f6020828403121561076b575f80fd5b8151610603816105c7565b73ffffffffffffffffffffffffffffffffffffffff831681525f602060408184015283518060408501525f5b818110156107be578581018301518582016060015282016107a2565b505f6060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea26469706673582212203083a4ccc2e42eed60bd19037f2efa77ed086dc7a5403f75bebb995dcba2221c64736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f" + } + }, + { + "contractName": "PolygonZkEVMBridge implementation", + "balance": "0", + "nonce": "1", + "address": "0x608484d3e94Fc775E3dCb06B0B48486c60A315e6", + "bytecode": "0x6080604052600436106101db575f3560e01c806383f24403116100fd578063ccaa2d1111610092578063ee25560b11610062578063ee25560b146105a9578063f5efcd79146105d4578063f811bff7146105f3578063fb57083414610612575f80fd5b8063ccaa2d111461053b578063cd5865791461055a578063d02103ca1461056d578063dbc1697614610595575f80fd5b8063bab161bf116100cd578063bab161bf146104b9578063be5831c7146104da578063c00f14ab146104fd578063cc4616321461051c575f80fd5b806383f244031461043d5780638ed7e3f21461045c578063aaa13cc21461047b578063b8b284d01461049a575f80fd5b80633cbc795b116101735780637843298b116101435780637843298b146103c257806379e2cf97146103e157806381b1c174146103f557806383c43a5514610429575f80fd5b80633cbc795b146103385780633e197043146103705780634b2f336d1461038f5780635ca1e165146103ae575f80fd5b806327aef4e8116101ae57806327aef4e81461026d5780632dfdf0b51461028e578063318aee3d146102b15780633c351e1014610319575f80fd5b806315064c96146101df5780632072f6c51461020d57806322e95f2c14610223578063240ff3781461025a575b5f80fd5b3480156101ea575f80fd5b506068546101f89060ff1681565b60405190151581526020015b60405180910390f35b348015610218575f80fd5b50610221610631565b005b34801561022e575f80fd5b5061024261023d366004612fb9565b610666565b6040516001600160a01b039091168152602001610204565b610221610268366004613040565b6106d0565b348015610278575f80fd5b50610281610759565b6040516102049190613102565b348015610299575f80fd5b506102a360535481565b604051908152602001610204565b3480156102bc575f80fd5b506102f56102cb36600461311b565b606b6020525f908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b03909116602083015201610204565b348015610324575f80fd5b50606d54610242906001600160a01b031681565b348015610343575f80fd5b50606d5461035b90600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610204565b34801561037b575f80fd5b506102a361038a366004613144565b6107e5565b34801561039a575f80fd5b50606f54610242906001600160a01b031681565b3480156103b9575f80fd5b506102a361088e565b3480156103cd575f80fd5b506102426103dc3660046131be565b61096a565b3480156103ec575f80fd5b50610221610993565b348015610400575f80fd5b5061024261040f366004613204565b606a6020525f90815260409020546001600160a01b031681565b348015610434575f80fd5b506102816109b4565b348015610448575f80fd5b506102a361045736600461322c565b6109d3565b348015610467575f80fd5b50606c54610242906001600160a01b031681565b348015610486575f80fd5b5061024261049536600461332d565b610aa8565b3480156104a5575f80fd5b506102216104b43660046133c3565b610be7565b3480156104c4575f80fd5b5060685461035b90610100900463ffffffff1681565b3480156104e5575f80fd5b5060685461035b90600160c81b900463ffffffff1681565b348015610508575f80fd5b5061028161051736600461311b565b610cc2565b348015610527575f80fd5b506101f8610536366004613441565b610d07565b348015610546575f80fd5b50610221610555366004613472565b610d8f565b610221610568366004613556565b6112c0565b348015610578575f80fd5b50606854610242906501000000000090046001600160a01b031681565b3480156105a0575f80fd5b5061022161172c565b3480156105b4575f80fd5b506102a36105c3366004613204565b60696020525f908152604090205481565b3480156105df575f80fd5b506102216105ee366004613472565b61175f565b3480156105fe575f80fd5b5061022161060d3660046135e6565b611a25565b34801561061d575f80fd5b506101f861062c366004613689565b611d40565b606c546001600160a01b0316331461065c57604051631736745960e31b815260040160405180910390fd5b610664611d57565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091205f908152606a90915220546001600160a01b03165b92915050565b60685460ff16156106f457604051630bc011ff60e21b815260040160405180910390fd5b341580159061070d5750606f546001600160a01b031615155b15610744576040517f6f625c4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610752858534868686611db2565b5050505050565b606e8054610766906136ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610792906136ce565b80156107dd5780601f106107b4576101008083540402835291602001916107dd565b820191905f5260205f20905b8154815290600101906020018083116107c057829003601f168201915b505050505081565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d82015260518101839052607181018290525f90609101604051602081830303815290604052805190602001209050979650505050505050565b6053545f90819081805b6020811015610961578083901c6001166001036108f557603381602081106108c2576108c2613706565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350610922565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806109599061372e565b915050610898565b50919392505050565b5f61098b848461097985611e7c565b61098286611f66565b61049587612047565b949350505050565b605354606854600160c81b900463ffffffff16101561066457610664612114565b60405180611ba00160405280611b668152602001613d80611b66913981565b5f83815b6020811015610a9f57600163ffffffff8516821c81169003610a4257848160208110610a0557610a05613706565b602002013582604051602001610a25929190918252602082015260400190565b604051602081830303815290604052805190602001209150610a8d565b81858260208110610a5557610a55613706565b6020020135604051602001610a74929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80610a978161372e565b9150506109d7565b50949350505050565b6040516001600160e01b031960e087901b1660208201526bffffffffffffffffffffffff19606086901b1660248201525f9081906038016040516020818303038152906040528051906020012090505f60ff60f81b308360405180611ba00160405280611b668152602001613d80611b669139898989604051602001610b3093929190613746565b60408051601f1981840301815290829052610b4e929160200161377e565b60405160208183030381529060405280519060200120604051602001610bc394939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610c0b57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610c4d576040517fdde3cda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b158015610c96575f80fd5b505af1158015610ca8573d5f803e3d5ffd5b50505050610cba868686868686611db2565b505050505050565b6060610ccd82611e7c565b610cd683611f66565b610cdf84612047565b604051602001610cf193929190613746565b6040516020818303038152906040529050919050565b6068545f908190610100900463ffffffff16158015610d2c575063ffffffff83166001145b15610d3e575063ffffffff8316610d66565b610d5364010000000063ffffffff85166137ac565b610d639063ffffffff86166137c3565b90505b600881901c5f90815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610db357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614610de3576040516302caf51760e11b815260040160405180910390fd5b610e168c8c8c8c8c610e115f8e8e8e8e8e8e8e604051610e049291906137d6565b60405180910390206107e5565b6121c2565b6001600160a01b038616610f6057606f546001600160a01b0316610efa575f6001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610e6c576020820181803683370190505b50604051610e7a91906137e5565b5f6040518083038185875af1925050503d805f8114610eb4576040519150601f19603f3d011682016040523d82523d5f602084013e610eb9565b606091505b5050905080610ef4576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611256565b606f546040516340c10f1960e01b81526001600160a01b03868116600483015260248201869052909116906340c10f19906044015f604051808303815f87803b158015610f45575f80fd5b505af1158015610f57573d5f803e3d5ffd5b50505050611256565b606d546001600160a01b038781169116148015610f8e5750606d5463ffffffff888116600160a01b90920416145b15610fa5575f6001600160a01b0385168482610e42565b60685463ffffffff610100909104811690881603610fd657610fd16001600160a01b0387168585612354565b611256565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b1660248201525f9060380160408051601f1981840301815291815281516020928301205f818152606a9093529120549091506001600160a01b0316806111f5575f6110808386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506123d592505050565b6040516340c10f1960e01b81526001600160a01b03898116600483015260248201899052919250908216906340c10f19906044015f604051808303815f87803b1580156110cb575f80fd5b505af11580156110dd573d5f803e3d5ffd5b5050505080606a5f8581526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b5f836001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548163ffffffff021916908363ffffffff1602179055506020820151815f0160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a8388886040516111e7959493929190613828565b60405180910390a150611253565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f19906044015f604051808303815f87803b15801561123c575f80fd5b505af115801561124e573d5f803e3d5ffd5b505050505b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a1505050505050505050505050565b60685460ff16156112e457604051630bc011ff60e21b815260040160405180910390fd5b6112ec612468565b60685463ffffffff61010090910481169088160361131d576040516302caf51760e11b815260040160405180910390fd5b5f806060876001600160a01b03881661141957883414611369576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff16945090611396906136ce565b80601f01602080910402602001604051908101604052809291908181526020018280546113c2906136ce565b801561140d5780601f106113e45761010080835404028352916020019161140d565b820191905f5260205f20905b8154815290600101906020018083116113f057829003601f168201915b505050505091506116a3565b3415611451576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f546001600160a01b03908116908916036114c757604051632770a7eb60e21b8152336004820152602481018a90526001600160a01b03891690639dc29fac906044015f604051808303815f87803b1580156114ac575f80fd5b505af11580156114be573d5f803e3d5ffd5b505050506116a3565b6001600160a01b038089165f908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901561157957604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac906044015f604051808303815f87803b158015611551575f80fd5b505af1158015611563573d5f803e3d5ffd5b5050505080602001519450805f01519350611696565b851561158b5761158b898b89896124c1565b6040516370a0823160e01b81523060048201525f906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156115cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f39190613860565b905061160a6001600160a01b038b1633308e612860565b6040516370a0823160e01b81523060048201525f906001600160a01b038c16906370a0823190602401602060405180830381865afa15801561164e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116729190613860565b905061167e8282613877565b6068548c9850610100900463ffffffff169650935050505b61169f89610cc2565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b5f84868e8e86886053546040516116e298979695949392919061388a565b60405180910390a16117086117035f85878f8f8789805190602001206107e5565b6128b1565b861561171657611716612114565b5050505061172360018055565b50505050505050565b606c546001600160a01b0316331461175757604051631736745960e31b815260040160405180910390fd5b6106646129b2565b60685460ff161561178357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff86811661010090920416146117b3576040516302caf51760e11b815260040160405180910390fd5b6117d58c8c8c8c8c610e1160018e8e8e8e8e8e8e604051610e049291906137d6565b606f545f906001600160a01b031661188857846001600160a01b031684888a868660405160240161180994939291906138f3565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161183e91906137e5565b5f6040518083038185875af1925050503d805f8114611878576040519150601f19603f3d011682016040523d82523d5f602084013e61187d565b606091505b505080915050611983565b606f546040516340c10f1960e01b81526001600160a01b03878116600483015260248201879052909116906340c10f19906044015f604051808303815f87803b1580156118d3575f80fd5b505af11580156118e5573d5f803e3d5ffd5b50505050846001600160a01b03168789858560405160240161190a94939291906138f3565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161193f91906137e5565b5f604051808303815f865af19150503d805f8114611978576040519150601f19603f3d011682016040523d82523d5f602084013e61197d565b606091505b50909150505b806119ba576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b5f54610100900460ff1615808015611a4357505f54600160ff909116105b80611a5c5750303b158015611a5c57505f5460ff166001145b611ad35760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b5f805460ff191660011790558015611af4575f805461ff0019166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff19168583161790558616611bcf5763ffffffff851615611bca576040517f1a874c1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ceb565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e611c1e8382613970565b50611cbd5f801b6012604051602001611ca991906060808252600d908201527f5772617070656420457468657200000000000000000000000000000000000000608082015260a0602082018190526004908201527f574554480000000000000000000000000000000000000000000000000000000060c082015260ff91909116604082015260e00190565b6040516020818303038152906040526123d5565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555b611cf3612a22565b8015611723575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b5f81611d4d8686866109d3565b1495945050505050565b60685460ff1615611d7b57604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497905f90a1565b60685463ffffffff610100909104811690871603611de3576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611e3799989796959493929190613a2c565b60405180910390a1611e6e6117036001606860019054906101000a900463ffffffff16338a8a8a8989604051610e049291906137d6565b8215610cba57610cba612114565b60408051600481526024810182526020810180516001600160e01b03167f06fdde030000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611edb91906137e5565b5f60405180830381855afa9150503d805f8114611f13576040519150601f19603f3d011682016040523d82523d5f602084013e611f18565b606091505b509150915081611f5d576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525061098b565b61098b81612a94565b60408051600481526024810182526020810180516001600160e01b03167f95d89b410000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611fc591906137e5565b5f60405180830381855afa9150503d805f8114611ffd576040519150601f19603f3d011682016040523d82523d5f602084013e612002565b606091505b509150915081611f5d576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525061098b565b60408051600481526024810182526020810180516001600160e01b03167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f91829182916001600160a01b038616916120a591906137e5565b5f60405180830381855afa9150503d805f81146120dd576040519150601f19603f3d011682016040523d82523d5f602084013e6120e2565b606091505b50915091508180156120f5575080516020145b61210057601261098b565b8080602001905181019061098b9190613a97565b6053546068805463ffffffff909216600160c81b027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117908190556001600160a01b0365010000000000909104166333d6247d61217561088e565b6040518263ffffffff1660e01b815260040161219391815260200190565b5f604051808303815f87803b1580156121aa575f80fd5b505af11580156121bc573d5f803e3d5ffd5b50505050565b606854604080516020808201879052818301869052825180830384018152606083019384905280519101207f257b36320000000000000000000000000000000000000000000000000000000090925260648101919091525f916501000000000090046001600160a01b03169063257b3632906084016020604051808303815f875af1158015612253573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122779190613860565b9050805f036122b1576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80680100000000000000008716156122f5578691506122d3848a8489611d40565b6122f0576040516338105f3b60e21b815260040160405180910390fd5b61233f565b602087901c612305816001613ab2565b9150879250612320612318868c866109d3565b8a8389611d40565b61233d576040516338105f3b60e21b815260040160405180910390fd5b505b6123498282612c64565b505050505050505050565b6040516001600160a01b0383166024820152604481018290526123d09084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612d24565b505050565b5f8060405180611ba00160405280611b668152602001613d80611b6691398360405160200161240592919061377e565b6040516020818303038152906040529050838151602083015ff591506001600160a01b038216612461576040517fbefb092000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5092915050565b6002600154036124ba5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611aca565b6002600155565b5f6124cf6004828486613acf565b6124d891613af6565b90507f2afa5331000000000000000000000000000000000000000000000000000000006001600160e01b03198216016126b2575f80808080808061251f896004818d613acf565b81019061252c9190613b26565b9650965096509650965096509650336001600160a01b0316876001600160a01b03161461256c5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03861630146125955760405163750643af60e01b815260040160405180910390fd5b8a85146125ce576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b03167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e169161266591906137e5565b5f604051808303815f865af19150503d805f811461269e576040519150601f19603f3d011682016040523d82523d5f602084013e6126a3565b606091505b50505050505050505050610752565b6001600160e01b031981166323f2ebc360e21b146126fc576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808080808080806127118a6004818e613acf565b81019061271e9190613b75565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146127605760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146127895760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f169161281091906137e5565b5f604051808303815f865af19150503d805f8114612849576040519150601f19603f3d011682016040523d82523d5f602084013e61284e565b606091505b50505050505050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526121bc9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612399565b8060016128c060206002613cd3565b6128ca9190613877565b60535410612904576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60535f81546129139061372e565b918290555090505f5b60208110156129a3578082901c60011660010361294f57826033826020811061294757612947613706565b015550505050565b6033816020811061296257612962613706565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061299b9061372e565b91505061291c565b506123d0613cde565b60018055565b60685460ff166129ee576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3905f90a1565b5f54610100900460ff16612a8c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611aca565b610664612e08565b60606040825110612ab357818060200190518101906106ca9190613cf2565b8151602003612c26575f5b602081108015612b055750828181518110612adb57612adb613706565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b15612b1c5780612b148161372e565b915050612abe565b805f03612b5e57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b5f8167ffffffffffffffff811115612b7857612b78613268565b6040519080825280601f01601f191660200182016040528015612ba2576020820181803683370190505b5090505f5b82811015612c1e57848181518110612bc157612bc1613706565b602001015160f81c60f81b828281518110612bde57612bde613706565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535080612c168161372e565b915050612ba7565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b6068545f90610100900463ffffffff16158015612c87575063ffffffff82166001145b15612c99575063ffffffff8216612cc1565b612cae64010000000063ffffffff84166137ac565b612cbe9063ffffffff85166137c3565b90505b600881901c5f8181526069602052604081208054600160ff861690811b91821892839055929091908183169003611723576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f612d78826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e729092919063ffffffff16565b8051909150156123d05780806020019051810190612d969190613d64565b6123d05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611aca565b5f54610100900460ff166129ac5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611aca565b606061098b84845f85855f80866001600160a01b03168587604051612e9791906137e5565b5f6040518083038185875af1925050503d805f8114612ed1576040519150601f19603f3d011682016040523d82523d5f602084013e612ed6565b606091505b5091509150612ee787838387612ef2565b979650505050505050565b60608315612f605782515f03612f59576001600160a01b0385163b612f595760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611aca565b508161098b565b61098b8383815115612f755781518083602001fd5b8060405162461bcd60e51b8152600401611aca9190613102565b803563ffffffff81168114612c5f575f80fd5b6001600160a01b0381168114612fb6575f80fd5b50565b5f8060408385031215612fca575f80fd5b612fd383612f8f565b91506020830135612fe381612fa2565b809150509250929050565b8015158114612fb6575f80fd5b5f8083601f84011261300b575f80fd5b50813567ffffffffffffffff811115613022575f80fd5b602083019150836020828501011115613039575f80fd5b9250929050565b5f805f805f60808688031215613054575f80fd5b61305d86612f8f565b9450602086013561306d81612fa2565b9350604086013561307d81612fee565b9250606086013567ffffffffffffffff811115613098575f80fd5b6130a488828901612ffb565b969995985093965092949392505050565b5f5b838110156130cf5781810151838201526020016130b7565b50505f910152565b5f81518084526130ee8160208601602086016130b5565b601f01601f19169290920160200192915050565b602081525f61311460208301846130d7565b9392505050565b5f6020828403121561312b575f80fd5b813561311481612fa2565b60ff81168114612fb6575f80fd5b5f805f805f805f60e0888a03121561315a575f80fd5b873561316581613136565b965061317360208901612f8f565b9550604088013561318381612fa2565b945061319160608901612f8f565b935060808801356131a181612fa2565b9699959850939692959460a0840135945060c09093013592915050565b5f805f606084860312156131d0575f80fd5b6131d984612f8f565b925060208401356131e981612fa2565b915060408401356131f981612fa2565b809150509250925092565b5f60208284031215613214575f80fd5b5035919050565b8061040081018310156106ca575f80fd5b5f805f610440848603121561323f575f80fd5b83359250613250856020860161321b565b915061325f6104208501612f8f565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156132a5576132a5613268565b604052919050565b5f67ffffffffffffffff8211156132c6576132c6613268565b50601f01601f191660200190565b5f6132e66132e1846132ad565b61327c565b90508281528383830111156132f9575f80fd5b828260208301375f602084830101529392505050565b5f82601f83011261331e575f80fd5b613114838335602085016132d4565b5f805f805f60a08688031215613341575f80fd5b61334a86612f8f565b9450602086013561335a81612fa2565b9350604086013567ffffffffffffffff80821115613376575f80fd5b61338289838a0161330f565b94506060880135915080821115613397575f80fd5b506133a48882890161330f565b92505060808601356133b581613136565b809150509295509295909350565b5f805f805f8060a087890312156133d8575f80fd5b6133e187612f8f565b955060208701356133f181612fa2565b945060408701359350606087013561340881612fee565b9250608087013567ffffffffffffffff811115613423575f80fd5b61342f89828a01612ffb565b979a9699509497509295939492505050565b5f8060408385031215613452575f80fd5b61345b83612f8f565b915061346960208401612f8f565b90509250929050565b5f805f805f805f805f805f806109208d8f03121561348e575f80fd5b6134988e8e61321b565b9b506134a88e6104008f0161321b565b9a506108008d013599506108208d013598506108408d013597506134cf6108608e01612f8f565b96506134df6108808e0135612fa2565b6108808d013595506134f46108a08e01612f8f565b94506135046108c08e0135612fa2565b6108c08d013593506108e08d0135925067ffffffffffffffff6109008e0135111561352d575f80fd5b61353e8e6109008f01358f01612ffb565b81935080925050509295989b509295989b509295989b565b5f805f805f805f60c0888a03121561356c575f80fd5b61357588612f8f565b9650602088013561358581612fa2565b955060408801359450606088013561359c81612fa2565b935060808801356135ac81612fee565b925060a088013567ffffffffffffffff8111156135c7575f80fd5b6135d38a828b01612ffb565b989b979a50959850939692959293505050565b5f805f805f8060c087890312156135fb575f80fd5b61360487612f8f565b9550602087013561361481612fa2565b945061362260408801612f8f565b9350606087013561363281612fa2565b9250608087013561364281612fa2565b915060a087013567ffffffffffffffff81111561365d575f80fd5b8701601f8101891361366d575f80fd5b61367c898235602084016132d4565b9150509295509295509295565b5f805f80610460858703121561369d575f80fd5b843593506136ae866020870161321b565b92506136bd6104208601612f8f565b939692955092936104400135925050565b600181811c908216806136e257607f821691505b60208210810361370057634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161373f5761373f61371a565b5060010190565b606081525f61375860608301866130d7565b828103602084015261376a81866130d7565b91505060ff83166040830152949350505050565b5f835161378f8184602088016130b5565b8351908301906137a38183602088016130b5565b01949350505050565b80820281158282048414176106ca576106ca61371a565b808201808211156106ca576106ca61371a565b818382375f9101908152919050565b5f82516137f68184602087016130b5565b9190910192915050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b63ffffffff861681525f6001600160a01b03808716602084015280861660408401525060806060830152612ee7608083018486613800565b5f60208284031215613870575f80fd5b5051919050565b818103818111156106ca576106ca61371a565b5f61010060ff8b16835263ffffffff808b1660208501526001600160a01b03808b166040860152818a1660608601528089166080860152508660a08501528160c08501526138da828501876130d7565b925080851660e085015250509998505050505050505050565b6001600160a01b038516815263ffffffff84166020820152606060408201525f613921606083018486613800565b9695505050505050565b601f8211156123d0575f81815260208120601f850160051c810160208610156139515750805b601f850160051c820191505b81811015610cba5782815560010161395d565b815167ffffffffffffffff81111561398a5761398a613268565b61399e8161399884546136ce565b8461392b565b602080601f8311600181146139d1575f84156139ba5750858301515b5f19600386901b1c1916600185901b178555610cba565b5f85815260208120601f198616915b828110156139ff578886015182559484019460019091019084016139e0565b5085821015613a1c57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f61010060ff8c16835263ffffffff808c1660208501526001600160a01b03808c166040860152818b166060860152808a166080860152508760a08501528160c0850152613a7d8285018789613800565b925080851660e085015250509a9950505050505050505050565b5f60208284031215613aa7575f80fd5b815161311481613136565b63ffffffff8181168382160190808211156124615761246161371a565b5f8085851115613add575f80fd5b83861115613ae9575f80fd5b5050820193919092039150565b6001600160e01b03198135818116916004851015613b1e5780818660040360031b1b83161692505b505092915050565b5f805f805f805f60e0888a031215613b3c575f80fd5b8735613b4781612fa2565b96506020880135613b5781612fa2565b9550604088013594506060880135935060808801356131a181613136565b5f805f805f805f80610100898b031215613b8d575f80fd5b8835613b9881612fa2565b97506020890135613ba881612fa2565b965060408901359550606089013594506080890135613bc681612fee565b935060a0890135613bd681613136565b979a969950949793969295929450505060c08201359160e0013590565b600181815b80851115613c2d57815f1904821115613c1357613c1361371a565b80851615613c2057918102915b93841c9390800290613bf8565b509250929050565b5f82613c43575060016106ca565b81613c4f57505f6106ca565b8160018114613c655760028114613c6f57613c8b565b60019150506106ca565b60ff841115613c8057613c8061371a565b50506001821b6106ca565b5060208310610133831016604e8410600b8410161715613cae575081810a6106ca565b613cb88383613bf3565b805f1904821115613ccb57613ccb61371a565b029392505050565b5f6131148383613c35565b634e487b7160e01b5f52600160045260245ffd5b5f60208284031215613d02575f80fd5b815167ffffffffffffffff811115613d18575f80fd5b8201601f81018413613d28575f80fd5b8051613d366132e1826132ad565b818152856020838501011115613d4a575f80fd5b613d5b8260208301602086016130b5565b95945050505050565b5f60208284031215613d74575f80fd5b815161311481612fee56fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220432f6d6b4446edbe1f73c19fd2115454d5c35d8b03b98a74fd46724151d7672264736f6c63430008140033" + }, + { + "contractName": "PolygonZkEVMBridge proxy", + "balance": "340282366920938463463374607431768211455", + "nonce": "1", + "address": "0xFe12ABaa190Ef0c8638Ee0ba9F828BF41368Ca0E", + "bytecode": "0x60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f80fd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f80fd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f80fd5b5061006a6100fd366004610854565b610228565b34801561010d575f80fd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f80375f80365f845af43d5f803e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610977602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f808573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090b565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610926565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f80fd5b919050565b5f60208284031215610864575f80fd5b6104e28261082c565b5f805f6040848603121561087f575f80fd5b6108888461082c565b9250602084013567ffffffffffffffff808211156108a4575f80fd5b818601915086601f8301126108b7575f80fd5b8135818111156108c5575f80fd5b8760208285010111156108d6575f80fd5b6020830194508093505050509250925092565b5f5b838110156109035781810151838201526020016108eb565b50505f910152565b5f825161091c8184602087016108e9565b9190910192915050565b602081525f82518060208401526109448160408501602087016108e9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212202ac98acbfbb3d3ac1b74050e18c4e76db25a3ff2801ec69bf85d0c61414d502b64736f6c63430008140033", + "storage": { + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000fadb60b5059e31614e02083ff6c021a24c31c891", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000608484d3e94fc775e3dcb06b0b48486c60a315e6" + } + }, + { + "contractName": "PolygonZkEVMGlobalExitRootL2 implementation", + "balance": "0", + "nonce": "1", + "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "bytecode": "0x608060405234801561000f575f80fd5b506004361061004a575f3560e01c806301fd90441461004e578063257b36321461006a57806333d6247d14610089578063a3c573eb1461009e575b5f80fd5b61005760015481565b6040519081526020015b60405180910390f35b61005761007836600461015e565b5f6020819052908152604090205481565b61009c61009736600461015e565b6100ea565b005b6100c57f000000000000000000000000fe12abaa190ef0c8638ee0ba9f828bf41368ca0e81565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610061565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000fe12abaa190ef0c8638ee0ba9f828bf41368ca0e1614610159576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b5f6020828403121561016e575f80fd5b503591905056fea26469706673582212205108c6c4f924146b736832a1bdf696e20d900450207b7452462368d150f2c71c64736f6c63430008140033" + }, + { + "contractName": "PolygonZkEVMGlobalExitRootL2 proxy", + "balance": "0", + "nonce": "1", + "address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa", + "bytecode": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033", + "storage": { + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000fadb60b5059e31614e02083ff6c021a24c31c891", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c9" + } + }, + { + "contractName": "PolygonZkEVMTimelock", + "balance": "0", + "nonce": "1", + "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F", + "bytecode": "0x6080604052600436106101bd575f3560e01c806364d62353116100f2578063b1c5f42711610092578063d547741f11610062578063d547741f1461063a578063e38335e514610659578063f23a6e611461066c578063f27a0c92146106b0575f80fd5b8063b1c5f4271461058d578063bc197c81146105ac578063c4d252f5146105f0578063d45c44351461060f575f80fd5b80638f61f4f5116100cd5780638f61f4f5146104c557806391d14854146104f8578063a217fddf14610547578063b08e51c01461055a575f80fd5b806364d62353146104685780638065657f146104875780638f2a0bb0146104a6575f80fd5b8063248a9ca31161015d57806331d507501161013857806331d50750146103b357806336568abe146103d25780633a6aae72146103f1578063584b153e14610449575f80fd5b8063248a9ca3146103375780632ab0f529146103655780632f2ff15d14610394575f80fd5b80630d3cf6fc116101985780630d3cf6fc1461025e578063134008d31461029157806313bc9f20146102a4578063150b7a02146102c3575f80fd5b806301d5062a146101c857806301ffc9a7146101e957806307bd02651461021d575f80fd5b366101c457005b5f80fd5b3480156101d3575f80fd5b506101e76101e2366004611bf6565b6106c4565b005b3480156101f4575f80fd5b50610208610203366004611c65565b610757565b60405190151581526020015b60405180910390f35b348015610228575f80fd5b506102507fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610214565b348015610269575f80fd5b506102507f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101e761029f366004611ca4565b6107b2565b3480156102af575f80fd5b506102086102be366004611d0b565b6108a7565b3480156102ce575f80fd5b506103066102dd366004611e28565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610214565b348015610342575f80fd5b50610250610351366004611d0b565b5f9081526020819052604090206001015490565b348015610370575f80fd5b5061020861037f366004611d0b565b5f908152600160208190526040909120541490565b34801561039f575f80fd5b506101e76103ae366004611e8c565b6108cc565b3480156103be575f80fd5b506102086103cd366004611d0b565b6108f5565b3480156103dd575f80fd5b506101e76103ec366004611e8c565b61090d565b3480156103fc575f80fd5b506104247f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b348015610454575f80fd5b50610208610463366004611d0b565b6109c5565b348015610473575f80fd5b506101e7610482366004611d0b565b6109da565b348015610492575f80fd5b506102506104a1366004611ca4565b610aaa565b3480156104b1575f80fd5b506101e76104c0366004611ef7565b610ae8565b3480156104d0575f80fd5b506102507fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b348015610503575f80fd5b50610208610512366004611e8c565b5f9182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610552575f80fd5b506102505f81565b348015610565575f80fd5b506102507ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b348015610598575f80fd5b506102506105a7366004611fa0565b610d18565b3480156105b7575f80fd5b506103066105c63660046120be565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b3480156105fb575f80fd5b506101e761060a366004611d0b565b610d5c565b34801561061a575f80fd5b50610250610629366004611d0b565b5f9081526001602052604090205490565b348015610645575f80fd5b506101e7610654366004611e8c565b610e56565b6101e7610667366004611fa0565b610e7a565b348015610677575f80fd5b50610306610686366004612161565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106bb575f80fd5b50610250611121565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc16106ee81611200565b5f6106fd898989898989610aaa565b9050610709818461120d565b5f817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a60405161074496959493929190612208565b60405180910390a3505050505050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107ac57506107ac82611359565b92915050565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661082e5761082e81336113ef565b5f61083d888888888888610aaa565b905061084981856114a6565b610855888888886115e2565b5f817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a60405161088c9493929190612252565b60405180910390a361089d816116e2565b5050505050505050565b5f818152600160205260408120546001811180156108c55750428111155b9392505050565b5f828152602081905260409020600101546108e681611200565b6108f0838361178a565b505050565b5f8181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109c18282611878565b5050565b5f818152600160208190526040822054610906565b333014610a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109ae565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b5f868686868686604051602001610ac696959493929190612208565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b1281611200565b888714610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b888514610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f610c418b8b8b8b8b8b8b8b610d18565b9050610c4d818461120d565b5f5b8a811015610d0a5780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610c8c57610c8c612291565b9050602002016020810190610ca191906122be565b8d8d86818110610cb357610cb3612291565b905060200201358c8c87818110610ccc57610ccc612291565b9050602002810190610cde91906122d7565b8c8b604051610cf296959493929190612208565b60405180910390a3610d0381612365565b9050610c4f565b505050505050505050505050565b5f8888888888888888604051602001610d38989796959493929190612447565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610d8681611200565b610d8f826109c5565b610e1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109ae565b5f828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b5f82815260208190526040902060010154610e7081611200565b6108f08383611878565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610ef657610ef681336113ef565b878614610f85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b878414611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f6110258a8a8a8a8a8a8a8a610d18565b905061103181856114a6565b5f5b8981101561110b575f8b8b8381811061104e5761104e612291565b905060200201602081019061106391906122be565b90505f8a8a8481811061107857611078612291565b905060200201359050365f8a8a8681811061109557611095612291565b90506020028101906110a791906122d7565b915091506110b7848484846115e2565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58868686866040516110ee9493929190612252565b60405180910390a3505050508061110490612365565b9050611033565b50611115816116e2565b50505050505050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16158015906111ef57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ef919061250c565b156111f957505f90565b5060025490565b61120a81336113ef565b50565b611216826108f5565b156112a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109ae565b6112ab611121565b81101561133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109ae565b611344814261252b565b5f928352600160205260409092209190915550565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107ac57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107ac565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c15761142c8161192d565b61143783602061194c565b604051602001611448929190612560565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109ae916004016125e0565b6114af826108a7565b61153b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b80158061155657505f81815260016020819052604090912054145b6109c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f8473ffffffffffffffffffffffffffffffffffffffff1684848460405161160b929190612630565b5f6040518083038185875af1925050503d805f8114611645576040519150601f19603f3d011682016040523d82523d5f602084013e61164a565b606091505b50509050806116db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109ae565b5050505050565b6116eb816108a7565b611777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b5f90815260016020819052604090912055565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561181a3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107ac73ffffffffffffffffffffffffffffffffffffffff831660145b60605f61195a83600261263f565b61196590600261252b565b67ffffffffffffffff81111561197d5761197d611d22565b6040519080825280601f01601f1916602001820160405280156119a7576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106119dd576119dd612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a3f57611a3f612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f611a7984600261263f565b611a8490600161252b565b90505b6001811115611b20577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611ac557611ac5612291565b1a60f81b828281518110611adb57611adb612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c93611b1981612656565b9050611a87565b5083156108c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109ae565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bac575f80fd5b919050565b5f8083601f840112611bc1575f80fd5b50813567ffffffffffffffff811115611bd8575f80fd5b602083019150836020828501011115611bef575f80fd5b9250929050565b5f805f805f805f60c0888a031215611c0c575f80fd5b611c1588611b89565b965060208801359550604088013567ffffffffffffffff811115611c37575f80fd5b611c438a828b01611bb1565b989b979a50986060810135976080820135975060a09091013595509350505050565b5f60208284031215611c75575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108c5575f80fd5b5f805f805f8060a08789031215611cb9575f80fd5b611cc287611b89565b955060208701359450604087013567ffffffffffffffff811115611ce4575f80fd5b611cf089828a01611bb1565b979a9699509760608101359660809091013595509350505050565b5f60208284031215611d1b575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d9657611d96611d22565b604052919050565b5f82601f830112611dad575f80fd5b813567ffffffffffffffff811115611dc757611dc7611d22565b611df860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d4f565b818152846020838601011115611e0c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611e3b575f80fd5b611e4485611b89565b9350611e5260208601611b89565b925060408501359150606085013567ffffffffffffffff811115611e74575f80fd5b611e8087828801611d9e565b91505092959194509250565b5f8060408385031215611e9d575f80fd5b82359150611ead60208401611b89565b90509250929050565b5f8083601f840112611ec6575f80fd5b50813567ffffffffffffffff811115611edd575f80fd5b6020830191508360208260051b8501011115611bef575f80fd5b5f805f805f805f805f60c08a8c031215611f0f575f80fd5b893567ffffffffffffffff80821115611f26575f80fd5b611f328d838e01611eb6565b909b50995060208c0135915080821115611f4a575f80fd5b611f568d838e01611eb6565b909950975060408c0135915080821115611f6e575f80fd5b50611f7b8c828d01611eb6565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b5f805f805f805f8060a0898b031215611fb7575f80fd5b883567ffffffffffffffff80821115611fce575f80fd5b611fda8c838d01611eb6565b909a50985060208b0135915080821115611ff2575f80fd5b611ffe8c838d01611eb6565b909850965060408b0135915080821115612016575f80fd5b506120238b828c01611eb6565b999c989b509699959896976060870135966080013595509350505050565b5f82601f830112612050575f80fd5b8135602067ffffffffffffffff82111561206c5761206c611d22565b8160051b61207b828201611d4f565b9283528481018201928281019087851115612094575f80fd5b83870192505b848310156120b35782358252918301919083019061209a565b979650505050505050565b5f805f805f60a086880312156120d2575f80fd5b6120db86611b89565b94506120e960208701611b89565b9350604086013567ffffffffffffffff80821115612105575f80fd5b61211189838a01612041565b94506060880135915080821115612126575f80fd5b61213289838a01612041565b93506080880135915080821115612147575f80fd5b5061215488828901611d9e565b9150509295509295909350565b5f805f805f60a08688031215612175575f80fd5b61217e86611b89565b945061218c60208701611b89565b93506040860135925060608601359150608086013567ffffffffffffffff8111156121b5575f80fd5b61215488828901611d9e565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201525f61223d60a0830186886121c1565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201525f6122876060830184866121c1565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082840312156122ce575f80fd5b6108c582611b89565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261230a575f80fd5b83018035915067ffffffffffffffff821115612324575f80fd5b602001915036819003821315611bef575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361239557612395612338565b5060010190565b8183525f6020808501808196508560051b81019150845f5b8781101561243a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126123f2575f80fd5b8701858101903567ffffffffffffffff81111561240d575f80fd5b80360382131561241b575f80fd5b6124268682846121c1565b9a87019a95505050908401906001016123b4565b5091979650505050505050565b60a080825281018890525f8960c08301825b8b8110156124945773ffffffffffffffffffffffffffffffffffffffff61247f84611b89565b16825260209283019290910190600101612459565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8911156124cc575f80fd5b8860051b9150818a602083013701828103602090810160408501526124f4908201878961239c565b60608401959095525050608001529695505050505050565b5f6020828403121561251c575f80fd5b815180151581146108c5575f80fd5b808201808211156107ac576107ac612338565b5f5b83811015612558578181015183820152602001612540565b50505f910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f835161259781601785016020880161253e565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516125d481602884016020880161253e565b01602801949350505050565b602081525f82518060208401526125fe81604085016020870161253e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b818382375f9101908152919050565b80820281158282048414176107ac576107ac612338565b5f8161266457612664612338565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220e28ae7494480ab1c619fd775dc5ff665588c808a910d66178a982c2e7c76a1e664736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000e10", + "0xaedcc9e7897c0d335bdc5d92fe3a8b4f23727fe558cd1c19f332b28716a30559": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xf5e61edb9c9cc6bfbae4463e9a2b1dd6ac3b44ddef38f18016e56ba0363910d9": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x60b9d94c75b7b3f721925089391e4644cd890cb5e6466f9596dfbd2c54e0b280": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x4b63b79f1e338a49559dcd3193ac9eecc50d0f275d24e97cc8c319e5a31a8bd0": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x800d5dfe4bba53eedee06cd4546a27da8de00f12db83f56062976d4493fda899": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5" + } + }, + { + "accountName": "keyless Deployer", + "balance": "0", + "nonce": "1", + "address": "0x694AB5383a002a4796f95530c14Cf0C25ec3EA03" + }, + { + "accountName": "deployer", + "balance": "100000000000000000000000", + "nonce": "8", + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + } + ] \ No newline at end of file diff --git a/go.mod b/go.mod index 1fdf96f..25f5447 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,9 @@ require ( github.com/ethereum/go-ethereum v1.13.14 github.com/mitchellh/mapstructure v1.5.0 github.com/spf13/viper v1.18.2 + github.com/stretchr/testify v1.8.4 github.com/urfave/cli/v2 v2.27.1 + golang.org/x/crypto v0.17.0 ) require ( @@ -18,6 +20,7 @@ require ( github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect @@ -30,6 +33,7 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -45,7 +49,6 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sync v0.5.0 // indirect diff --git a/networks/mainnet/mainnet/rollupManager.json b/networks/mainnet/mainnet/rollupManager.json index 02b73ec..25b0b3a 100644 --- a/networks/mainnet/mainnet/rollupManager.json +++ b/networks/mainnet/mainnet/rollupManager.json @@ -1,5 +1,4 @@ { - "Client": {}, "Address": "0x5132a183e9f3cb7c848b0aac5ae0c4f0491b7ab2", "BridgeAddress": "0x2a3dd3eb832af982ec71669e178424b10dca2ede", "GERAddr": "0x580bda1e7a0cfae92fa7f6c20a3794f169ce3cfb", diff --git a/networks/mainnet/mainnet/rollups/Astar zkEVM.json b/networks/mainnet/mainnet/rollups/Astar zkEVM.json index 37ae338..a87f23c 100644 --- a/networks/mainnet/mainnet/rollups/Astar zkEVM.json +++ b/networks/mainnet/mainnet/rollups/Astar zkEVM.json @@ -2,5 +2,8 @@ "Address": "0x1e163594e13030244dcaf4cdfc2cd0ba3206da80", "GenesisRoot": "0xe3a7d8bae497945ba8ddc51c69564f60ad4c1a990b9c7bdbd27f7929bfa8f272", "CreationBlock": 19285389, - "ChainID": 3776 + "ChainID": 3776, + "Name": "Astar zkEVM", + "RollupID": 2, + "GasToken": "0x0000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/networks/mainnet/mainnet/rollups/polygon zkEVM.json b/networks/mainnet/mainnet/rollups/polygon zkEVM.json index 2d7620f..ddd14fc 100644 --- a/networks/mainnet/mainnet/rollups/polygon zkEVM.json +++ b/networks/mainnet/mainnet/rollups/polygon zkEVM.json @@ -2,5 +2,8 @@ "Address": "0x519e42c24163192dca44cd3fbdcebf6be9130987", "GenesisRoot": "0x3f86b09b43e3e49a41fc20a07579b79eba044253367817d5c241d23c0e2bc5c9", "CreationBlock": 16896721, - "ChainID": 1101 + "ChainID": 1101, + "Name": "polygon zkEVM", + "RollupID": 1, + "GasToken": "0x0000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/networks/sepolia/bali/rollupManager.json b/networks/sepolia/bali/rollupManager.json index 011e0e9..e702c7e 100644 --- a/networks/sepolia/bali/rollupManager.json +++ b/networks/sepolia/bali/rollupManager.json @@ -1,5 +1,4 @@ { - "Client": {}, "Address": "0xe2ef6215adc132df6913c8dd16487abf118d1764", "BridgeAddress": "0x1348947e282138d8f377b467f7d9c2eb0f335d1f", "GERAddr": "0x2968d6d736178f8fe7393cc33c87f29d9c287e78", diff --git a/networks/sepolia/cardona/rollupManager.json b/networks/sepolia/cardona/rollupManager.json index e124704..4166ce1 100644 --- a/networks/sepolia/cardona/rollupManager.json +++ b/networks/sepolia/cardona/rollupManager.json @@ -1,5 +1,4 @@ { - "Client": {}, "Address": "0x32d33d5137a7cffb54c5bf8371172bcec5f310ff", "BridgeAddress": "0x528e26b25a34a4a5d0dbda1d57d318153d2ed582", "GERAddr": "0xad1490c248c5d3cbae399fd529b79b42984277df", diff --git a/rollup/consensus.go b/rollup/consensus.go new file mode 100644 index 0000000..1b9eefe --- /dev/null +++ b/rollup/consensus.go @@ -0,0 +1,116 @@ +package rollup + +import ( + "fmt" + + validiumelderberry "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/polygonvalidiumetrog" + rollupelderberry "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/polygonzkevmetrog" + validiumetrog "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonvalidiumetrog" + rollupetrog "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmetrog" + "github.com/0xPolygon/cdk-contracts-tooling/rollupmanager" + "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/ethclient" +) + +const ( + Etrog = "etrog" + Elderberry = "elderberry" + RollupConsensus = "rollup" + ValidiumConsensus = "validium" +) + +type Consensus struct { + Deploy func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) + GenerateInitializeTransaction func(opts *bind.CallOpts, networkID uint32, _gasTokenAddress common.Address, _gasTokenNetwork uint32, _gasTokenMetadata []byte) ([]byte, error) +} + +func GetConsensus( + version, consensusType string, + client *ethclient.Client, auth *bind.TransactOpts, + rm *rollupmanager.RollupManager, + consensusAddress *common.Address, +) (*Consensus, error) { + var consensus Consensus + switch version { + case Etrog: + switch consensusType { + case RollupConsensus: + consensus.Deploy = func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) { + _, tx, _, err := rollupetrog.DeployPolygonzkevmetrog( + auth, client, rm.GERAddr, rm.POLAddr, rm.BridgeAddress, rm.Address, + ) + return tx, err + } + if consensusAddress != nil { + c, err := rollupetrog.NewPolygonzkevmetrog(*consensusAddress, client) + if err != nil { + return nil, err + } + consensus.GenerateInitializeTransaction = c.GenerateInitializeTransaction + } + case ValidiumConsensus: + consensus.Deploy = func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) { + _, tx, _, err := validiumetrog.DeployPolygonvalidiumetrog( + auth, client, rm.GERAddr, rm.POLAddr, rm.BridgeAddress, rm.Address, + ) + return tx, err + } + if consensusAddress != nil { + c, err := validiumetrog.NewPolygonvalidiumetrog(*consensusAddress, client) + if err != nil { + return nil, err + } + consensus.GenerateInitializeTransaction = c.GenerateInitializeTransaction + } + default: + return nil, fmt.Errorf( + "unsupported consensus type %s. Supported values are [%s, %s]", + consensusType, RollupConsensus, ValidiumConsensus, + ) + } + case Elderberry: + switch consensusType { + case RollupConsensus: + consensus.Deploy = func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) { + _, tx, _, err := rollupelderberry.DeployPolygonzkevmetrog( + auth, client, rm.GERAddr, rm.POLAddr, rm.BridgeAddress, rm.Address, + ) + return tx, err + } + if consensusAddress != nil { + c, err := rollupelderberry.NewPolygonzkevmetrog(*consensusAddress, client) + if err != nil { + return nil, err + } + consensus.GenerateInitializeTransaction = c.GenerateInitializeTransaction + } + case ValidiumConsensus: + consensus.Deploy = func(auth *bind.TransactOpts, backend bind.ContractBackend) (*types.Transaction, error) { + _, tx, _, err := validiumelderberry.DeployPolygonvalidiumetrog( + auth, client, rm.GERAddr, rm.POLAddr, rm.BridgeAddress, rm.Address, + ) + return tx, err + } + if consensusAddress != nil { + c, err := validiumelderberry.NewPolygonvalidiumetrog(*consensusAddress, client) + if err != nil { + return nil, err + } + consensus.GenerateInitializeTransaction = c.GenerateInitializeTransaction + } + default: + return nil, fmt.Errorf( + "unsupported consensus type %s. Supported values are [%s, %s]", + consensusType, RollupConsensus, ValidiumConsensus, + ) + } + default: + return nil, fmt.Errorf( + "unsupported version %s. SUpported versions [%s, %s]", + version, Etrog, Elderberry, + ) + } + return &consensus, nil +} diff --git a/rollup/rollup.go b/rollup/rollup.go index 58591b0..ef5d0f9 100644 --- a/rollup/rollup.go +++ b/rollup/rollup.go @@ -5,9 +5,12 @@ import ( "encoding/json" "os" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/polygonvalidiumetrog" "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevm" "github.com/0xPolygon/cdk-contracts-tooling/rollupmanager" + "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/ethclient" ) @@ -20,9 +23,10 @@ type Rollup struct { Name string RollupID uint32 GasToken common.Address + client *ethclient.Client } -func LoadFromL1ByChainID(client *ethclient.Client, rm *rollupmanager.RollupManager, chainID uint64) (*Rollup, error) { +func LoadFromL1ByChainID(ctx context.Context, client *ethclient.Client, rm *rollupmanager.RollupManager, chainID uint64) (*Rollup, error) { rID, err := rm.Contract.ChainIDToRollupID(nil, chainID) if err != nil { return nil, err @@ -31,7 +35,7 @@ func LoadFromL1ByChainID(client *ethclient.Client, rm *rollupmanager.RollupManag if err != nil { return nil, err } - info, err := rm.GetRollupCreationInfo(context.TODO(), rID) + info, err := rm.GetRollupCreationInfo(ctx, rID) if err != nil { return nil, err } @@ -53,6 +57,7 @@ func LoadFromL1ByChainID(client *ethclient.Client, rm *rollupmanager.RollupManag Name: name, RollupID: info.RollupID, GasToken: info.GasToken, + client: client, }, nil } @@ -72,6 +77,17 @@ func LoadFromFile(client *ethclient.Client, filePath string) (*Rollup, error) { return nil, err } r.Contract = contract + r.client = client } return &r, nil } + +func (r *Rollup) SetDataAvailabilityProtocol( + auth *bind.TransactOpts, dap common.Address, +) (*types.Transaction, error) { + v, err := polygonvalidiumetrog.NewPolygonvalidiumetrog(r.Address, r.client) + if err != nil { + return nil, err + } + return v.SetDataAvailabilityProtocol(auth, dap) +} diff --git a/rollupmanager/rollupmanager.go b/rollupmanager/rollupmanager.go index a7d1cb8..8dcab94 100644 --- a/rollupmanager/rollupmanager.go +++ b/rollupmanager/rollupmanager.go @@ -3,10 +3,11 @@ package rollupmanager import ( "context" "encoding/json" + "errors" "fmt" - "math/big" "os" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry/polygonrollupmanagernotupgraded" "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonrollupmanager" "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevm" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -14,8 +15,13 @@ import ( "github.com/ethereum/go-ethereum/ethclient" ) +var ( + ADD_ROLLUP_TYPE_ROLE = common.HexToHash("0xac75d24dbb35ea80e25fab167da4dea46c1915260426570db84f184891f5f590") + CREATE_ROLLUP_ROLE = common.HexToHash("0xa0fab074aba36a6fa69f1a83ee86e5abfb8433966eb57efb13dc2fc2f24ddd08") +) + type RollupManager struct { - Client *ethclient.Client + Client *ethclient.Client `json:"-"` Contract *polygonrollupmanager.Polygonrollupmanager `json:"-"` Address common.Address BridgeAddress common.Address @@ -25,7 +31,7 @@ type RollupManager struct { UpdateToULxLyBlock uint64 } -func LoadFromL1(client *ethclient.Client, address common.Address) (*RollupManager, error) { +func LoadFromL1(ctx context.Context, client *ethclient.Client, address common.Address) (*RollupManager, error) { contract, err := polygonrollupmanager.NewPolygonrollupmanager(address, client) if err != nil { return nil, err @@ -54,19 +60,26 @@ func LoadFromL1(client *ethclient.Client, address common.Address) (*RollupManage } rm.POLAddr = polAddr - ub, err := rm.GetUpgradeBlocks(context.TODO()) + ub, err := rm.GetUpgradeBlocks(ctx) if err != nil { return nil, err } - if block, ok := ub[1]; ok { - rm.CreationBlock = block - } else { - return nil, fmt.Errorf("creation block not found") - } - if block, ok := ub[2]; ok { - rm.UpdateToULxLyBlock = block + var creationBlock, upgradeBlock uint64 + var creationBlockFound, upgradeBlockFound bool + creationBlock, creationBlockFound = ub[1] + upgradeBlock, upgradeBlockFound = ub[1] + if creationBlockFound && upgradeBlockFound { + // Rollup Manager used to be a isolated LxLy and upgraded to uLxLy + rm.CreationBlock = creationBlock + rm.UpdateToULxLyBlock = upgradeBlock } else { - return nil, fmt.Errorf("upgrade to uLxLy block not found") + // Rollup Manager deployed directly on uLxLy mode + initBlock, err := rm.GetInitializedBlock(ctx) + if err != nil { + return nil, err + } + rm.CreationBlock = initBlock + rm.UpdateToULxLyBlock = initBlock } return &rm, nil } @@ -107,6 +120,25 @@ func (rm *RollupManager) GetUpgradeBlocks(ctx context.Context) (map[uint8]uint64 return res, nil } +// GetInitializedBlock returns the block in which the contract was initialized +func (rm *RollupManager) GetInitializedBlock(ctx context.Context) (uint64, error) { + notUpgraded, err := polygonrollupmanagernotupgraded.NewPolygonrollupmanagernotupgraded(rm.Address, rm.Client) + if err != nil { + return 0, err + } + it, err := notUpgraded.FilterInitialized(&bind.FilterOpts{ + Start: 1, + Context: ctx, + }) + if err != nil { + return 0, err + } + for it.Next() { + return it.Event.Raw.BlockNumber, nil + } + return 0, errors.New("initialized event not found") +} + type CreateRollupInfo struct { Root common.Hash Block uint64 @@ -117,34 +149,42 @@ type CreateRollupInfo struct { // GetRollupCreation returns genesis root and the block number in which the rollup was created func (rm *RollupManager) GetRollupCreationInfo(ctx context.Context, rollupID uint32) (CreateRollupInfo, error) { - if rollupID == 1 { - rollup, err := polygonzkevm.NewPolygonzkevm(rm.Address, rm.Client) - if err != nil { - return CreateRollupInfo{}, err - } - root, err := rollup.BatchNumToStateRoot( - &bind.CallOpts{BlockNumber: big.NewInt(int64(rm.UpdateToULxLyBlock - 1))}, - 0, - ) - if err != nil { - fmt.Println("couldn't find genesis for batch 0 of the rollup 1") - return CreateRollupInfo{}, err - } - chainID, err := rollup.ChainID( - &bind.CallOpts{BlockNumber: big.NewInt(int64(rm.UpdateToULxLyBlock - 1))}, - ) - if err != nil { - return CreateRollupInfo{}, err - } + // // WARNING: leaving this commented as it breaks my test. + // // Comenting this code will make it work when rollup 1 was attached in already uLxLy + // // But will break wen rollup 1 was created before uLxLt + // if rollupID == 1 { + // // TODO: this assumes that the first rollup is always created in unified bridge mode + // // but this is not the case! + // rollup, err := polygonzkevm.NewPolygonzkevm(rm.Address, rm.Client) + // if err != nil { + // return CreateRollupInfo{}, err + // } + // root, err := rollup.BatchNumToStateRoot( + // &bind.CallOpts{BlockNumber: big.NewInt(int64(rm.UpdateToULxLyBlock - 1))}, + // 0, + // ) + // if err != nil { + // if strings.Contains(err.Error(), "missing trie node") { + // fmt.Println("your L1 node does not support this query. Probably need an archival node") + // } + // fmt.Println("couldn't find genesis for batch 0 of the rollup 1") + // return CreateRollupInfo{}, err + // } + // chainID, err := rollup.ChainID( + // &bind.CallOpts{BlockNumber: big.NewInt(int64(rm.UpdateToULxLyBlock - 1))}, + // ) + // if err != nil { + // return CreateRollupInfo{}, err + // } - return CreateRollupInfo{ - Root: common.Hash(root), - Block: rm.CreationBlock, - ChainID: chainID, - RollupID: rollupID, - GasToken: common.Address{}, - }, nil - } + // return CreateRollupInfo{ + // Root: common.Hash(root), + // Block: rm.CreationBlock, + // ChainID: chainID, + // RollupID: rollupID, + // GasToken: common.Address{}, + // }, nil + // } it, err := rm.Contract.FilterCreateNewRollup(&bind.FilterOpts{ Start: rm.UpdateToULxLyBlock, Context: ctx, @@ -176,6 +216,11 @@ func (rm *RollupManager) GetAttachedRollups(ctx context.Context) (map[uint64]str if err != nil { return nil, err } + zeroAddr := common.Address{} + if data.RollupContract == zeroAddr { + fmt.Println("rollup manager has no attached rollups") + return res, nil + } rollup, err := polygonzkevm.NewPolygonzkevm(data.RollupContract, rm.Client) if err != nil { return nil, err diff --git a/wallets.example.toml b/wallets.example.toml index e69de29..b6ace00 100644 --- a/wallets.example.toml +++ b/wallets.example.toml @@ -0,0 +1,8 @@ +[Wallets.0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D] +Type = "PlainTextPrivateKey" +PrivateKey = "0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e" + +[Wallets.0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266] +Type = "EncryptedFile" +FilePath = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266.keystore" +# The password is testonly