Commit 12900b75 authored by clabby's avatar clabby Committed by GitHub

feat(ctb): Consolidate `OutputBisectionGame` -> `FaultDisputeGame` (#8787)

* Consolidate `OutputBisectionGame` -> `FaultDisputeGame`

* Deploy fix

* deploy config updates

* challenger/op-e2e: Consolidate `OutputBisectionGame` -> `FaultDisputeGame`

* lint

* e2e helper refactor

* Remove `AlphabetTrace` config option

* Rename contract binding

* Update packages/contracts-bedrock/scripts/Deploy.s.sol
Co-authored-by: default avatarrefcell.eth <abigger87@gmail.com>

* @refcell comment nit
Co-Authored-By: default avatarrefcell <abigger87@gmail.com>

* fmt

* @refcell nit

* Revert @ajsutton's alphabet config change

---------
Co-authored-by: default avatarrefcell.eth <abigger87@gmail.com>
parent b01f7802
...@@ -29,14 +29,11 @@ ...@@ -29,14 +29,11 @@
"L1BlockNumber", "L1BlockNumber",
"DisputeGameFactory", "DisputeGameFactory",
"FaultDisputeGame", "FaultDisputeGame",
"OutputBisectionGame",
"AlphabetVM", "AlphabetVM",
"AlphabetVM2",
"StandardBridge", "StandardBridge",
"CrossDomainMessenger", "CrossDomainMessenger",
"MIPS", "MIPS",
"PreimageOracle", "PreimageOracle",
"BlockOracle",
"EAS", "EAS",
"SchemaRegistry", "SchemaRegistry",
"ProtocolVersions", "ProtocolVersions",
......
...@@ -30,8 +30,8 @@ var ( ...@@ -30,8 +30,8 @@ var (
// AlphabetVMMetaData contains all meta data concerning the AlphabetVM contract. // AlphabetVMMetaData contains all meta data concerning the AlphabetVM contract.
var AlphabetVMMetaData = &bind.MetaData{ var AlphabetVMMetaData = &bind.MetaData{
ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"oracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPreimageOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"postState_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"}]", ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"oracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPreimageOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_localContext\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"postState_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"}]",
Bin: "0x60a060405234801561001057600080fd5b50604051610a7d380380610a7d83398101604081905261002f91610090565b608081905260405161004090610083565b604051809103906000f08015801561005c573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b0392909216919091179055506100a9565b61065c8061042183390190565b6000602082840312156100a257600080fd5b5051919050565b60805161035e6100c3600039600060af015261035e6000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610213565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610287565b6040518091039020901b03610108576000915061010187890189610297565b9050610127565b610114878901896102b0565b90925090508161012381610301565b9250505b81610133826001610339565b604080516020810193909352820152606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b60008083601f8401126101dc57600080fd5b50813567ffffffffffffffff8111156101f457600080fd5b60208301915083602082850101111561020c57600080fd5b9250929050565b60008060008060006060868803121561022b57600080fd5b853567ffffffffffffffff8082111561024357600080fd5b61024f89838a016101ca565b9097509550602088013591508082111561026857600080fd5b50610275888289016101ca565b96999598509660400135949350505050565b8183823760009101908152919050565b6000602082840312156102a957600080fd5b5035919050565b600080604083850312156102c357600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610332576103326102d2565b5060010190565b6000821982111561034c5761034c6102d2565b50019056fea164736f6c634300080f000a608060405234801561001057600080fd5b5061063c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806352f0f3ad1461007757806361238bde1461009d5780638542cf50146100c8575b600080fd5b61008a6100853660046104df565b610163565b6040519081526020015b60405180910390f35b61008a6100ab36600461051a565b600160209081526000928352604080842090915290825290205481565b6100f66100d636600461051a565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610094565b61011961011436600461051a565b610238565b60408051928352602083019190915201610094565b61014161013c36600461053c565b610329565b005b61008a6101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080600080600060a086880312156104f757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806040838503121561052d57600080fd5b50508035926020909101359150565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a", Bin: "0x60a060405234801561001057600080fd5b50604051610c23380380610c2383398101604081905261002f91610090565b608081905260405161004090610083565b604051809103906000f08015801561005c573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b0392909216919091179055506100a9565b61065c806105c783390190565b6000602082840312156100a257600080fd5b5051919050565b6080516105046100c3600039600060af01526105046000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610395565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610409565b6040518091039020901b036101d9576000805473ffffffffffffffffffffffffffffffffffffffff1663e03110e161011b60048861029f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152600060248201526044016040805180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610419565b50640ffffffff0607c82901c169350905063ffffffff608082901c1660006101c38a8c018c61043d565b90506101cf8582610485565b9350505050610206565b6101e58789018961049d565b9092509050816101f4816104bf565b9250508080610202906104bf565b9150505b6040805160208101849052908101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617610345818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b60008083601f84011261035e57600080fd5b50813567ffffffffffffffff81111561037657600080fd5b60208301915083602082850101111561038e57600080fd5b9250929050565b6000806000806000606086880312156103ad57600080fd5b853567ffffffffffffffff808211156103c557600080fd5b6103d189838a0161034c565b909750955060208801359150808211156103ea57600080fd5b506103f78882890161034c565b96999598509660400135949350505050565b8183823760009101908152919050565b6000806040838503121561042c57600080fd5b505080516020909101519092909150565b60006020828403121561044f57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561049857610498610456565b500190565b600080604083850312156104b057600080fd5b50508035926020909101359150565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036104f0576104f0610456565b506001019056fea164736f6c634300080f000a608060405234801561001057600080fd5b5061063c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806352f0f3ad1461007757806361238bde1461009d5780638542cf50146100c8575b600080fd5b61008a6100853660046104df565b610163565b6040519081526020015b60405180910390f35b61008a6100ab36600461051a565b600160209081526000928352604080842090915290825290205481565b6100f66100d636600461051a565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610094565b61011961011436600461051a565b610238565b60408051928352602083019190915201610094565b61014161013c36600461053c565b610329565b005b61008a6101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080600080600060a086880312156104f757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806040838503121561052d57600080fd5b50508035926020909101359150565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a",
} }
// AlphabetVMABI is the input ABI used to generate the binding from. // AlphabetVMABI is the input ABI used to generate the binding from.
...@@ -234,10 +234,10 @@ func (_AlphabetVM *AlphabetVMCallerSession) Oracle() (common.Address, error) { ...@@ -234,10 +234,10 @@ func (_AlphabetVM *AlphabetVMCallerSession) Oracle() (common.Address, error) {
// Step is a free data retrieval call binding the contract method 0xe14ced32. // Step is a free data retrieval call binding the contract method 0xe14ced32.
// //
// Solidity: function step(bytes _stateData, bytes , bytes32 ) view returns(bytes32 postState_) // Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_)
func (_AlphabetVM *AlphabetVMCaller) Step(opts *bind.CallOpts, _stateData []byte, arg1 []byte, arg2 [32]byte) ([32]byte, error) { func (_AlphabetVM *AlphabetVMCaller) Step(opts *bind.CallOpts, _stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) {
var out []interface{} var out []interface{}
err := _AlphabetVM.contract.Call(opts, &out, "step", _stateData, arg1, arg2) err := _AlphabetVM.contract.Call(opts, &out, "step", _stateData, arg1, _localContext)
if err != nil { if err != nil {
return *new([32]byte), err return *new([32]byte), err
...@@ -251,14 +251,14 @@ func (_AlphabetVM *AlphabetVMCaller) Step(opts *bind.CallOpts, _stateData []byte ...@@ -251,14 +251,14 @@ func (_AlphabetVM *AlphabetVMCaller) Step(opts *bind.CallOpts, _stateData []byte
// Step is a free data retrieval call binding the contract method 0xe14ced32. // Step is a free data retrieval call binding the contract method 0xe14ced32.
// //
// Solidity: function step(bytes _stateData, bytes , bytes32 ) view returns(bytes32 postState_) // Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_)
func (_AlphabetVM *AlphabetVMSession) Step(_stateData []byte, arg1 []byte, arg2 [32]byte) ([32]byte, error) { func (_AlphabetVM *AlphabetVMSession) Step(_stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) {
return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, arg2) return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, _localContext)
} }
// Step is a free data retrieval call binding the contract method 0xe14ced32. // Step is a free data retrieval call binding the contract method 0xe14ced32.
// //
// Solidity: function step(bytes _stateData, bytes , bytes32 ) view returns(bytes32 postState_) // Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_)
func (_AlphabetVM *AlphabetVMCallerSession) Step(_stateData []byte, arg1 []byte, arg2 [32]byte) ([32]byte, error) { func (_AlphabetVM *AlphabetVMCallerSession) Step(_stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) {
return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, arg2) return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, _localContext)
} }
...@@ -13,7 +13,7 @@ const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\": ...@@ -13,7 +13,7 @@ const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":
var AlphabetVMStorageLayout = new(solc.StorageLayout) var AlphabetVMStorageLayout = new(solc.StorageLayout)
var AlphabetVMDeployedBin = "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610213565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610287565b6040518091039020901b03610108576000915061010187890189610297565b9050610127565b610114878901896102b0565b90925090508161012381610301565b9250505b81610133826001610339565b604080516020810193909352820152606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b60008083601f8401126101dc57600080fd5b50813567ffffffffffffffff8111156101f457600080fd5b60208301915083602082850101111561020c57600080fd5b9250929050565b60008060008060006060868803121561022b57600080fd5b853567ffffffffffffffff8082111561024357600080fd5b61024f89838a016101ca565b9097509550602088013591508082111561026857600080fd5b50610275888289016101ca565b96999598509660400135949350505050565b8183823760009101908152919050565b6000602082840312156102a957600080fd5b5035919050565b600080604083850312156102c357600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610332576103326102d2565b5060010190565b6000821982111561034c5761034c6102d2565b50019056fea164736f6c634300080f000a" var AlphabetVMDeployedBin = "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610395565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610409565b6040518091039020901b036101d9576000805473ffffffffffffffffffffffffffffffffffffffff1663e03110e161011b60048861029f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152600060248201526044016040805180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610419565b50640ffffffff0607c82901c169350905063ffffffff608082901c1660006101c38a8c018c61043d565b90506101cf8582610485565b9350505050610206565b6101e58789018961049d565b9092509050816101f4816104bf565b9250508080610202906104bf565b9150505b6040805160208101849052908101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617610345818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b60008083601f84011261035e57600080fd5b50813567ffffffffffffffff81111561037657600080fd5b60208301915083602082850101111561038e57600080fd5b9250929050565b6000806000806000606086880312156103ad57600080fd5b853567ffffffffffffffff808211156103c557600080fd5b6103d189838a0161034c565b909750955060208801359150808211156103ea57600080fd5b506103f78882890161034c565b96999598509660400135949350505050565b8183823760009101908152919050565b6000806040838503121561042c57600080fd5b505080516020909101519092909150565b60006020828403121561044f57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561049857610498610456565b500190565b600080604083850312156104b057600080fd5b50508035926020909101359150565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036104f0576104f0610456565b506001019056fea164736f6c634300080f000a"
func init() { func init() {
......
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
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
)
// BlockOracleBlockInfo is an auto generated low-level Go binding around an user-defined struct.
type BlockOracleBlockInfo struct {
Hash [32]byte
ChildTimestamp uint64
}
// BlockOracleMetaData contains all meta data concerning the BlockOracle contract.
var BlockOracleMetaData = &bind.MetaData{
ABI: "[{\"type\":\"function\",\"name\":\"checkpoint\",\"inputs\":[],\"outputs\":[{\"name\":\"blockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"load\",\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"blockInfo_\",\"type\":\"tuple\",\"internalType\":\"structBlockOracle.BlockInfo\",\"components\":[{\"name\":\"hash\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"childTimestamp\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Checkpoint\",\"inputs\":[{\"name\":\"blockNumber\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Hash\"},{\"name\":\"childTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"Timestamp\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"BlockHashNotPresent\",\"inputs\":[]}]",
Bin: "0x608060405234801561001057600080fd5b506102e7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806399d548aa14610098578063c2c4c5c1146100d0575b600080fd5b6100826040518060400160405280600581526020017f302e302e3100000000000000000000000000000000000000000000000000000081525081565b60405161008f9190610210565b60405180910390f35b6100ab6100a6366004610283565b6100e6565b604080518251815260209283015167ffffffffffffffff16928101929092520161008f565b6100d8610165565b60405190815260200161008f565b604080518082018252600080825260209182018190528381528082528281208351808501909452805480855260019091015467ffffffffffffffff169284019290925203610160576040517f37cf270500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600061017260014361029c565b60408051808201825282408082524267ffffffffffffffff81811660208086018281526000898152918290528782209651875551600190960180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016969093169590951790915593519495509093909291849186917fb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c691a4505090565b600060208083528351808285015260005b8181101561023d57858101830151858201604001528201610221565b8181111561024f576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561029557600080fd5b5035919050565b6000828210156102d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a",
}
// BlockOracleABI is the input ABI used to generate the binding from.
// Deprecated: Use BlockOracleMetaData.ABI instead.
var BlockOracleABI = BlockOracleMetaData.ABI
// BlockOracleBin is the compiled bytecode used for deploying new contracts.
// Deprecated: Use BlockOracleMetaData.Bin instead.
var BlockOracleBin = BlockOracleMetaData.Bin
// DeployBlockOracle deploys a new Ethereum contract, binding an instance of BlockOracle to it.
func DeployBlockOracle(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *BlockOracle, error) {
parsed, err := BlockOracleMetaData.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(BlockOracleBin), backend)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &BlockOracle{BlockOracleCaller: BlockOracleCaller{contract: contract}, BlockOracleTransactor: BlockOracleTransactor{contract: contract}, BlockOracleFilterer: BlockOracleFilterer{contract: contract}}, nil
}
// BlockOracle is an auto generated Go binding around an Ethereum contract.
type BlockOracle struct {
BlockOracleCaller // Read-only binding to the contract
BlockOracleTransactor // Write-only binding to the contract
BlockOracleFilterer // Log filterer for contract events
}
// BlockOracleCaller is an auto generated read-only Go binding around an Ethereum contract.
type BlockOracleCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BlockOracleTransactor is an auto generated write-only Go binding around an Ethereum contract.
type BlockOracleTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BlockOracleFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type BlockOracleFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BlockOracleSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type BlockOracleSession struct {
Contract *BlockOracle // 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
}
// BlockOracleCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type BlockOracleCallerSession struct {
Contract *BlockOracleCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// BlockOracleTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type BlockOracleTransactorSession struct {
Contract *BlockOracleTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// BlockOracleRaw is an auto generated low-level Go binding around an Ethereum contract.
type BlockOracleRaw struct {
Contract *BlockOracle // Generic contract binding to access the raw methods on
}
// BlockOracleCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type BlockOracleCallerRaw struct {
Contract *BlockOracleCaller // Generic read-only contract binding to access the raw methods on
}
// BlockOracleTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type BlockOracleTransactorRaw struct {
Contract *BlockOracleTransactor // Generic write-only contract binding to access the raw methods on
}
// NewBlockOracle creates a new instance of BlockOracle, bound to a specific deployed contract.
func NewBlockOracle(address common.Address, backend bind.ContractBackend) (*BlockOracle, error) {
contract, err := bindBlockOracle(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &BlockOracle{BlockOracleCaller: BlockOracleCaller{contract: contract}, BlockOracleTransactor: BlockOracleTransactor{contract: contract}, BlockOracleFilterer: BlockOracleFilterer{contract: contract}}, nil
}
// NewBlockOracleCaller creates a new read-only instance of BlockOracle, bound to a specific deployed contract.
func NewBlockOracleCaller(address common.Address, caller bind.ContractCaller) (*BlockOracleCaller, error) {
contract, err := bindBlockOracle(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &BlockOracleCaller{contract: contract}, nil
}
// NewBlockOracleTransactor creates a new write-only instance of BlockOracle, bound to a specific deployed contract.
func NewBlockOracleTransactor(address common.Address, transactor bind.ContractTransactor) (*BlockOracleTransactor, error) {
contract, err := bindBlockOracle(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &BlockOracleTransactor{contract: contract}, nil
}
// NewBlockOracleFilterer creates a new log filterer instance of BlockOracle, bound to a specific deployed contract.
func NewBlockOracleFilterer(address common.Address, filterer bind.ContractFilterer) (*BlockOracleFilterer, error) {
contract, err := bindBlockOracle(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &BlockOracleFilterer{contract: contract}, nil
}
// bindBlockOracle binds a generic wrapper to an already deployed contract.
func bindBlockOracle(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(BlockOracleABI))
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 (_BlockOracle *BlockOracleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BlockOracle.Contract.BlockOracleCaller.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 (_BlockOracle *BlockOracleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BlockOracle.Contract.BlockOracleTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BlockOracle *BlockOracleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BlockOracle.Contract.BlockOracleTransactor.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 (_BlockOracle *BlockOracleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BlockOracle.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 (_BlockOracle *BlockOracleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BlockOracle.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BlockOracle *BlockOracleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BlockOracle.Contract.contract.Transact(opts, method, params...)
}
// Load is a free data retrieval call binding the contract method 0x99d548aa.
//
// Solidity: function load(uint256 _blockNumber) view returns((bytes32,uint64) blockInfo_)
func (_BlockOracle *BlockOracleCaller) Load(opts *bind.CallOpts, _blockNumber *big.Int) (BlockOracleBlockInfo, error) {
var out []interface{}
err := _BlockOracle.contract.Call(opts, &out, "load", _blockNumber)
if err != nil {
return *new(BlockOracleBlockInfo), err
}
out0 := *abi.ConvertType(out[0], new(BlockOracleBlockInfo)).(*BlockOracleBlockInfo)
return out0, err
}
// Load is a free data retrieval call binding the contract method 0x99d548aa.
//
// Solidity: function load(uint256 _blockNumber) view returns((bytes32,uint64) blockInfo_)
func (_BlockOracle *BlockOracleSession) Load(_blockNumber *big.Int) (BlockOracleBlockInfo, error) {
return _BlockOracle.Contract.Load(&_BlockOracle.CallOpts, _blockNumber)
}
// Load is a free data retrieval call binding the contract method 0x99d548aa.
//
// Solidity: function load(uint256 _blockNumber) view returns((bytes32,uint64) blockInfo_)
func (_BlockOracle *BlockOracleCallerSession) Load(_blockNumber *big.Int) (BlockOracleBlockInfo, error) {
return _BlockOracle.Contract.Load(&_BlockOracle.CallOpts, _blockNumber)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_BlockOracle *BlockOracleCaller) Version(opts *bind.CallOpts) (string, error) {
var out []interface{}
err := _BlockOracle.contract.Call(opts, &out, "version")
if err != nil {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_BlockOracle *BlockOracleSession) Version() (string, error) {
return _BlockOracle.Contract.Version(&_BlockOracle.CallOpts)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_BlockOracle *BlockOracleCallerSession) Version() (string, error) {
return _BlockOracle.Contract.Version(&_BlockOracle.CallOpts)
}
// Checkpoint is a paid mutator transaction binding the contract method 0xc2c4c5c1.
//
// Solidity: function checkpoint() returns(uint256 blockNumber_)
func (_BlockOracle *BlockOracleTransactor) Checkpoint(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BlockOracle.contract.Transact(opts, "checkpoint")
}
// Checkpoint is a paid mutator transaction binding the contract method 0xc2c4c5c1.
//
// Solidity: function checkpoint() returns(uint256 blockNumber_)
func (_BlockOracle *BlockOracleSession) Checkpoint() (*types.Transaction, error) {
return _BlockOracle.Contract.Checkpoint(&_BlockOracle.TransactOpts)
}
// Checkpoint is a paid mutator transaction binding the contract method 0xc2c4c5c1.
//
// Solidity: function checkpoint() returns(uint256 blockNumber_)
func (_BlockOracle *BlockOracleTransactorSession) Checkpoint() (*types.Transaction, error) {
return _BlockOracle.Contract.Checkpoint(&_BlockOracle.TransactOpts)
}
// BlockOracleCheckpointIterator is returned from FilterCheckpoint and is used to iterate over the raw logs and unpacked data for Checkpoint events raised by the BlockOracle contract.
type BlockOracleCheckpointIterator struct {
Event *BlockOracleCheckpoint // 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 *BlockOracleCheckpointIterator) 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(BlockOracleCheckpoint)
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(BlockOracleCheckpoint)
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 *BlockOracleCheckpointIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *BlockOracleCheckpointIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// BlockOracleCheckpoint represents a Checkpoint event raised by the BlockOracle contract.
type BlockOracleCheckpoint struct {
BlockNumber *big.Int
BlockHash [32]byte
ChildTimestamp uint64
Raw types.Log // Blockchain specific contextual infos
}
// FilterCheckpoint is a free log retrieval operation binding the contract event 0xb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c6.
//
// Solidity: event Checkpoint(uint256 indexed blockNumber, bytes32 indexed blockHash, uint64 indexed childTimestamp)
func (_BlockOracle *BlockOracleFilterer) FilterCheckpoint(opts *bind.FilterOpts, blockNumber []*big.Int, blockHash [][32]byte, childTimestamp []uint64) (*BlockOracleCheckpointIterator, error) {
var blockNumberRule []interface{}
for _, blockNumberItem := range blockNumber {
blockNumberRule = append(blockNumberRule, blockNumberItem)
}
var blockHashRule []interface{}
for _, blockHashItem := range blockHash {
blockHashRule = append(blockHashRule, blockHashItem)
}
var childTimestampRule []interface{}
for _, childTimestampItem := range childTimestamp {
childTimestampRule = append(childTimestampRule, childTimestampItem)
}
logs, sub, err := _BlockOracle.contract.FilterLogs(opts, "Checkpoint", blockNumberRule, blockHashRule, childTimestampRule)
if err != nil {
return nil, err
}
return &BlockOracleCheckpointIterator{contract: _BlockOracle.contract, event: "Checkpoint", logs: logs, sub: sub}, nil
}
// WatchCheckpoint is a free log subscription operation binding the contract event 0xb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c6.
//
// Solidity: event Checkpoint(uint256 indexed blockNumber, bytes32 indexed blockHash, uint64 indexed childTimestamp)
func (_BlockOracle *BlockOracleFilterer) WatchCheckpoint(opts *bind.WatchOpts, sink chan<- *BlockOracleCheckpoint, blockNumber []*big.Int, blockHash [][32]byte, childTimestamp []uint64) (event.Subscription, error) {
var blockNumberRule []interface{}
for _, blockNumberItem := range blockNumber {
blockNumberRule = append(blockNumberRule, blockNumberItem)
}
var blockHashRule []interface{}
for _, blockHashItem := range blockHash {
blockHashRule = append(blockHashRule, blockHashItem)
}
var childTimestampRule []interface{}
for _, childTimestampItem := range childTimestamp {
childTimestampRule = append(childTimestampRule, childTimestampItem)
}
logs, sub, err := _BlockOracle.contract.WatchLogs(opts, "Checkpoint", blockNumberRule, blockHashRule, childTimestampRule)
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(BlockOracleCheckpoint)
if err := _BlockOracle.contract.UnpackLog(event, "Checkpoint", 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
}
// ParseCheckpoint is a log parse operation binding the contract event 0xb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c6.
//
// Solidity: event Checkpoint(uint256 indexed blockNumber, bytes32 indexed blockHash, uint64 indexed childTimestamp)
func (_BlockOracle *BlockOracleFilterer) ParseCheckpoint(log types.Log) (*BlockOracleCheckpoint, error) {
event := new(BlockOracleCheckpoint)
if err := _BlockOracle.contract.UnpackLog(event, "Checkpoint", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const BlockOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/BlockOracle.sol:BlockOracle\",\"label\":\"blocks\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_uint256,t_struct(BlockInfo)1001_storage)\"}],\"types\":{\"t_mapping(t_uint256,t_struct(BlockInfo)1001_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e struct BlockOracle.BlockInfo)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_struct(BlockInfo)1001_storage\"},\"t_struct(BlockInfo)1001_storage\":{\"encoding\":\"inplace\",\"label\":\"struct BlockOracle.BlockInfo\",\"numberOfBytes\":\"64\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Hash)1002\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Timestamp)1003\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}"
var BlockOracleStorageLayout = new(solc.StorageLayout)
var BlockOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806399d548aa14610098578063c2c4c5c1146100d0575b600080fd5b6100826040518060400160405280600581526020017f302e302e3100000000000000000000000000000000000000000000000000000081525081565b60405161008f9190610210565b60405180910390f35b6100ab6100a6366004610283565b6100e6565b604080518251815260209283015167ffffffffffffffff16928101929092520161008f565b6100d8610165565b60405190815260200161008f565b604080518082018252600080825260209182018190528381528082528281208351808501909452805480855260019091015467ffffffffffffffff169284019290925203610160576040517f37cf270500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600061017260014361029c565b60408051808201825282408082524267ffffffffffffffff81811660208086018281526000898152918290528782209651875551600190960180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016969093169590951790915593519495509093909291849186917fb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c691a4505090565b600060208083528351808285015260005b8181101561023d57858101830151858201604001528201610221565b8181111561024f576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561029557600080fd5b5035919050565b6000828210156102d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(BlockOracleStorageLayoutJSON), BlockOracleStorageLayout); err != nil {
panic(err)
}
layouts["BlockOracle"] = BlockOracleStorageLayout
deployedBytecodes["BlockOracle"] = BlockOracleDeployedBin
immutableReferences["BlockOracle"] = false
}
...@@ -28,17 +28,10 @@ var ( ...@@ -28,17 +28,10 @@ var (
_ = event.NewSubscription _ = event.NewSubscription
) )
// IFaultDisputeGameOutputProposal is an auto generated low-level Go binding around an user-defined struct.
type IFaultDisputeGameOutputProposal struct {
Index *big.Int
L2BlockNumber *big.Int
OutputRoot [32]byte
}
// FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract. // FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract.
var FaultDisputeGameMetaData = &bind.MetaData{ var FaultDisputeGameMetaData = &bind.MetaData{
ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint8\",\"internalType\":\"GameType\"},{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gameDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"_vm\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"},{\"name\":\"_l2oo\",\"type\":\"address\",\"internalType\":\"contractL2OutputOracle\"},{\"name\":\"_blockOracle\",\"type\":\"address\",\"internalType\":\"contractBlockOracle\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ABSOLUTE_PRESTATE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"BLOCK_ORACLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractBlockOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"GAME_DURATION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Duration\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L2_OUTPUT_ORACLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractL2OutputOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_GAME_DEPTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VM\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addLocalData\",\"inputs\":[{\"name\":\"_ident\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_localContext\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"attack\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bondManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBondManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimData\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"parentIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"countered\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"position\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"clock\",\"type\":\"uint128\",\"internalType\":\"Clock\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDataLen\",\"inputs\":[],\"outputs\":[{\"name\":\"len_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createdAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"defend\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"extraData\",\"inputs\":[],\"outputs\":[{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"gameData\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint8\",\"internalType\":\"GameType\"},{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameType\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint8\",\"internalType\":\"GameType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"l1BlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"l1Head\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"l2BlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"move\",\"inputs\":[{\"name\":\"_challengeIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"proposals\",\"inputs\":[],\"outputs\":[{\"name\":\"starting\",\"type\":\"tuple\",\"internalType\":\"structIFaultDisputeGame.OutputProposal\",\"components\":[{\"name\":\"index\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}]},{\"name\":\"disputed\",\"type\":\"tuple\",\"internalType\":\"structIFaultDisputeGame.OutputProposal\",\"components\":[{\"name\":\"index\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[],\"outputs\":[{\"name\":\"status_\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolveClaim\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"rootClaim\",\"inputs\":[],\"outputs\":[{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"status\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Move\",\"inputs\":[{\"name\":\"parentIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Claim\"},{\"name\":\"claimant\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Resolved\",\"inputs\":[{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumGameStatus\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"CannotDefendRootClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyResolved\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockNotExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockTimeExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameDepthExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameNotInProgress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidParent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPrestate\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1HeadTooOld\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OutOfOrderResolution\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UnexpectedRootClaim\",\"inputs\":[{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]},{\"type\":\"error\",\"name\":\"ValidStep\",\"inputs\":[]}]", ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint8\",\"internalType\":\"GameType\"},{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_genesisBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_genesisOutputRoot\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"_maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_splitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gameDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"_vm\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"absolutePrestate\",\"inputs\":[],\"outputs\":[{\"name\":\"absolutePrestate_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addLocalData\",\"inputs\":[{\"name\":\"_ident\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_execLeafIdx\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"attack\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bondManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBondManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimData\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"parentIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"countered\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"position\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"clock\",\"type\":\"uint128\",\"internalType\":\"Clock\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDataLen\",\"inputs\":[],\"outputs\":[{\"name\":\"len_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createdAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"defend\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"extraData\",\"inputs\":[],\"outputs\":[{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"gameData\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint8\",\"internalType\":\"GameType\"},{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameDuration\",\"inputs\":[],\"outputs\":[{\"name\":\"gameDuration_\",\"type\":\"uint64\",\"internalType\":\"Duration\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameType\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint8\",\"internalType\":\"GameType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisBlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisOutputRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisOutputRoot_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1Head\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"l2BlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"maxGameDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"maxGameDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"move\",\"inputs\":[{\"name\":\"_challengeIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[],\"outputs\":[{\"name\":\"status_\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolveClaim\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolvedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rootClaim\",\"inputs\":[],\"outputs\":[{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"splitDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"splitDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"status\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"vm\",\"inputs\":[],\"outputs\":[{\"name\":\"vm_\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Move\",\"inputs\":[{\"name\":\"parentIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Claim\"},{\"name\":\"claimant\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Resolved\",\"inputs\":[{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumGameStatus\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"CannotDefendRootClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAboveSplit\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyResolved\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockNotExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockTimeExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameDepthExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameNotInProgress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidLocalIdent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidParent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPrestate\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSplitDepth\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OutOfOrderResolution\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UnexpectedRootClaim\",\"inputs\":[{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]},{\"type\":\"error\",\"name\":\"ValidStep\",\"inputs\":[]}]",
Bin: "0x6101606040523480156200001257600080fd5b5060405162002b5d38038062002b5d83398101604081905262000035916200008f565b60ff9096166101405260809490945260a0929092526001600160401b031660c0526001600160a01b0390811660e05290811661010052166101205262000133565b6001600160a01b03811681146200008c57600080fd5b50565b600080600080600080600060e0888a031215620000ab57600080fd5b875160ff81168114620000bd57600080fd5b602089015160408a015160608b015192995090975095506001600160401b0381168114620000ea57600080fd5b6080890151909450620000fd8162000076565b60a0890151909350620001108162000076565b60c0890151909250620001238162000076565b8091505092959891949750929550565b60805160a05160c05160e05161010051610120516101405161297b620001e2600039600081816105410152611c4401526000818161034901526112fd0152600081816105ba015281816110ca0152818161119e015261127701526000818161050b015281816117fb0152611adc0152600081816105ee01528181610bc60152611d3301526000818161031501528181610a0501526115fa01526000818161020a0152611756015261297b6000f3fe6080604052600436106101b75760003560e01c80638980e0cc116100ec578063c55cd0c71161008a578063d8cc1a3c11610064578063d8cc1a3c146106c1578063e66825b2146106e1578063fa24f74314610701578063fdffbb281461072557600080fd5b8063c55cd0c714610629578063c6f0308c1461063c578063cf09e0d0146106a057600080fd5b8063bbdc02db116100c6578063bbdc02db1461052d578063bcef3b551461056b578063c0c3a092146105a8578063c31b29ce146105dc57600080fd5b80638980e0cc146104a45780638b85902b146104b957806392931298146104f957600080fd5b8063529184c911610159578063609d333411610133578063609d333414610451578063632247ea146104665780636361506d146104795780638129fc1c1461048f57600080fd5b8063529184c91461033757806354fd4d501461036b57806355ef20e6146103c157600080fd5b8063298c900511610195578063298c90051461024f57806335fef5671461028f578063363cc427146102a45780634778efe81461030357600080fd5b8063200d2ed2146101bc578063266198f9146101f85780632810e1d61461023a575b600080fd5b3480156101c857600080fd5b506000546101e29068010000000000000000900460ff1681565b6040516101ef91906122c8565b60405180910390f35b34801561020457600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101ef565b34801561024657600080fd5b506101e2610738565b34801561025b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561022c565b6102a261029d366004612309565b61089c565b005b3480156102b057600080fd5b506000546102de906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ef565b34801561030f57600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034357600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037757600080fd5b506103b46040518060400160405280600681526020017f302e302e3133000000000000000000000000000000000000000000000000000081525081565b6040516101ef9190612396565b3480156103cd57600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff808216845270010000000000000000000000000000000091829004811660208086019190915260045485870152855193840186526005548083168552929092041690820152600654928101929092526104439182565b6040516101ef9291906123b0565b34801561045d57600080fd5b506103b46108ac565b6102a2610474366004612419565b6108ba565b34801561048557600080fd5b5061022c60015481565b34801561049b57600080fd5b506102a2610ed0565b3480156104b057600080fd5b5060025461022c565b3480156104c557600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561022c565b34801561050557600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561053957600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101ef565b34801561057757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561022c565b3480156105b457600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e857600080fd5b506106107f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff90911681526020016101ef565b6102a2610637366004612309565b6114d4565b34801561064857600080fd5b5061065c61065736600461244e565b6114e0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101ef565b3480156106ac57600080fd5b506000546106109067ffffffffffffffff1681565b3480156106cd57600080fd5b506102a26106dc3660046124b0565b611551565b3480156106ed57600080fd5b506102a26106fc36600461253a565b611a7d565b34801561070d57600080fd5b50610716611c42565b6040516101ef93929190612566565b6102a261073336600461244e565b611c9f565b60008060005468010000000000000000900460ff16600281111561075e5761075e612299565b14610795576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460ff166107d1576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000815481106107e5576107e5612591565b6000918252602090912060039091020154640100000000900460ff1661080c57600261080f565b60015b6000805491925082917fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff166801000000000000000083600281111561085657610856612299565b02179055600281111561086b5761086b612299565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b905090565b6108a8828260006108ba565b5050565b606061089760206040611fd1565b6000805468010000000000000000900460ff1660028111156108de576108de612299565b14610915576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610921575080155b15610958576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002848154811061096d5761096d612591565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610a019190859061206816565b90507f0000000000000000000000000000000000000000000000000000000000000000610ac0826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610b02576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610b62576002836000015163ffffffff1681548110610b3157610b31612591565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610b9b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610baf91906125ef565b610bb99190612607565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c2c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42176000888152608086901b6fffffffffffffffffffffffffffffffff8b1617602052604081209192509060008181526007602052604090205490915060ff1615610caa576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b908110610e2257610e22612591565b6000918252602080832060039092029091018054931515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909416939093179092558a8152600890915260409020600254610e8690600190612607565b8154600181018355600092835260208320015560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a6001811480610f10575060ff81166002145b610f76576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600291908101610ffb7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f00642061112460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b815260040161114291815260200190565b602060405180830381865afa15801561115f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611183919061261e565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae5576111ce600185612607565b6040518263ffffffff1660e01b81526004016111ec91815260200190565b606060405180830381865afa158015611209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122d9190612686565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa1580156112be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e29190612686565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b815260040161136e91815260200190565b6040805180830381865afa15801561138a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ae9190612712565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161140d576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081018252908190810180611428600189612607565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b6108a8828260016108ba565b600281815481106114f057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff16600281111561157557611575612299565b146115ac576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106115c1576115c1612591565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506116207f000000000000000000000000000000000000000000000000000000000000000060016125ef565b6116bc826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146116fd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561178057611721836fffffffffffffffffffffffffffffffff16612070565b67ffffffffffffffff16156117545761174b61173e600186612799565b865463ffffffff16612116565b60010154611776565b7f00000000000000000000000000000000000000000000000000000000000000005b915084905061179a565b8460010154915061179784600161173e91906127ca565b90505b600882901b60088a8a6040516117b19291906127fe565b6040518091039020901b146117f2576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e14ced328c8c8c8c60006040518663ffffffff1660e01b815260040161185b959493929190612857565b6020604051808303816000875af115801561187a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189e919061261e565b600284810154929091149250600091611949906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119e5886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119ef9190612891565b6119f991906128b2565b67ffffffffffffffff161590508115158103611a41576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b6000805468010000000000000000900460ff166002811115611aa157611aa1612299565b14611ad8576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190612900565b7f52f0f3ad00000000000000000000000000000000000000000000000000000000601c8190526020869052604085905290915060008560018114611bd55760028114611bdf5760038114611be95760048114611bf35760058114611c035763ff137e656000526004601cfd5b6001549150611c0a565b6004549150611c0a565b6006549150611c0a565b60035460801c60c01b9150611c0a565b4660c01b91505b50606052600160038611811b6005031b60805260a083905260008060a4601c82865af1611c3b573d6000803e3d6000fd5b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611c986108ac565b9050909192565b6000805468010000000000000000900460ff166002811115611cc357611cc3612299565b14611cfa576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611d0f57611d0f612591565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611d7f90700100000000000000000000000000000000900467ffffffffffffffff1642612607565b6002830154611daf9190700100000000000000000000000000000000900460401c67ffffffffffffffff166125ef565b11611de6576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040902082158015611e04575060095460ff165b15611e3b576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e4957508215155b15611e80576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f4e576000838281548110611ea157611ea1612591565b6000918252602080832090910154808352600890915260409091205490915015611ef7576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611f0c57611f0c612591565b600091825260209091206003909102018054909150640100000000900460ff16611f3b57600193505050611f4e565b505080611f4790612936565b9050611e84565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600860205260408120611f979161225f565b83600003611fcb57600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061200884367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036125ef565b90508267ffffffffffffffff1667ffffffffffffffff81111561202d5761202d612637565b6040519080825280601f01601f191660200182016040528015612057576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000806120fd837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080612134846fffffffffffffffffffffffffffffffff166121b3565b90506002838154811061214957612149612591565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146121ac57815460028054909163ffffffff1690811061219757612197612591565b9060005260206000209060030201915061215a565b5092915050565b60008119600183011681612247827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b508054600082559060005260206000209081019061227d9190612280565b50565b5b808211156122955760008155600101612281565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612303577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561231c57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561235157602081850181015186830182015201612335565b81811115612363576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123a9602083018461232b565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c081016123a9565b8035801515811461241457600080fd5b919050565b60008060006060848603121561242e57600080fd5b833592506020840135915061244560408501612404565b90509250925092565b60006020828403121561246057600080fd5b5035919050565b60008083601f84011261247957600080fd5b50813567ffffffffffffffff81111561249157600080fd5b6020830191508360208285010111156124a957600080fd5b9250929050565b600080600080600080608087890312156124c957600080fd5b863595506124d960208801612404565b9450604087013567ffffffffffffffff808211156124f657600080fd5b6125028a838b01612467565b9096509450606089013591508082111561251b57600080fd5b5061252889828a01612467565b979a9699509497509295939492505050565b60008060006060848603121561254f57600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612588606083018461232b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612602576126026125c0565b500190565b600082821015612619576126196125c0565b500390565b60006020828403121561263057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff8116811461241457600080fd5b60006060828403121561269857600080fd5b6040516060810181811067ffffffffffffffff821117156126e2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052825181526126f560208401612666565b602082015261270660408401612666565b60408201529392505050565b60006040828403121561272457600080fd5b6040516040810167ffffffffffffffff828210818311171561276f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b816040528451835260208501519150808216821461278c57600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156127c2576127c26125c0565b039392505050565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156127f5576127f56125c0565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60608152600061286b60608301878961280e565b828103602084015261287e81868861280e565b9150508260408301529695505050505050565b600067ffffffffffffffff838116908316818110156127c2576127c26125c0565b600067ffffffffffffffff808416806128f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910692915050565b60006020828403121561291257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146123a957600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612967576129676125c0565b506001019056fea164736f6c634300080f000a", Bin: "0x6101806040523480156200001257600080fd5b506040516200346738038062003467833981016040819052620000359162000098565b838310620000565760405163e62ccf3960e01b815260040160405180910390fd5b60ff90971661016052608095909552610120939093526101409190915260a05260c0526001600160401b031660e0526001600160a01b0316610100526200013a565b600080600080600080600080610100898b031215620000b657600080fd5b885160ff81168114620000c857600080fd5b60208a015160408b015160608c015160808d015160a08e015160c08f0151959d50939b509199509750955093506001600160401b03811681146200010b57600080fd5b60e08a01519092506001600160a01b03811681146200012957600080fd5b809150509295985092959890939650565b60805160a05160c05160e0516101005161012051610140516101605161322d6200023a600039600081816104a60152611c7d0152600081816103d1015261274a0152600081816101cb01528181610f5a01528181611ab50152611aeb01526000818161030a0152818161150401526118140152600081816105d401528181610c360152611d7401526000818161060701528181610a7101528181610b3a015281816113ad01528181611a8b015281816120e301528181612324015281816124520152818161255a015261263601526000818161067e01528181610add0152818161129c01526113ce01526000818161046e0152611452015261322d6000f3fe6080604052600436106101b75760003560e01c80638b85902b116100ec578063d8cc1a3c1161008a578063f8f43ff611610064578063f8f43ff61461062b578063fa24f7431461064b578063fa315aa91461066f578063fdffbb28146106a257600080fd5b8063d8cc1a3c146105a5578063e1f0c376146105c5578063ec5e6308146105f857600080fd5b8063bcef3b55116100c6578063bcef3b55146104d0578063c55cd0c71461050d578063c6f0308c14610520578063cf09e0d01461058457600080fd5b80638b85902b1461041f5780638d450a951461045f578063bbdc02db1461049257600080fd5b806354fd4d50116101595780636361506d116101335780636361506d146103ac57806368800abf146103c25780638129fc1c146103f55780638980e0cc1461040a57600080fd5b806354fd4d501461032e578063609d333414610384578063632247ea1461039957600080fd5b80632810e1d6116101955780632810e1d61461027f57806335fef56714610294578063363cc427146102a95780633a768463146102fb57600080fd5b80630356fe3a146101bc57806319effeb4146101fe578063200d2ed214610244575b600080fd5b3480156101c857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561020a57600080fd5b5060005461022b9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101f5565b34801561025057600080fd5b5060005461027290700100000000000000000000000000000000900460ff1681565b6040516101f59190612ce5565b34801561028b57600080fd5b506102726106b5565b6102a76102a2366004612d26565b610886565b005b3480156102b557600080fd5b506001546102d69073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f5565b34801561030757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102d6565b34801561033a57600080fd5b506103776040518060400160405280600681526020017f302e302e3139000000000000000000000000000000000000000000000000000081525081565b6040516101f59190612db3565b34801561039057600080fd5b50610377610896565b6102a76103a7366004612ddb565b6108a8565b3480156103b857600080fd5b506101eb60025481565b3480156103ce57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561040157600080fd5b506102a7610f58565b34801561041657600080fd5b506003546101eb565b34801561042b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101eb565b34801561046b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561049e57600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f5565b3480156104dc57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101eb565b6102a761051b366004612d26565b61116e565b34801561052c57600080fd5b5061054061053b366004612e10565b61117a565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101f5565b34801561059057600080fd5b5060005461022b9067ffffffffffffffff1681565b3480156105b157600080fd5b506102a76105c0366004612e72565b6111eb565b3480156105d157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061022b565b34801561060457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561063757600080fd5b506102a7610646366004612efc565b611786565b34801561065757600080fd5b50610660611c7b565b6040516101f593929190612f28565b34801561067b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b6102a76106b0366004612e10565b611cd8565b600080600054700100000000000000000000000000000000900460ff1660028111156106e3576106e3612cb6565b1461071a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065460ff16610756576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600360008154811061076a5761076a612f53565b6000918252602090912060039091020154640100000000900460ff16610791576002610794565b60015b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561084557610845612cb6565b02179055600281111561085a5761085a612cb6565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610892828260006108a8565b5050565b60606108a3602080612012565b905090565b60008054700100000000000000000000000000000000900460ff1660028111156108d4576108d4612cb6565b1461090b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003848154811061092057610920612f53565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff808216606085018190527001000000000000000000000000000000009092041660808401529193509091906109b890839086906120a916565b90506000610a58826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610a9a5750610a977f00000000000000000000000000000000000000000000000000000000000000006002612fb1565b81145b8015610aa4575084155b15610adb576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610b35576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b607f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8103610b7257610b72868885886120b1565b835160009063ffffffff90811614610bd2576003856000015163ffffffff1681548110610ba157610ba1612f53565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608085015160009067ffffffffffffffff1667ffffffffffffffff1642610c0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610c1f9190612fb1565b610c299190612fc9565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c9c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615610d1a576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060036040518060a001604052808d63ffffffff1681526020016000151581526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548160ff0219169083151502179055506040820151816001015560608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160020160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600160038c81548110610eab57610eab612f53565b600091825260208083206003928302018054941515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909516949094179093558d82526005909252604090209054610f0c90600190612fc9565b8154600181018355600092835260208320015560405133918c918e917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a45050505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001351161100f576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff16179055604636111561105a5763c407e0256000526004601cfd5b6040805160a08101825263ffffffff8152600060208201526003918101367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff90931692909217949094178155604083015181850155606083015160809093015182167001000000000000000000000000000000000292909116919091176002909101556111689043612fc9565b40600255565b610892828260016108a8565b6003818154811061118a57600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b60008054700100000000000000000000000000000000900460ff16600281111561121757611217612cb6565b1461124e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003878154811061126357611263612f53565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112c27f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b61135e826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161461139f576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561147c576113f27f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612fc9565b6001901b611411846fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16611425919061300f565b1561145057611447611438600186613023565b865463ffffffff166000612304565b60010154611472565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611496565b846001015491506114938460016114389190613054565b90505b600882901b60088a8a6040516114ad929190613088565b6040518091039020901b146114ee576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114f98c6123e8565b9050600082600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e14ced328d8d8d8d886040518663ffffffff1660e01b81526004016115639594939291906130e1565b6020604051808303816000875af1158015611582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a6919061311b565b600285810154929091149250600091611651906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116ed896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116f79190613134565b6117019190613155565b67ffffffffffffffff161590508115158103611749576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156117b2576117b2612cb6565b146117e9576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806117f886612417565b9350935093509350600061180e858585856127e4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561187d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a1919061317c565b905060018903611963576002546040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018b9052602481018490526044810191909152602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4015b6020604051808303816000875af1158015611939573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195d919061311b565b50611c70565b600289036119da576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101879052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60038903611a51576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101859052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60048903611bc55760006fffffffffffffffffffffffffffffffff861615611ae957611aaf6fffffffffffffffffffffffffffffffff87167f00000000000000000000000000000000000000000000000000000000000000006128a4565b611ad9907f0000000000000000000000000000000000000000000000000000000000000000612fb1565b611ae4906001612fb1565b611b0b565b7f00000000000000000000000000000000000000000000000000000000000000005b6040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018c90526024810185905260c082901b604482015260086064820152608481018a905290915073ffffffffffffffffffffffffffffffffffffffff8316906352f0f3ad9060a4016020604051808303816000875af1158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe919061311b565b5050611c70565b60058903611c3e576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390524660c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611cd1610896565b9050909192565b60008054700100000000000000000000000000000000900460ff166002811115611d0457611d04612cb6565b14611d3b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611d5057611d50612f53565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611dc090700100000000000000000000000000000000900467ffffffffffffffff1642612fc9565b6002830154611df09190700100000000000000000000000000000000900460401c67ffffffffffffffff16612fb1565b11611e27576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260056020526040902082158015611e45575060065460ff165b15611e7c576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e8a57508215155b15611ec1576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f8f576000838281548110611ee257611ee2612f53565b6000918252602080832090910154808352600590915260409091205490915015611f38576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611f4d57611f4d612f53565b600091825260209091206003909102018054909150640100000000900460ff16611f7c57600193505050611f8f565b505080611f88906131b9565b9050611ec5565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600560205260408120611fd891612c7c565b8360000361200c57600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061204984367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003612fb1565b90508267ffffffffffffffff1667ffffffffffffffff81111561206e5761206e6131f1565b6040519080825280601f01601f191660200182016040528015612098576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60006120be836001613054565b905060006120ce82866001612304565b9050600086901a83806121bf575061210760027f000000000000000000000000000000000000000000000000000000000000000061300f565b6002838101546121a9906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121b39190613155565b67ffffffffffffffff16145b156122175760ff8116600114806121d9575060ff81166002145b612212576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b612255565b60ff811615612255576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b50505050505050565b6000806122eb837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261234d576123486fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000612959565b612368565b612368856fffffffffffffffffffffffffffffffff16612b20565b90506003848154811061237d5761237d612f53565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146123e057815460038054909163ffffffff169081106123cb576123cb612f53565b9060005260206000209060030201915061238e565b509392505050565b60008060008060006123f986612417565b935093509350935061240d848484846127e4565b9695505050505050565b600080600080600085905060006003828154811061243757612437612f53565b600091825260209091206002600390920201908101549091507f00000000000000000000000000000000000000000000000000000000000000009061250e906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161254f576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60028301547f000000000000000000000000000000000000000000000000000000000000000090612616906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16925082111561269257825463ffffffff1661265c7f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8303612666578391505b6003818154811061267957612679612f53565b9060005260206000209060030201935080945050612553565b600280820154908401546fffffffffffffffffffffffffffffffff91821691166000816126bf8460011c90565b6fffffffffffffffffffffffffffffffff1614905080156127925760006126f7836fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16111561274857600061271f612717600185613023565b896001612304565b6001810154600290910154909c506fffffffffffffffffffffffffffffffff169a5061276c9050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600186015460028701549099506fffffffffffffffffffffffffffffffff1697506127d6565b60006127a2612717846001613054565b6001808901546002808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b6000836fffffffffffffffffffffffffffffffff1660000361284b57828260405160200161282e9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b60405160208183030381529060405280519060200120905061289c565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080612931847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b6000816129f8846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612a39576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a4283612b20565b905081612ae1826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612b1a57612b17612afe836001612fb1565b6fffffffffffffffffffffffffffffffff831690612bcc565b90505b92915050565b60008119600183011681612bb4827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080612c59847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190612c9a9190612c9d565b50565b5b80821115612cb25760008155600101612c9e565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612d20577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215612d3957600080fd5b50508035926020909101359150565b6000815180845260005b81811015612d6e57602081850181015186830182015201612d52565b81811115612d80576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612b176020830184612d48565b80358015158114612dd657600080fd5b919050565b600080600060608486031215612df057600080fd5b8335925060208401359150612e0760408501612dc6565b90509250925092565b600060208284031215612e2257600080fd5b5035919050565b60008083601f840112612e3b57600080fd5b50813567ffffffffffffffff811115612e5357600080fd5b602083019150836020828501011115612e6b57600080fd5b9250929050565b60008060008060008060808789031215612e8b57600080fd5b86359550612e9b60208801612dc6565b9450604087013567ffffffffffffffff80821115612eb857600080fd5b612ec48a838b01612e29565b90965094506060890135915080821115612edd57600080fd5b50612eea89828a01612e29565b979a9699509497509295939492505050565b600080600060608486031215612f1157600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612f4a6060830184612d48565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612fc457612fc4612f82565b500190565b600082821015612fdb57612fdb612f82565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261301e5761301e612fe0565b500690565b60006fffffffffffffffffffffffffffffffff8381169083168181101561304c5761304c612f82565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561307f5761307f612f82565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006130f5606083018789613098565b8281036020840152613108818688613098565b9150508260408301529695505050505050565b60006020828403121561312d57600080fd5b5051919050565b600067ffffffffffffffff8381169083168181101561304c5761304c612f82565b600067ffffffffffffffff8084168061317057613170612fe0565b92169190910692915050565b60006020828403121561318e57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146131b257600080fd5b9392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036131ea576131ea612f82565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c634300080f000a",
} }
// FaultDisputeGameABI is the input ABI used to generate the binding from. // FaultDisputeGameABI is the input ABI used to generate the binding from.
...@@ -50,7 +43,7 @@ var FaultDisputeGameABI = FaultDisputeGameMetaData.ABI ...@@ -50,7 +43,7 @@ var FaultDisputeGameABI = FaultDisputeGameMetaData.ABI
var FaultDisputeGameBin = FaultDisputeGameMetaData.Bin var FaultDisputeGameBin = FaultDisputeGameMetaData.Bin
// DeployFaultDisputeGame deploys a new Ethereum contract, binding an instance of FaultDisputeGame to it. // DeployFaultDisputeGame deploys a new Ethereum contract, binding an instance of FaultDisputeGame to it.
func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBackend, _gameType uint8, _absolutePrestate [32]byte, _maxGameDepth *big.Int, _gameDuration uint64, _vm common.Address, _l2oo common.Address, _blockOracle common.Address) (common.Address, *types.Transaction, *FaultDisputeGame, error) { func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBackend, _gameType uint8, _absolutePrestate [32]byte, _genesisBlockNumber *big.Int, _genesisOutputRoot [32]byte, _maxGameDepth *big.Int, _splitDepth *big.Int, _gameDuration uint64, _vm common.Address) (common.Address, *types.Transaction, *FaultDisputeGame, error) {
parsed, err := FaultDisputeGameMetaData.GetAbi() parsed, err := FaultDisputeGameMetaData.GetAbi()
if err != nil { if err != nil {
return common.Address{}, nil, nil, err return common.Address{}, nil, nil, err
...@@ -59,7 +52,7 @@ func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBacken ...@@ -59,7 +52,7 @@ func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBacken
return common.Address{}, nil, nil, errors.New("GetABI returned nil") return common.Address{}, nil, nil, errors.New("GetABI returned nil")
} }
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FaultDisputeGameBin), backend, _gameType, _absolutePrestate, _maxGameDepth, _gameDuration, _vm, _l2oo, _blockOracle) address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FaultDisputeGameBin), backend, _gameType, _absolutePrestate, _genesisBlockNumber, _genesisOutputRoot, _maxGameDepth, _splitDepth, _gameDuration, _vm)
if err != nil { if err != nil {
return common.Address{}, nil, nil, err return common.Address{}, nil, nil, err
} }
...@@ -208,12 +201,12 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorRaw) Transact(opts *bind.Tran ...@@ -208,12 +201,12 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorRaw) Transact(opts *bind.Tran
return _FaultDisputeGame.Contract.contract.Transact(opts, method, params...) return _FaultDisputeGame.Contract.contract.Transact(opts, method, params...)
} }
// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9. // AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95.
// //
// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32) // Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_)
func (_FaultDisputeGame *FaultDisputeGameCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) { func (_FaultDisputeGame *FaultDisputeGameCaller) AbsolutePrestate(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{} var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "ABSOLUTE_PRESTATE") err := _FaultDisputeGame.contract.Call(opts, &out, "absolutePrestate")
if err != nil { if err != nil {
return *new([32]byte), err return *new([32]byte), err
...@@ -225,173 +218,18 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) ABSOLUTEPRESTATE(opts *bind.Cal ...@@ -225,173 +218,18 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) ABSOLUTEPRESTATE(opts *bind.Cal
} }
// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9. // AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95.
//
// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32)
func (_FaultDisputeGame *FaultDisputeGameSession) ABSOLUTEPRESTATE() ([32]byte, error) {
return _FaultDisputeGame.Contract.ABSOLUTEPRESTATE(&_FaultDisputeGame.CallOpts)
}
// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9.
//
// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) ABSOLUTEPRESTATE() ([32]byte, error) {
return _FaultDisputeGame.Contract.ABSOLUTEPRESTATE(&_FaultDisputeGame.CallOpts)
}
// BLOCKORACLE is a free data retrieval call binding the contract method 0x529184c9.
//
// Solidity: function BLOCK_ORACLE() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCaller) BLOCKORACLE(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "BLOCK_ORACLE")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// BLOCKORACLE is a free data retrieval call binding the contract method 0x529184c9.
// //
// Solidity: function BLOCK_ORACLE() view returns(address) // Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_)
func (_FaultDisputeGame *FaultDisputeGameSession) BLOCKORACLE() (common.Address, error) { func (_FaultDisputeGame *FaultDisputeGameSession) AbsolutePrestate() ([32]byte, error) {
return _FaultDisputeGame.Contract.BLOCKORACLE(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.AbsolutePrestate(&_FaultDisputeGame.CallOpts)
} }
// BLOCKORACLE is a free data retrieval call binding the contract method 0x529184c9. // AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95.
// //
// Solidity: function BLOCK_ORACLE() view returns(address) // Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) BLOCKORACLE() (common.Address, error) { func (_FaultDisputeGame *FaultDisputeGameCallerSession) AbsolutePrestate() ([32]byte, error) {
return _FaultDisputeGame.Contract.BLOCKORACLE(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.AbsolutePrestate(&_FaultDisputeGame.CallOpts)
}
// GAMEDURATION is a free data retrieval call binding the contract method 0xc31b29ce.
//
// Solidity: function GAME_DURATION() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameCaller) GAMEDURATION(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "GAME_DURATION")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// GAMEDURATION is a free data retrieval call binding the contract method 0xc31b29ce.
//
// Solidity: function GAME_DURATION() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameSession) GAMEDURATION() (uint64, error) {
return _FaultDisputeGame.Contract.GAMEDURATION(&_FaultDisputeGame.CallOpts)
}
// GAMEDURATION is a free data retrieval call binding the contract method 0xc31b29ce.
//
// Solidity: function GAME_DURATION() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) GAMEDURATION() (uint64, error) {
return _FaultDisputeGame.Contract.GAMEDURATION(&_FaultDisputeGame.CallOpts)
}
// L2OUTPUTORACLE is a free data retrieval call binding the contract method 0xc0c3a092.
//
// Solidity: function L2_OUTPUT_ORACLE() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCaller) L2OUTPUTORACLE(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "L2_OUTPUT_ORACLE")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// L2OUTPUTORACLE is a free data retrieval call binding the contract method 0xc0c3a092.
//
// Solidity: function L2_OUTPUT_ORACLE() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameSession) L2OUTPUTORACLE() (common.Address, error) {
return _FaultDisputeGame.Contract.L2OUTPUTORACLE(&_FaultDisputeGame.CallOpts)
}
// L2OUTPUTORACLE is a free data retrieval call binding the contract method 0xc0c3a092.
//
// Solidity: function L2_OUTPUT_ORACLE() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) L2OUTPUTORACLE() (common.Address, error) {
return _FaultDisputeGame.Contract.L2OUTPUTORACLE(&_FaultDisputeGame.CallOpts)
}
// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8.
//
// Solidity: function MAX_GAME_DEPTH() view returns(uint256)
func (_FaultDisputeGame *FaultDisputeGameCaller) MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "MAX_GAME_DEPTH")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8.
//
// Solidity: function MAX_GAME_DEPTH() view returns(uint256)
func (_FaultDisputeGame *FaultDisputeGameSession) MAXGAMEDEPTH() (*big.Int, error) {
return _FaultDisputeGame.Contract.MAXGAMEDEPTH(&_FaultDisputeGame.CallOpts)
}
// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8.
//
// Solidity: function MAX_GAME_DEPTH() view returns(uint256)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) MAXGAMEDEPTH() (*big.Int, error) {
return _FaultDisputeGame.Contract.MAXGAMEDEPTH(&_FaultDisputeGame.CallOpts)
}
// VM is a free data retrieval call binding the contract method 0x92931298.
//
// Solidity: function VM() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCaller) VM(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "VM")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// VM is a free data retrieval call binding the contract method 0x92931298.
//
// Solidity: function VM() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameSession) VM() (common.Address, error) {
return _FaultDisputeGame.Contract.VM(&_FaultDisputeGame.CallOpts)
}
// VM is a free data retrieval call binding the contract method 0x92931298.
//
// Solidity: function VM() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) VM() (common.Address, error) {
return _FaultDisputeGame.Contract.VM(&_FaultDisputeGame.CallOpts)
} }
// BondManager is a free data retrieval call binding the contract method 0x363cc427. // BondManager is a free data retrieval call binding the contract method 0x363cc427.
...@@ -628,6 +466,37 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameData() (struct { ...@@ -628,6 +466,37 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameData() (struct {
return _FaultDisputeGame.Contract.GameData(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.GameData(&_FaultDisputeGame.CallOpts)
} }
// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376.
//
// Solidity: function gameDuration() view returns(uint64 gameDuration_)
func (_FaultDisputeGame *FaultDisputeGameCaller) GameDuration(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "gameDuration")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376.
//
// Solidity: function gameDuration() view returns(uint64 gameDuration_)
func (_FaultDisputeGame *FaultDisputeGameSession) GameDuration() (uint64, error) {
return _FaultDisputeGame.Contract.GameDuration(&_FaultDisputeGame.CallOpts)
}
// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376.
//
// Solidity: function gameDuration() view returns(uint64 gameDuration_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameDuration() (uint64, error) {
return _FaultDisputeGame.Contract.GameDuration(&_FaultDisputeGame.CallOpts)
}
// GameType is a free data retrieval call binding the contract method 0xbbdc02db. // GameType is a free data retrieval call binding the contract method 0xbbdc02db.
// //
// Solidity: function gameType() view returns(uint8 gameType_) // Solidity: function gameType() view returns(uint8 gameType_)
...@@ -659,12 +528,12 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameType() (uint8, error ...@@ -659,12 +528,12 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameType() (uint8, error
return _FaultDisputeGame.Contract.GameType(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.GameType(&_FaultDisputeGame.CallOpts)
} }
// L1BlockNumber is a free data retrieval call binding the contract method 0x298c9005. // GenesisBlockNumber is a free data retrieval call binding the contract method 0x0356fe3a.
// //
// Solidity: function l1BlockNumber() pure returns(uint256 l1BlockNumber_) // Solidity: function genesisBlockNumber() view returns(uint256 genesisBlockNumber_)
func (_FaultDisputeGame *FaultDisputeGameCaller) L1BlockNumber(opts *bind.CallOpts) (*big.Int, error) { func (_FaultDisputeGame *FaultDisputeGameCaller) GenesisBlockNumber(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{} var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "l1BlockNumber") err := _FaultDisputeGame.contract.Call(opts, &out, "genesisBlockNumber")
if err != nil { if err != nil {
return *new(*big.Int), err return *new(*big.Int), err
...@@ -676,18 +545,49 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) L1BlockNumber(opts *bind.CallOp ...@@ -676,18 +545,49 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) L1BlockNumber(opts *bind.CallOp
} }
// L1BlockNumber is a free data retrieval call binding the contract method 0x298c9005. // GenesisBlockNumber is a free data retrieval call binding the contract method 0x0356fe3a.
// //
// Solidity: function l1BlockNumber() pure returns(uint256 l1BlockNumber_) // Solidity: function genesisBlockNumber() view returns(uint256 genesisBlockNumber_)
func (_FaultDisputeGame *FaultDisputeGameSession) L1BlockNumber() (*big.Int, error) { func (_FaultDisputeGame *FaultDisputeGameSession) GenesisBlockNumber() (*big.Int, error) {
return _FaultDisputeGame.Contract.L1BlockNumber(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.GenesisBlockNumber(&_FaultDisputeGame.CallOpts)
} }
// L1BlockNumber is a free data retrieval call binding the contract method 0x298c9005. // GenesisBlockNumber is a free data retrieval call binding the contract method 0x0356fe3a.
// //
// Solidity: function l1BlockNumber() pure returns(uint256 l1BlockNumber_) // Solidity: function genesisBlockNumber() view returns(uint256 genesisBlockNumber_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) L1BlockNumber() (*big.Int, error) { func (_FaultDisputeGame *FaultDisputeGameCallerSession) GenesisBlockNumber() (*big.Int, error) {
return _FaultDisputeGame.Contract.L1BlockNumber(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.GenesisBlockNumber(&_FaultDisputeGame.CallOpts)
}
// GenesisOutputRoot is a free data retrieval call binding the contract method 0x68800abf.
//
// Solidity: function genesisOutputRoot() view returns(bytes32 genesisOutputRoot_)
func (_FaultDisputeGame *FaultDisputeGameCaller) GenesisOutputRoot(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "genesisOutputRoot")
if err != nil {
return *new([32]byte), err
}
out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
return out0, err
}
// GenesisOutputRoot is a free data retrieval call binding the contract method 0x68800abf.
//
// Solidity: function genesisOutputRoot() view returns(bytes32 genesisOutputRoot_)
func (_FaultDisputeGame *FaultDisputeGameSession) GenesisOutputRoot() ([32]byte, error) {
return _FaultDisputeGame.Contract.GenesisOutputRoot(&_FaultDisputeGame.CallOpts)
}
// GenesisOutputRoot is a free data retrieval call binding the contract method 0x68800abf.
//
// Solidity: function genesisOutputRoot() view returns(bytes32 genesisOutputRoot_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) GenesisOutputRoot() ([32]byte, error) {
return _FaultDisputeGame.Contract.GenesisOutputRoot(&_FaultDisputeGame.CallOpts)
} }
// L1Head is a free data retrieval call binding the contract method 0x6361506d. // L1Head is a free data retrieval call binding the contract method 0x6361506d.
...@@ -752,49 +652,66 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) L2BlockNumber() (*big.In ...@@ -752,49 +652,66 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) L2BlockNumber() (*big.In
return _FaultDisputeGame.Contract.L2BlockNumber(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.L2BlockNumber(&_FaultDisputeGame.CallOpts)
} }
// Proposals is a free data retrieval call binding the contract method 0x55ef20e6. // MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9.
// //
// Solidity: function proposals() view returns((uint128,uint128,bytes32) starting, (uint128,uint128,bytes32) disputed) // Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_)
func (_FaultDisputeGame *FaultDisputeGameCaller) Proposals(opts *bind.CallOpts) (struct { func (_FaultDisputeGame *FaultDisputeGameCaller) MaxGameDepth(opts *bind.CallOpts) (*big.Int, error) {
Starting IFaultDisputeGameOutputProposal
Disputed IFaultDisputeGameOutputProposal
}, error) {
var out []interface{} var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "proposals") err := _FaultDisputeGame.contract.Call(opts, &out, "maxGameDepth")
outstruct := new(struct {
Starting IFaultDisputeGameOutputProposal
Disputed IFaultDisputeGameOutputProposal
})
if err != nil { if err != nil {
return *outstruct, err return *new(*big.Int), err
} }
outstruct.Starting = *abi.ConvertType(out[0], new(IFaultDisputeGameOutputProposal)).(*IFaultDisputeGameOutputProposal) out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
outstruct.Disputed = *abi.ConvertType(out[1], new(IFaultDisputeGameOutputProposal)).(*IFaultDisputeGameOutputProposal)
return *outstruct, err return out0, err
} }
// Proposals is a free data retrieval call binding the contract method 0x55ef20e6. // MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9.
// //
// Solidity: function proposals() view returns((uint128,uint128,bytes32) starting, (uint128,uint128,bytes32) disputed) // Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_)
func (_FaultDisputeGame *FaultDisputeGameSession) Proposals() (struct { func (_FaultDisputeGame *FaultDisputeGameSession) MaxGameDepth() (*big.Int, error) {
Starting IFaultDisputeGameOutputProposal return _FaultDisputeGame.Contract.MaxGameDepth(&_FaultDisputeGame.CallOpts)
Disputed IFaultDisputeGameOutputProposal
}, error) {
return _FaultDisputeGame.Contract.Proposals(&_FaultDisputeGame.CallOpts)
} }
// Proposals is a free data retrieval call binding the contract method 0x55ef20e6. // MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9.
// //
// Solidity: function proposals() view returns((uint128,uint128,bytes32) starting, (uint128,uint128,bytes32) disputed) // Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) Proposals() (struct { func (_FaultDisputeGame *FaultDisputeGameCallerSession) MaxGameDepth() (*big.Int, error) {
Starting IFaultDisputeGameOutputProposal return _FaultDisputeGame.Contract.MaxGameDepth(&_FaultDisputeGame.CallOpts)
Disputed IFaultDisputeGameOutputProposal }
}, error) {
return _FaultDisputeGame.Contract.Proposals(&_FaultDisputeGame.CallOpts) // ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4.
//
// Solidity: function resolvedAt() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameCaller) ResolvedAt(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "resolvedAt")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4.
//
// Solidity: function resolvedAt() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameSession) ResolvedAt() (uint64, error) {
return _FaultDisputeGame.Contract.ResolvedAt(&_FaultDisputeGame.CallOpts)
}
// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4.
//
// Solidity: function resolvedAt() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) ResolvedAt() (uint64, error) {
return _FaultDisputeGame.Contract.ResolvedAt(&_FaultDisputeGame.CallOpts)
} }
// RootClaim is a free data retrieval call binding the contract method 0xbcef3b55. // RootClaim is a free data retrieval call binding the contract method 0xbcef3b55.
...@@ -828,6 +745,37 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) RootClaim() ([32]byte, e ...@@ -828,6 +745,37 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) RootClaim() ([32]byte, e
return _FaultDisputeGame.Contract.RootClaim(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.RootClaim(&_FaultDisputeGame.CallOpts)
} }
// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308.
//
// Solidity: function splitDepth() view returns(uint256 splitDepth_)
func (_FaultDisputeGame *FaultDisputeGameCaller) SplitDepth(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "splitDepth")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308.
//
// Solidity: function splitDepth() view returns(uint256 splitDepth_)
func (_FaultDisputeGame *FaultDisputeGameSession) SplitDepth() (*big.Int, error) {
return _FaultDisputeGame.Contract.SplitDepth(&_FaultDisputeGame.CallOpts)
}
// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308.
//
// Solidity: function splitDepth() view returns(uint256 splitDepth_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) SplitDepth() (*big.Int, error) {
return _FaultDisputeGame.Contract.SplitDepth(&_FaultDisputeGame.CallOpts)
}
// Status is a free data retrieval call binding the contract method 0x200d2ed2. // Status is a free data retrieval call binding the contract method 0x200d2ed2.
// //
// Solidity: function status() view returns(uint8) // Solidity: function status() view returns(uint8)
...@@ -890,25 +838,56 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) Version() (string, error ...@@ -890,25 +838,56 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) Version() (string, error
return _FaultDisputeGame.Contract.Version(&_FaultDisputeGame.CallOpts) return _FaultDisputeGame.Contract.Version(&_FaultDisputeGame.CallOpts)
} }
// AddLocalData is a paid mutator transaction binding the contract method 0xe66825b2. // Vm is a free data retrieval call binding the contract method 0x3a768463.
//
// Solidity: function vm() view returns(address vm_)
func (_FaultDisputeGame *FaultDisputeGameCaller) Vm(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "vm")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// Vm is a free data retrieval call binding the contract method 0x3a768463.
//
// Solidity: function vm() view returns(address vm_)
func (_FaultDisputeGame *FaultDisputeGameSession) Vm() (common.Address, error) {
return _FaultDisputeGame.Contract.Vm(&_FaultDisputeGame.CallOpts)
}
// Vm is a free data retrieval call binding the contract method 0x3a768463.
//
// Solidity: function vm() view returns(address vm_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) Vm() (common.Address, error) {
return _FaultDisputeGame.Contract.Vm(&_FaultDisputeGame.CallOpts)
}
// AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6.
// //
// Solidity: function addLocalData(uint256 _ident, bytes32 _localContext, uint256 _partOffset) returns() // Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns()
func (_FaultDisputeGame *FaultDisputeGameTransactor) AddLocalData(opts *bind.TransactOpts, _ident *big.Int, _localContext [32]byte, _partOffset *big.Int) (*types.Transaction, error) { func (_FaultDisputeGame *FaultDisputeGameTransactor) AddLocalData(opts *bind.TransactOpts, _ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) {
return _FaultDisputeGame.contract.Transact(opts, "addLocalData", _ident, _localContext, _partOffset) return _FaultDisputeGame.contract.Transact(opts, "addLocalData", _ident, _execLeafIdx, _partOffset)
} }
// AddLocalData is a paid mutator transaction binding the contract method 0xe66825b2. // AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6.
// //
// Solidity: function addLocalData(uint256 _ident, bytes32 _localContext, uint256 _partOffset) returns() // Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns()
func (_FaultDisputeGame *FaultDisputeGameSession) AddLocalData(_ident *big.Int, _localContext [32]byte, _partOffset *big.Int) (*types.Transaction, error) { func (_FaultDisputeGame *FaultDisputeGameSession) AddLocalData(_ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _localContext, _partOffset) return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _execLeafIdx, _partOffset)
} }
// AddLocalData is a paid mutator transaction binding the contract method 0xe66825b2. // AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6.
// //
// Solidity: function addLocalData(uint256 _ident, bytes32 _localContext, uint256 _partOffset) returns() // Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns()
func (_FaultDisputeGame *FaultDisputeGameTransactorSession) AddLocalData(_ident *big.Int, _localContext [32]byte, _partOffset *big.Int) (*types.Transaction, error) { func (_FaultDisputeGame *FaultDisputeGameTransactorSession) AddLocalData(_ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _localContext, _partOffset) return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _execLeafIdx, _partOffset)
} }
// Attack is a paid mutator transaction binding the contract method 0xc55cd0c7. // Attack is a paid mutator transaction binding the contract method 0xc55cd0c7.
......
...@@ -9,11 +9,11 @@ import ( ...@@ -9,11 +9,11 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const FaultDisputeGameStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"createdAt\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1019\"},{\"astId\":1001,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"status\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_enum(GameStatus)1010\"},{\"astId\":1002,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"bondManager\",\"offset\":9,\"slot\":\"0\",\"type\":\"t_contract(IBondManager)1009\"},{\"astId\":1003,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"l1Head\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_userDefinedValueType(Hash)1017\"},{\"astId\":1004,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claimData\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\"},{\"astId\":1005,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"proposals\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_struct(OutputProposals)1013_storage\"},{\"astId\":1006,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claims\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_mapping(t_userDefinedValueType(ClaimHash)1015,t_bool)\"},{\"astId\":1007,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgames\",\"offset\":0,\"slot\":\"8\",\"type\":\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\"},{\"astId\":1008,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgameAtRootResolved\",\"offset\":0,\"slot\":\"9\",\"type\":\"t_bool\"}],\"types\":{\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct IFaultDisputeGame.ClaimData[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(ClaimData)1011_storage\"},\"t_array(t_uint256)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"uint256[]\",\"numberOfBytes\":\"32\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(IBondManager)1009\":{\"encoding\":\"inplace\",\"label\":\"contract IBondManager\",\"numberOfBytes\":\"20\"},\"t_enum(GameStatus)1010\":{\"encoding\":\"inplace\",\"label\":\"enum GameStatus\",\"numberOfBytes\":\"1\"},\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e uint256[])\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_array(t_uint256)dyn_storage\"},\"t_mapping(t_userDefinedValueType(ClaimHash)1015,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(ClaimHash =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(ClaimHash)1015\",\"value\":\"t_bool\"},\"t_struct(ClaimData)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.ClaimData\",\"numberOfBytes\":\"96\"},\"t_struct(OutputProposal)1012_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.OutputProposal\",\"numberOfBytes\":\"64\"},\"t_struct(OutputProposals)1013_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.OutputProposals\",\"numberOfBytes\":\"128\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_userDefinedValueType(Claim)1014\":{\"encoding\":\"inplace\",\"label\":\"Claim\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(ClaimHash)1015\":{\"encoding\":\"inplace\",\"label\":\"ClaimHash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Clock)1016\":{\"encoding\":\"inplace\",\"label\":\"Clock\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Hash)1017\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Position)1018\":{\"encoding\":\"inplace\",\"label\":\"Position\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Timestamp)1019\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}" const FaultDisputeGameStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"createdAt\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1017\"},{\"astId\":1001,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"resolvedAt\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1017\"},{\"astId\":1002,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"status\",\"offset\":16,\"slot\":\"0\",\"type\":\"t_enum(GameStatus)1010\"},{\"astId\":1003,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"bondManager\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_contract(IBondManager)1009\"},{\"astId\":1004,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"l1Head\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_userDefinedValueType(Hash)1015\"},{\"astId\":1005,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claimData\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\"},{\"astId\":1006,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claims\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_mapping(t_userDefinedValueType(ClaimHash)1013,t_bool)\"},{\"astId\":1007,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgames\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\"},{\"astId\":1008,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgameAtRootResolved\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_bool\"}],\"types\":{\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct IFaultDisputeGame.ClaimData[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(ClaimData)1011_storage\"},\"t_array(t_uint256)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"uint256[]\",\"numberOfBytes\":\"32\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(IBondManager)1009\":{\"encoding\":\"inplace\",\"label\":\"contract IBondManager\",\"numberOfBytes\":\"20\"},\"t_enum(GameStatus)1010\":{\"encoding\":\"inplace\",\"label\":\"enum GameStatus\",\"numberOfBytes\":\"1\"},\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e uint256[])\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_array(t_uint256)dyn_storage\"},\"t_mapping(t_userDefinedValueType(ClaimHash)1013,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(ClaimHash =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(ClaimHash)1013\",\"value\":\"t_bool\"},\"t_struct(ClaimData)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.ClaimData\",\"numberOfBytes\":\"96\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_userDefinedValueType(Claim)1012\":{\"encoding\":\"inplace\",\"label\":\"Claim\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(ClaimHash)1013\":{\"encoding\":\"inplace\",\"label\":\"ClaimHash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Clock)1014\":{\"encoding\":\"inplace\",\"label\":\"Clock\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Hash)1015\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Position)1016\":{\"encoding\":\"inplace\",\"label\":\"Position\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Timestamp)1017\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}"
var FaultDisputeGameStorageLayout = new(solc.StorageLayout) var FaultDisputeGameStorageLayout = new(solc.StorageLayout)
var FaultDisputeGameDeployedBin = "0x6080604052600436106101b75760003560e01c80638980e0cc116100ec578063c55cd0c71161008a578063d8cc1a3c11610064578063d8cc1a3c146106c1578063e66825b2146106e1578063fa24f74314610701578063fdffbb281461072557600080fd5b8063c55cd0c714610629578063c6f0308c1461063c578063cf09e0d0146106a057600080fd5b8063bbdc02db116100c6578063bbdc02db1461052d578063bcef3b551461056b578063c0c3a092146105a8578063c31b29ce146105dc57600080fd5b80638980e0cc146104a45780638b85902b146104b957806392931298146104f957600080fd5b8063529184c911610159578063609d333411610133578063609d333414610451578063632247ea146104665780636361506d146104795780638129fc1c1461048f57600080fd5b8063529184c91461033757806354fd4d501461036b57806355ef20e6146103c157600080fd5b8063298c900511610195578063298c90051461024f57806335fef5671461028f578063363cc427146102a45780634778efe81461030357600080fd5b8063200d2ed2146101bc578063266198f9146101f85780632810e1d61461023a575b600080fd5b3480156101c857600080fd5b506000546101e29068010000000000000000900460ff1681565b6040516101ef91906122c8565b60405180910390f35b34801561020457600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101ef565b34801561024657600080fd5b506101e2610738565b34801561025b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561022c565b6102a261029d366004612309565b61089c565b005b3480156102b057600080fd5b506000546102de906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ef565b34801561030f57600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034357600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037757600080fd5b506103b46040518060400160405280600681526020017f302e302e3133000000000000000000000000000000000000000000000000000081525081565b6040516101ef9190612396565b3480156103cd57600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff808216845270010000000000000000000000000000000091829004811660208086019190915260045485870152855193840186526005548083168552929092041690820152600654928101929092526104439182565b6040516101ef9291906123b0565b34801561045d57600080fd5b506103b46108ac565b6102a2610474366004612419565b6108ba565b34801561048557600080fd5b5061022c60015481565b34801561049b57600080fd5b506102a2610ed0565b3480156104b057600080fd5b5060025461022c565b3480156104c557600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561022c565b34801561050557600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561053957600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101ef565b34801561057757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561022c565b3480156105b457600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e857600080fd5b506106107f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff90911681526020016101ef565b6102a2610637366004612309565b6114d4565b34801561064857600080fd5b5061065c61065736600461244e565b6114e0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101ef565b3480156106ac57600080fd5b506000546106109067ffffffffffffffff1681565b3480156106cd57600080fd5b506102a26106dc3660046124b0565b611551565b3480156106ed57600080fd5b506102a26106fc36600461253a565b611a7d565b34801561070d57600080fd5b50610716611c42565b6040516101ef93929190612566565b6102a261073336600461244e565b611c9f565b60008060005468010000000000000000900460ff16600281111561075e5761075e612299565b14610795576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460ff166107d1576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000815481106107e5576107e5612591565b6000918252602090912060039091020154640100000000900460ff1661080c57600261080f565b60015b6000805491925082917fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff166801000000000000000083600281111561085657610856612299565b02179055600281111561086b5761086b612299565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b905090565b6108a8828260006108ba565b5050565b606061089760206040611fd1565b6000805468010000000000000000900460ff1660028111156108de576108de612299565b14610915576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610921575080155b15610958576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002848154811061096d5761096d612591565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610a019190859061206816565b90507f0000000000000000000000000000000000000000000000000000000000000000610ac0826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610b02576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610b62576002836000015163ffffffff1681548110610b3157610b31612591565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610b9b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610baf91906125ef565b610bb99190612607565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c2c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42176000888152608086901b6fffffffffffffffffffffffffffffffff8b1617602052604081209192509060008181526007602052604090205490915060ff1615610caa576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b908110610e2257610e22612591565b6000918252602080832060039092029091018054931515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909416939093179092558a8152600890915260409020600254610e8690600190612607565b8154600181018355600092835260208320015560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a6001811480610f10575060ff81166002145b610f76576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600291908101610ffb7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f00642061112460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b815260040161114291815260200190565b602060405180830381865afa15801561115f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611183919061261e565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae5576111ce600185612607565b6040518263ffffffff1660e01b81526004016111ec91815260200190565b606060405180830381865afa158015611209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122d9190612686565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa1580156112be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e29190612686565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b815260040161136e91815260200190565b6040805180830381865afa15801561138a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ae9190612712565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161140d576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081018252908190810180611428600189612607565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b6108a8828260016108ba565b600281815481106114f057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff16600281111561157557611575612299565b146115ac576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106115c1576115c1612591565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506116207f000000000000000000000000000000000000000000000000000000000000000060016125ef565b6116bc826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146116fd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561178057611721836fffffffffffffffffffffffffffffffff16612070565b67ffffffffffffffff16156117545761174b61173e600186612799565b865463ffffffff16612116565b60010154611776565b7f00000000000000000000000000000000000000000000000000000000000000005b915084905061179a565b8460010154915061179784600161173e91906127ca565b90505b600882901b60088a8a6040516117b19291906127fe565b6040518091039020901b146117f2576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e14ced328c8c8c8c60006040518663ffffffff1660e01b815260040161185b959493929190612857565b6020604051808303816000875af115801561187a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189e919061261e565b600284810154929091149250600091611949906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119e5886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119ef9190612891565b6119f991906128b2565b67ffffffffffffffff161590508115158103611a41576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b6000805468010000000000000000900460ff166002811115611aa157611aa1612299565b14611ad8576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190612900565b7f52f0f3ad00000000000000000000000000000000000000000000000000000000601c8190526020869052604085905290915060008560018114611bd55760028114611bdf5760038114611be95760048114611bf35760058114611c035763ff137e656000526004601cfd5b6001549150611c0a565b6004549150611c0a565b6006549150611c0a565b60035460801c60c01b9150611c0a565b4660c01b91505b50606052600160038611811b6005031b60805260a083905260008060a4601c82865af1611c3b573d6000803e3d6000fd5b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611c986108ac565b9050909192565b6000805468010000000000000000900460ff166002811115611cc357611cc3612299565b14611cfa576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611d0f57611d0f612591565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611d7f90700100000000000000000000000000000000900467ffffffffffffffff1642612607565b6002830154611daf9190700100000000000000000000000000000000900460401c67ffffffffffffffff166125ef565b11611de6576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040902082158015611e04575060095460ff165b15611e3b576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e4957508215155b15611e80576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f4e576000838281548110611ea157611ea1612591565b6000918252602080832090910154808352600890915260409091205490915015611ef7576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611f0c57611f0c612591565b600091825260209091206003909102018054909150640100000000900460ff16611f3b57600193505050611f4e565b505080611f4790612936565b9050611e84565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600860205260408120611f979161225f565b83600003611fcb57600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061200884367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036125ef565b90508267ffffffffffffffff1667ffffffffffffffff81111561202d5761202d612637565b6040519080825280601f01601f191660200182016040528015612057576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000806120fd837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080612134846fffffffffffffffffffffffffffffffff166121b3565b90506002838154811061214957612149612591565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146121ac57815460028054909163ffffffff1690811061219757612197612591565b9060005260206000209060030201915061215a565b5092915050565b60008119600183011681612247827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b508054600082559060005260206000209081019061227d9190612280565b50565b5b808211156122955760008155600101612281565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612303577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561231c57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561235157602081850181015186830182015201612335565b81811115612363576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123a9602083018461232b565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c081016123a9565b8035801515811461241457600080fd5b919050565b60008060006060848603121561242e57600080fd5b833592506020840135915061244560408501612404565b90509250925092565b60006020828403121561246057600080fd5b5035919050565b60008083601f84011261247957600080fd5b50813567ffffffffffffffff81111561249157600080fd5b6020830191508360208285010111156124a957600080fd5b9250929050565b600080600080600080608087890312156124c957600080fd5b863595506124d960208801612404565b9450604087013567ffffffffffffffff808211156124f657600080fd5b6125028a838b01612467565b9096509450606089013591508082111561251b57600080fd5b5061252889828a01612467565b979a9699509497509295939492505050565b60008060006060848603121561254f57600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612588606083018461232b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612602576126026125c0565b500190565b600082821015612619576126196125c0565b500390565b60006020828403121561263057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff8116811461241457600080fd5b60006060828403121561269857600080fd5b6040516060810181811067ffffffffffffffff821117156126e2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052825181526126f560208401612666565b602082015261270660408401612666565b60408201529392505050565b60006040828403121561272457600080fd5b6040516040810167ffffffffffffffff828210818311171561276f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b816040528451835260208501519150808216821461278c57600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156127c2576127c26125c0565b039392505050565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156127f5576127f56125c0565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60608152600061286b60608301878961280e565b828103602084015261287e81868861280e565b9150508260408301529695505050505050565b600067ffffffffffffffff838116908316818110156127c2576127c26125c0565b600067ffffffffffffffff808416806128f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910692915050565b60006020828403121561291257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146123a957600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612967576129676125c0565b506001019056fea164736f6c634300080f000a" var FaultDisputeGameDeployedBin = "0x6080604052600436106101b75760003560e01c80638b85902b116100ec578063d8cc1a3c1161008a578063f8f43ff611610064578063f8f43ff61461062b578063fa24f7431461064b578063fa315aa91461066f578063fdffbb28146106a257600080fd5b8063d8cc1a3c146105a5578063e1f0c376146105c5578063ec5e6308146105f857600080fd5b8063bcef3b55116100c6578063bcef3b55146104d0578063c55cd0c71461050d578063c6f0308c14610520578063cf09e0d01461058457600080fd5b80638b85902b1461041f5780638d450a951461045f578063bbdc02db1461049257600080fd5b806354fd4d50116101595780636361506d116101335780636361506d146103ac57806368800abf146103c25780638129fc1c146103f55780638980e0cc1461040a57600080fd5b806354fd4d501461032e578063609d333414610384578063632247ea1461039957600080fd5b80632810e1d6116101955780632810e1d61461027f57806335fef56714610294578063363cc427146102a95780633a768463146102fb57600080fd5b80630356fe3a146101bc57806319effeb4146101fe578063200d2ed214610244575b600080fd5b3480156101c857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561020a57600080fd5b5060005461022b9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101f5565b34801561025057600080fd5b5060005461027290700100000000000000000000000000000000900460ff1681565b6040516101f59190612ce5565b34801561028b57600080fd5b506102726106b5565b6102a76102a2366004612d26565b610886565b005b3480156102b557600080fd5b506001546102d69073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f5565b34801561030757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102d6565b34801561033a57600080fd5b506103776040518060400160405280600681526020017f302e302e3139000000000000000000000000000000000000000000000000000081525081565b6040516101f59190612db3565b34801561039057600080fd5b50610377610896565b6102a76103a7366004612ddb565b6108a8565b3480156103b857600080fd5b506101eb60025481565b3480156103ce57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561040157600080fd5b506102a7610f58565b34801561041657600080fd5b506003546101eb565b34801561042b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101eb565b34801561046b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561049e57600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f5565b3480156104dc57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101eb565b6102a761051b366004612d26565b61116e565b34801561052c57600080fd5b5061054061053b366004612e10565b61117a565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101f5565b34801561059057600080fd5b5060005461022b9067ffffffffffffffff1681565b3480156105b157600080fd5b506102a76105c0366004612e72565b6111eb565b3480156105d157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061022b565b34801561060457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561063757600080fd5b506102a7610646366004612efc565b611786565b34801561065757600080fd5b50610660611c7b565b6040516101f593929190612f28565b34801561067b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b6102a76106b0366004612e10565b611cd8565b600080600054700100000000000000000000000000000000900460ff1660028111156106e3576106e3612cb6565b1461071a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065460ff16610756576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600360008154811061076a5761076a612f53565b6000918252602090912060039091020154640100000000900460ff16610791576002610794565b60015b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561084557610845612cb6565b02179055600281111561085a5761085a612cb6565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610892828260006108a8565b5050565b60606108a3602080612012565b905090565b60008054700100000000000000000000000000000000900460ff1660028111156108d4576108d4612cb6565b1461090b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003848154811061092057610920612f53565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff808216606085018190527001000000000000000000000000000000009092041660808401529193509091906109b890839086906120a916565b90506000610a58826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610a9a5750610a977f00000000000000000000000000000000000000000000000000000000000000006002612fb1565b81145b8015610aa4575084155b15610adb576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610b35576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b607f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8103610b7257610b72868885886120b1565b835160009063ffffffff90811614610bd2576003856000015163ffffffff1681548110610ba157610ba1612f53565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608085015160009067ffffffffffffffff1667ffffffffffffffff1642610c0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610c1f9190612fb1565b610c299190612fc9565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c9c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615610d1a576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060036040518060a001604052808d63ffffffff1681526020016000151581526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548160ff0219169083151502179055506040820151816001015560608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160020160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600160038c81548110610eab57610eab612f53565b600091825260208083206003928302018054941515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909516949094179093558d82526005909252604090209054610f0c90600190612fc9565b8154600181018355600092835260208320015560405133918c918e917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a45050505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001351161100f576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff16179055604636111561105a5763c407e0256000526004601cfd5b6040805160a08101825263ffffffff8152600060208201526003918101367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff90931692909217949094178155604083015181850155606083015160809093015182167001000000000000000000000000000000000292909116919091176002909101556111689043612fc9565b40600255565b610892828260016108a8565b6003818154811061118a57600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b60008054700100000000000000000000000000000000900460ff16600281111561121757611217612cb6565b1461124e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003878154811061126357611263612f53565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112c27f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b61135e826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161461139f576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561147c576113f27f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612fc9565b6001901b611411846fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16611425919061300f565b1561145057611447611438600186613023565b865463ffffffff166000612304565b60010154611472565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611496565b846001015491506114938460016114389190613054565b90505b600882901b60088a8a6040516114ad929190613088565b6040518091039020901b146114ee576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114f98c6123e8565b9050600082600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e14ced328d8d8d8d886040518663ffffffff1660e01b81526004016115639594939291906130e1565b6020604051808303816000875af1158015611582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a6919061311b565b600285810154929091149250600091611651906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116ed896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116f79190613134565b6117019190613155565b67ffffffffffffffff161590508115158103611749576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156117b2576117b2612cb6565b146117e9576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806117f886612417565b9350935093509350600061180e858585856127e4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561187d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a1919061317c565b905060018903611963576002546040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018b9052602481018490526044810191909152602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4015b6020604051808303816000875af1158015611939573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195d919061311b565b50611c70565b600289036119da576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101879052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60038903611a51576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101859052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60048903611bc55760006fffffffffffffffffffffffffffffffff861615611ae957611aaf6fffffffffffffffffffffffffffffffff87167f00000000000000000000000000000000000000000000000000000000000000006128a4565b611ad9907f0000000000000000000000000000000000000000000000000000000000000000612fb1565b611ae4906001612fb1565b611b0b565b7f00000000000000000000000000000000000000000000000000000000000000005b6040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018c90526024810185905260c082901b604482015260086064820152608481018a905290915073ffffffffffffffffffffffffffffffffffffffff8316906352f0f3ad9060a4016020604051808303816000875af1158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe919061311b565b5050611c70565b60058903611c3e576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390524660c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611cd1610896565b9050909192565b60008054700100000000000000000000000000000000900460ff166002811115611d0457611d04612cb6565b14611d3b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611d5057611d50612f53565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611dc090700100000000000000000000000000000000900467ffffffffffffffff1642612fc9565b6002830154611df09190700100000000000000000000000000000000900460401c67ffffffffffffffff16612fb1565b11611e27576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260056020526040902082158015611e45575060065460ff165b15611e7c576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e8a57508215155b15611ec1576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f8f576000838281548110611ee257611ee2612f53565b6000918252602080832090910154808352600590915260409091205490915015611f38576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611f4d57611f4d612f53565b600091825260209091206003909102018054909150640100000000900460ff16611f7c57600193505050611f8f565b505080611f88906131b9565b9050611ec5565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600560205260408120611fd891612c7c565b8360000361200c57600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061204984367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003612fb1565b90508267ffffffffffffffff1667ffffffffffffffff81111561206e5761206e6131f1565b6040519080825280601f01601f191660200182016040528015612098576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60006120be836001613054565b905060006120ce82866001612304565b9050600086901a83806121bf575061210760027f000000000000000000000000000000000000000000000000000000000000000061300f565b6002838101546121a9906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121b39190613155565b67ffffffffffffffff16145b156122175760ff8116600114806121d9575060ff81166002145b612212576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b612255565b60ff811615612255576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b50505050505050565b6000806122eb837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261234d576123486fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000612959565b612368565b612368856fffffffffffffffffffffffffffffffff16612b20565b90506003848154811061237d5761237d612f53565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146123e057815460038054909163ffffffff169081106123cb576123cb612f53565b9060005260206000209060030201915061238e565b509392505050565b60008060008060006123f986612417565b935093509350935061240d848484846127e4565b9695505050505050565b600080600080600085905060006003828154811061243757612437612f53565b600091825260209091206002600390920201908101549091507f00000000000000000000000000000000000000000000000000000000000000009061250e906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161254f576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60028301547f000000000000000000000000000000000000000000000000000000000000000090612616906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16925082111561269257825463ffffffff1661265c7f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8303612666578391505b6003818154811061267957612679612f53565b9060005260206000209060030201935080945050612553565b600280820154908401546fffffffffffffffffffffffffffffffff91821691166000816126bf8460011c90565b6fffffffffffffffffffffffffffffffff1614905080156127925760006126f7836fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16111561274857600061271f612717600185613023565b896001612304565b6001810154600290910154909c506fffffffffffffffffffffffffffffffff169a5061276c9050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600186015460028701549099506fffffffffffffffffffffffffffffffff1697506127d6565b60006127a2612717846001613054565b6001808901546002808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b6000836fffffffffffffffffffffffffffffffff1660000361284b57828260405160200161282e9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b60405160208183030381529060405280519060200120905061289c565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080612931847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b6000816129f8846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612a39576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a4283612b20565b905081612ae1826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612b1a57612b17612afe836001612fb1565b6fffffffffffffffffffffffffffffffff831690612bcc565b90505b92915050565b60008119600183011681612bb4827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080612c59847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190612c9a9190612c9d565b50565b5b80821115612cb25760008155600101612c9e565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612d20577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215612d3957600080fd5b50508035926020909101359150565b6000815180845260005b81811015612d6e57602081850181015186830182015201612d52565b81811115612d80576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612b176020830184612d48565b80358015158114612dd657600080fd5b919050565b600080600060608486031215612df057600080fd5b8335925060208401359150612e0760408501612dc6565b90509250925092565b600060208284031215612e2257600080fd5b5035919050565b60008083601f840112612e3b57600080fd5b50813567ffffffffffffffff811115612e5357600080fd5b602083019150836020828501011115612e6b57600080fd5b9250929050565b60008060008060008060808789031215612e8b57600080fd5b86359550612e9b60208801612dc6565b9450604087013567ffffffffffffffff80821115612eb857600080fd5b612ec48a838b01612e29565b90965094506060890135915080821115612edd57600080fd5b50612eea89828a01612e29565b979a9699509497509295939492505050565b600080600060608486031215612f1157600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612f4a6060830184612d48565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612fc457612fc4612f82565b500190565b600082821015612fdb57612fdb612f82565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261301e5761301e612fe0565b500690565b60006fffffffffffffffffffffffffffffffff8381169083168181101561304c5761304c612f82565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561307f5761307f612f82565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006130f5606083018789613098565b8281036020840152613108818688613098565b9150508260408301529695505050505050565b60006020828403121561312d57600080fd5b5051919050565b600067ffffffffffffffff8381169083168181101561304c5761304c612f82565b600067ffffffffffffffff8084168061317057613170612fe0565b92169190910692915050565b60006020828403121561318e57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146131b257600080fd5b9392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036131ea576131ea612f82565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c634300080f000a"
func init() { func init() {
......
...@@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) ...@@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout)
var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063e14ced32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063e14ced32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"
var MIPSDeployedSourceMap = "1131:40054:142:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:324;176:23;;;158:42;;146:2;131:18;1710:45:142;;;;;;;;2448:99;;;412:42:324;2534:6:142;400:55:324;382:74;;370:2;355:18;2448:99:142;211:251:324;26025:6379:142;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:324;;;1743:2;1728:18;26025:6379:142;1609:177:324;26025:6379:142;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:142;;-1:-1:-1;28593:7:142;:20::i;:::-;28579:34;-1:-1:-1;28643:10:142;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:142;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:142;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:142;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:142;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:142;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:142:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:142;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:142;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:142:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:324;19164:28:142;;;2164:21:324;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:142;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:142;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:324;14107:30:142;;;2511:21:324;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:142;2327:344:324;14055:97:142;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:142:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:142;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:142;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:142;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:142;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:142;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:142;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:142;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:142;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:142;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:142;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:142;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:142;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:324;37406:29:142;;;2860:21:324;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:142;2676:343:324;37297:157:142;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:142;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:142;;-1:-1:-1;;38164:8:142;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:142;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:142;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:142;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:142;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:142;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:142;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:142;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:142;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:324;20288:41:142;;;3208:21:324;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:142;3024:338:324;20288:41:142;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:142;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:142;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:142:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:142;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:143;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:142;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:324;;;8234:54:142;3601:23:324;;;3581:18;;;3574:51;8203:11:142;;;;8234:19;:6;:19;;;;3513:18:324;;8234:54:142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:142;;-1:-1:-1;;;7642:2553:142;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:142;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:142;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:142;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:142;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:142;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:142;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:142;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:142;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:142;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:142;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:142;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:142;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:142;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:142:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:142;25120:9;25084:343;;;-1:-1:-1;;25526:4:142;25519:18;-1:-1:-1;;;;23913:1654:142:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:324;21415:72:142;;;4259:21:324;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:142;4075:399:324;21415:72:142;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:324:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:324;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:324;-1:-1:-1;1349:2:324;1334:18;;1321:32;;-1:-1:-1;1365:16:324;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:324;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:324:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:324;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:324:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" var MIPSDeployedSourceMap = "1131:40054:142:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:321;176:23;;;158:42;;146:2;131:18;1710:45:142;;;;;;;;2448:99;;;412:42:321;2534:6:142;400:55:321;382:74;;370:2;355:18;2448:99:142;211:251:321;26025:6379:142;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:321;;;1743:2;1728:18;26025:6379:142;1609:177:321;26025:6379:142;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:142;;-1:-1:-1;28593:7:142;:20::i;:::-;28579:34;-1:-1:-1;28643:10:142;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:142;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:142;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:142;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:142;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:142;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:142:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:142;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:142;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:142:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:321;19164:28:142;;;2164:21:321;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:142;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:142;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:321;14107:30:142;;;2511:21:321;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:142;2327:344:321;14055:97:142;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:142:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:142;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:142;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:142;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:142;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:142;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:142;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:142;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:142;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:142;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:142;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:142;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:142;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:321;37406:29:142;;;2860:21:321;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:142;2676:343:321;37297:157:142;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:142;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:142;;-1:-1:-1;;38164:8:142;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:142;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:142;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:142;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:142;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:142;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:142;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:142;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:142;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:321;20288:41:142;;;3208:21:321;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:142;3024:338:321;20288:41:142;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:142;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:142;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:142:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:142;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:143;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:142;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:321;;;8234:54:142;3601:23:321;;;3581:18;;;3574:51;8203:11:142;;;;8234:19;:6;:19;;;;3513:18:321;;8234:54:142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:142;;-1:-1:-1;;;7642:2553:142;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:142;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:142;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:142;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:142;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:142;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:142;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:142;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:142;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:142;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:142;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:142;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:142;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:142;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:142:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:142;25120:9;25084:343;;;-1:-1:-1;;25526:4:142;25519:18;-1:-1:-1;;;;23913:1654:142:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:321;21415:72:142;;;4259:21:321;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:142;4075:399:321;21415:72:142;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:321:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:321;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:321;-1:-1:-1;1349:2:321;1334:18;;1321:32;;-1:-1:-1;1365:16:321;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:321;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:321:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:321;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:321:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15"
func init() { func init() {
......
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
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
)
// OutputBisectionGameMetaData contains all meta data concerning the OutputBisectionGame contract.
var OutputBisectionGameMetaData = &bind.MetaData{
ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint8\",\"internalType\":\"GameType\"},{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_genesisBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_genesisOutputRoot\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"_maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_splitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gameDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"_vm\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"absolutePrestate\",\"inputs\":[],\"outputs\":[{\"name\":\"absolutePrestate_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addLocalData\",\"inputs\":[{\"name\":\"_ident\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_execLeafIdx\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"attack\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bondManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBondManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimData\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"parentIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"countered\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"position\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"clock\",\"type\":\"uint128\",\"internalType\":\"Clock\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDataLen\",\"inputs\":[],\"outputs\":[{\"name\":\"len_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createdAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"defend\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"extraData\",\"inputs\":[],\"outputs\":[{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"gameData\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint8\",\"internalType\":\"GameType\"},{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameDuration\",\"inputs\":[],\"outputs\":[{\"name\":\"gameDuration_\",\"type\":\"uint64\",\"internalType\":\"Duration\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameType\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint8\",\"internalType\":\"GameType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisBlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisOutputRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisOutputRoot_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1Head\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"l2BlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"maxGameDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"maxGameDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"move\",\"inputs\":[{\"name\":\"_challengeIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[],\"outputs\":[{\"name\":\"status_\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolveClaim\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolvedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rootClaim\",\"inputs\":[],\"outputs\":[{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"splitDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"splitDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"status\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"vm\",\"inputs\":[],\"outputs\":[{\"name\":\"vm_\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Move\",\"inputs\":[{\"name\":\"parentIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Claim\"},{\"name\":\"claimant\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Resolved\",\"inputs\":[{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumGameStatus\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"CannotDefendRootClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAboveSplit\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyResolved\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockNotExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockTimeExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameDepthExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameNotInProgress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidLocalIdent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidParent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPrestate\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSplitDepth\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OutOfOrderResolution\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UnexpectedRootClaim\",\"inputs\":[{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]},{\"type\":\"error\",\"name\":\"ValidStep\",\"inputs\":[]}]",
Bin: "0x6101806040523480156200001257600080fd5b506040516200346738038062003467833981016040819052620000359162000098565b838310620000565760405163e62ccf3960e01b815260040160405180910390fd5b60ff90971661016052608095909552610120939093526101409190915260a05260c0526001600160401b031660e0526001600160a01b0316610100526200013a565b600080600080600080600080610100898b031215620000b657600080fd5b885160ff81168114620000c857600080fd5b60208a015160408b015160608c015160808d015160a08e015160c08f0151959d50939b509199509750955093506001600160401b03811681146200010b57600080fd5b60e08a01519092506001600160a01b03811681146200012957600080fd5b809150509295985092959890939650565b60805160a05160c05160e0516101005161012051610140516101605161322d6200023a600039600081816104a60152611c7d0152600081816103d1015261274a0152600081816101cb01528181610f5a01528181611ab50152611aeb01526000818161030a0152818161150401526118140152600081816105d401528181610c360152611d7401526000818161060701528181610a7101528181610b3a015281816113ad01528181611a8b015281816120e301528181612324015281816124520152818161255a015261263601526000818161067e01528181610add0152818161129c01526113ce01526000818161046e0152611452015261322d6000f3fe6080604052600436106101b75760003560e01c80638b85902b116100ec578063d8cc1a3c1161008a578063f8f43ff611610064578063f8f43ff61461062b578063fa24f7431461064b578063fa315aa91461066f578063fdffbb28146106a257600080fd5b8063d8cc1a3c146105a5578063e1f0c376146105c5578063ec5e6308146105f857600080fd5b8063bcef3b55116100c6578063bcef3b55146104d0578063c55cd0c71461050d578063c6f0308c14610520578063cf09e0d01461058457600080fd5b80638b85902b1461041f5780638d450a951461045f578063bbdc02db1461049257600080fd5b806354fd4d50116101595780636361506d116101335780636361506d146103ac57806368800abf146103c25780638129fc1c146103f55780638980e0cc1461040a57600080fd5b806354fd4d501461032e578063609d333414610384578063632247ea1461039957600080fd5b80632810e1d6116101955780632810e1d61461027f57806335fef56714610294578063363cc427146102a95780633a768463146102fb57600080fd5b80630356fe3a146101bc57806319effeb4146101fe578063200d2ed214610244575b600080fd5b3480156101c857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561020a57600080fd5b5060005461022b9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101f5565b34801561025057600080fd5b5060005461027290700100000000000000000000000000000000900460ff1681565b6040516101f59190612ce5565b34801561028b57600080fd5b506102726106b5565b6102a76102a2366004612d26565b610886565b005b3480156102b557600080fd5b506001546102d69073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f5565b34801561030757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102d6565b34801561033a57600080fd5b506103776040518060400160405280600681526020017f302e302e3138000000000000000000000000000000000000000000000000000081525081565b6040516101f59190612db3565b34801561039057600080fd5b50610377610896565b6102a76103a7366004612ddb565b6108a8565b3480156103b857600080fd5b506101eb60025481565b3480156103ce57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561040157600080fd5b506102a7610f58565b34801561041657600080fd5b506003546101eb565b34801561042b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101eb565b34801561046b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561049e57600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f5565b3480156104dc57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101eb565b6102a761051b366004612d26565b61116e565b34801561052c57600080fd5b5061054061053b366004612e10565b61117a565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101f5565b34801561059057600080fd5b5060005461022b9067ffffffffffffffff1681565b3480156105b157600080fd5b506102a76105c0366004612e72565b6111eb565b3480156105d157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061022b565b34801561060457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561063757600080fd5b506102a7610646366004612efc565b611786565b34801561065757600080fd5b50610660611c7b565b6040516101f593929190612f28565b34801561067b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b6102a76106b0366004612e10565b611cd8565b600080600054700100000000000000000000000000000000900460ff1660028111156106e3576106e3612cb6565b1461071a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065460ff16610756576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600360008154811061076a5761076a612f53565b6000918252602090912060039091020154640100000000900460ff16610791576002610794565b60015b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561084557610845612cb6565b02179055600281111561085a5761085a612cb6565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610892828260006108a8565b5050565b60606108a3602080612012565b905090565b60008054700100000000000000000000000000000000900460ff1660028111156108d4576108d4612cb6565b1461090b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003848154811061092057610920612f53565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff808216606085018190527001000000000000000000000000000000009092041660808401529193509091906109b890839086906120a916565b90506000610a58826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610a9a5750610a977f00000000000000000000000000000000000000000000000000000000000000006002612fb1565b81145b8015610aa4575084155b15610adb576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610b35576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b607f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8103610b7257610b72868885886120b1565b835160009063ffffffff90811614610bd2576003856000015163ffffffff1681548110610ba157610ba1612f53565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608085015160009067ffffffffffffffff1667ffffffffffffffff1642610c0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610c1f9190612fb1565b610c299190612fc9565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c9c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615610d1a576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060036040518060a001604052808d63ffffffff1681526020016000151581526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548160ff0219169083151502179055506040820151816001015560608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160020160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600160038c81548110610eab57610eab612f53565b600091825260208083206003928302018054941515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909516949094179093558d82526005909252604090209054610f0c90600190612fc9565b8154600181018355600092835260208320015560405133918c918e917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a45050505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001351161100f576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff16179055604636111561105a5763c407e0256000526004601cfd5b6040805160a08101825263ffffffff8152600060208201526003918101367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff90931692909217949094178155604083015181850155606083015160809093015182167001000000000000000000000000000000000292909116919091176002909101556111689043612fc9565b40600255565b610892828260016108a8565b6003818154811061118a57600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b60008054700100000000000000000000000000000000900460ff16600281111561121757611217612cb6565b1461124e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003878154811061126357611263612f53565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112c27f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b61135e826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161461139f576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561147c576113f27f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612fc9565b6001901b611411846fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16611425919061300f565b1561145057611447611438600186613023565b865463ffffffff166000612304565b60010154611472565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611496565b846001015491506114938460016114389190613054565b90505b600882901b60088a8a6040516114ad929190613088565b6040518091039020901b146114ee576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114f98c6123e8565b9050600082600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e14ced328d8d8d8d886040518663ffffffff1660e01b81526004016115639594939291906130e1565b6020604051808303816000875af1158015611582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a6919061311b565b600285810154929091149250600091611651906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116ed896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116f79190613134565b6117019190613155565b67ffffffffffffffff161590508115158103611749576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156117b2576117b2612cb6565b146117e9576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806117f886612417565b9350935093509350600061180e858585856127e4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561187d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a1919061317c565b905060018903611963576002546040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018b9052602481018490526044810191909152602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4015b6020604051808303816000875af1158015611939573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195d919061311b565b50611c70565b600289036119da576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101879052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60038903611a51576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101859052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60048903611bc55760006fffffffffffffffffffffffffffffffff861615611ae957611aaf6fffffffffffffffffffffffffffffffff87167f00000000000000000000000000000000000000000000000000000000000000006128a4565b611ad9907f0000000000000000000000000000000000000000000000000000000000000000612fb1565b611ae4906001612fb1565b611b0b565b7f00000000000000000000000000000000000000000000000000000000000000005b6040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018c90526024810185905260c082901b604482015260086064820152608481018a905290915073ffffffffffffffffffffffffffffffffffffffff8316906352f0f3ad9060a4016020604051808303816000875af1158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe919061311b565b5050611c70565b60058903611c3e576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390524660c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611cd1610896565b9050909192565b60008054700100000000000000000000000000000000900460ff166002811115611d0457611d04612cb6565b14611d3b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611d5057611d50612f53565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611dc090700100000000000000000000000000000000900467ffffffffffffffff1642612fc9565b6002830154611df09190700100000000000000000000000000000000900460401c67ffffffffffffffff16612fb1565b11611e27576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260056020526040902082158015611e45575060065460ff165b15611e7c576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e8a57508215155b15611ec1576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f8f576000838281548110611ee257611ee2612f53565b6000918252602080832090910154808352600590915260409091205490915015611f38576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611f4d57611f4d612f53565b600091825260209091206003909102018054909150640100000000900460ff16611f7c57600193505050611f8f565b505080611f88906131b9565b9050611ec5565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600560205260408120611fd891612c7c565b8360000361200c57600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061204984367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003612fb1565b90508267ffffffffffffffff1667ffffffffffffffff81111561206e5761206e6131f1565b6040519080825280601f01601f191660200182016040528015612098576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60006120be836001613054565b905060006120ce82866001612304565b9050600086901a83806121bf575061210760027f000000000000000000000000000000000000000000000000000000000000000061300f565b6002838101546121a9906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121b39190613155565b67ffffffffffffffff16145b156122175760ff8116600114806121d9575060ff81166002145b612212576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b612255565b60ff811615612255576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b50505050505050565b6000806122eb837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261234d576123486fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000612959565b612368565b612368856fffffffffffffffffffffffffffffffff16612b20565b90506003848154811061237d5761237d612f53565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146123e057815460038054909163ffffffff169081106123cb576123cb612f53565b9060005260206000209060030201915061238e565b509392505050565b60008060008060006123f986612417565b935093509350935061240d848484846127e4565b9695505050505050565b600080600080600085905060006003828154811061243757612437612f53565b600091825260209091206002600390920201908101549091507f00000000000000000000000000000000000000000000000000000000000000009061250e906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161254f576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60028301547f000000000000000000000000000000000000000000000000000000000000000090612616906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16925082111561269257825463ffffffff1661265c7f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8303612666578391505b6003818154811061267957612679612f53565b9060005260206000209060030201935080945050612553565b600280820154908401546fffffffffffffffffffffffffffffffff91821691166000816126bf8460011c90565b6fffffffffffffffffffffffffffffffff1614905080156127925760006126f7836fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16111561274857600061271f612717600185613023565b896001612304565b6001810154600290910154909c506fffffffffffffffffffffffffffffffff169a5061276c9050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600186015460028701549099506fffffffffffffffffffffffffffffffff1697506127d6565b60006127a2612717846001613054565b6001808901546002808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b6000836fffffffffffffffffffffffffffffffff1660000361284b57828260405160200161282e9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b60405160208183030381529060405280519060200120905061289c565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080612931847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b6000816129f8846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612a39576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a4283612b20565b905081612ae1826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612b1a57612b17612afe836001612fb1565b6fffffffffffffffffffffffffffffffff831690612bcc565b90505b92915050565b60008119600183011681612bb4827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080612c59847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190612c9a9190612c9d565b50565b5b80821115612cb25760008155600101612c9e565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612d20577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215612d3957600080fd5b50508035926020909101359150565b6000815180845260005b81811015612d6e57602081850181015186830182015201612d52565b81811115612d80576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612b176020830184612d48565b80358015158114612dd657600080fd5b919050565b600080600060608486031215612df057600080fd5b8335925060208401359150612e0760408501612dc6565b90509250925092565b600060208284031215612e2257600080fd5b5035919050565b60008083601f840112612e3b57600080fd5b50813567ffffffffffffffff811115612e5357600080fd5b602083019150836020828501011115612e6b57600080fd5b9250929050565b60008060008060008060808789031215612e8b57600080fd5b86359550612e9b60208801612dc6565b9450604087013567ffffffffffffffff80821115612eb857600080fd5b612ec48a838b01612e29565b90965094506060890135915080821115612edd57600080fd5b50612eea89828a01612e29565b979a9699509497509295939492505050565b600080600060608486031215612f1157600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612f4a6060830184612d48565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612fc457612fc4612f82565b500190565b600082821015612fdb57612fdb612f82565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261301e5761301e612fe0565b500690565b60006fffffffffffffffffffffffffffffffff8381169083168181101561304c5761304c612f82565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561307f5761307f612f82565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006130f5606083018789613098565b8281036020840152613108818688613098565b9150508260408301529695505050505050565b60006020828403121561312d57600080fd5b5051919050565b600067ffffffffffffffff8381169083168181101561304c5761304c612f82565b600067ffffffffffffffff8084168061317057613170612fe0565b92169190910692915050565b60006020828403121561318e57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146131b257600080fd5b9392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036131ea576131ea612f82565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c634300080f000a",
}
// OutputBisectionGameABI is the input ABI used to generate the binding from.
// Deprecated: Use OutputBisectionGameMetaData.ABI instead.
var OutputBisectionGameABI = OutputBisectionGameMetaData.ABI
// OutputBisectionGameBin is the compiled bytecode used for deploying new contracts.
// Deprecated: Use OutputBisectionGameMetaData.Bin instead.
var OutputBisectionGameBin = OutputBisectionGameMetaData.Bin
// DeployOutputBisectionGame deploys a new Ethereum contract, binding an instance of OutputBisectionGame to it.
func DeployOutputBisectionGame(auth *bind.TransactOpts, backend bind.ContractBackend, _gameType uint8, _absolutePrestate [32]byte, _genesisBlockNumber *big.Int, _genesisOutputRoot [32]byte, _maxGameDepth *big.Int, _splitDepth *big.Int, _gameDuration uint64, _vm common.Address) (common.Address, *types.Transaction, *OutputBisectionGame, error) {
parsed, err := OutputBisectionGameMetaData.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(OutputBisectionGameBin), backend, _gameType, _absolutePrestate, _genesisBlockNumber, _genesisOutputRoot, _maxGameDepth, _splitDepth, _gameDuration, _vm)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &OutputBisectionGame{OutputBisectionGameCaller: OutputBisectionGameCaller{contract: contract}, OutputBisectionGameTransactor: OutputBisectionGameTransactor{contract: contract}, OutputBisectionGameFilterer: OutputBisectionGameFilterer{contract: contract}}, nil
}
// OutputBisectionGame is an auto generated Go binding around an Ethereum contract.
type OutputBisectionGame struct {
OutputBisectionGameCaller // Read-only binding to the contract
OutputBisectionGameTransactor // Write-only binding to the contract
OutputBisectionGameFilterer // Log filterer for contract events
}
// OutputBisectionGameCaller is an auto generated read-only Go binding around an Ethereum contract.
type OutputBisectionGameCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// OutputBisectionGameTransactor is an auto generated write-only Go binding around an Ethereum contract.
type OutputBisectionGameTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// OutputBisectionGameFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type OutputBisectionGameFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// OutputBisectionGameSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type OutputBisectionGameSession struct {
Contract *OutputBisectionGame // 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
}
// OutputBisectionGameCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type OutputBisectionGameCallerSession struct {
Contract *OutputBisectionGameCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// OutputBisectionGameTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type OutputBisectionGameTransactorSession struct {
Contract *OutputBisectionGameTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// OutputBisectionGameRaw is an auto generated low-level Go binding around an Ethereum contract.
type OutputBisectionGameRaw struct {
Contract *OutputBisectionGame // Generic contract binding to access the raw methods on
}
// OutputBisectionGameCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type OutputBisectionGameCallerRaw struct {
Contract *OutputBisectionGameCaller // Generic read-only contract binding to access the raw methods on
}
// OutputBisectionGameTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type OutputBisectionGameTransactorRaw struct {
Contract *OutputBisectionGameTransactor // Generic write-only contract binding to access the raw methods on
}
// NewOutputBisectionGame creates a new instance of OutputBisectionGame, bound to a specific deployed contract.
func NewOutputBisectionGame(address common.Address, backend bind.ContractBackend) (*OutputBisectionGame, error) {
contract, err := bindOutputBisectionGame(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &OutputBisectionGame{OutputBisectionGameCaller: OutputBisectionGameCaller{contract: contract}, OutputBisectionGameTransactor: OutputBisectionGameTransactor{contract: contract}, OutputBisectionGameFilterer: OutputBisectionGameFilterer{contract: contract}}, nil
}
// NewOutputBisectionGameCaller creates a new read-only instance of OutputBisectionGame, bound to a specific deployed contract.
func NewOutputBisectionGameCaller(address common.Address, caller bind.ContractCaller) (*OutputBisectionGameCaller, error) {
contract, err := bindOutputBisectionGame(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &OutputBisectionGameCaller{contract: contract}, nil
}
// NewOutputBisectionGameTransactor creates a new write-only instance of OutputBisectionGame, bound to a specific deployed contract.
func NewOutputBisectionGameTransactor(address common.Address, transactor bind.ContractTransactor) (*OutputBisectionGameTransactor, error) {
contract, err := bindOutputBisectionGame(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &OutputBisectionGameTransactor{contract: contract}, nil
}
// NewOutputBisectionGameFilterer creates a new log filterer instance of OutputBisectionGame, bound to a specific deployed contract.
func NewOutputBisectionGameFilterer(address common.Address, filterer bind.ContractFilterer) (*OutputBisectionGameFilterer, error) {
contract, err := bindOutputBisectionGame(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &OutputBisectionGameFilterer{contract: contract}, nil
}
// bindOutputBisectionGame binds a generic wrapper to an already deployed contract.
func bindOutputBisectionGame(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(OutputBisectionGameABI))
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 (_OutputBisectionGame *OutputBisectionGameRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _OutputBisectionGame.Contract.OutputBisectionGameCaller.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 (_OutputBisectionGame *OutputBisectionGameRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.OutputBisectionGameTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_OutputBisectionGame *OutputBisectionGameRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.OutputBisectionGameTransactor.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 (_OutputBisectionGame *OutputBisectionGameCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _OutputBisectionGame.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 (_OutputBisectionGame *OutputBisectionGameTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_OutputBisectionGame *OutputBisectionGameTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.contract.Transact(opts, method, params...)
}
// AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95.
//
// Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_)
func (_OutputBisectionGame *OutputBisectionGameCaller) AbsolutePrestate(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "absolutePrestate")
if err != nil {
return *new([32]byte), err
}
out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
return out0, err
}
// AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95.
//
// Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_)
func (_OutputBisectionGame *OutputBisectionGameSession) AbsolutePrestate() ([32]byte, error) {
return _OutputBisectionGame.Contract.AbsolutePrestate(&_OutputBisectionGame.CallOpts)
}
// AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95.
//
// Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) AbsolutePrestate() ([32]byte, error) {
return _OutputBisectionGame.Contract.AbsolutePrestate(&_OutputBisectionGame.CallOpts)
}
// BondManager is a free data retrieval call binding the contract method 0x363cc427.
//
// Solidity: function bondManager() view returns(address)
func (_OutputBisectionGame *OutputBisectionGameCaller) BondManager(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "bondManager")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// BondManager is a free data retrieval call binding the contract method 0x363cc427.
//
// Solidity: function bondManager() view returns(address)
func (_OutputBisectionGame *OutputBisectionGameSession) BondManager() (common.Address, error) {
return _OutputBisectionGame.Contract.BondManager(&_OutputBisectionGame.CallOpts)
}
// BondManager is a free data retrieval call binding the contract method 0x363cc427.
//
// Solidity: function bondManager() view returns(address)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) BondManager() (common.Address, error) {
return _OutputBisectionGame.Contract.BondManager(&_OutputBisectionGame.CallOpts)
}
// ClaimData is a free data retrieval call binding the contract method 0xc6f0308c.
//
// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock)
func (_OutputBisectionGame *OutputBisectionGameCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "claimData", arg0)
outstruct := new(struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
})
if err != nil {
return *outstruct, err
}
outstruct.ParentIndex = *abi.ConvertType(out[0], new(uint32)).(*uint32)
outstruct.Countered = *abi.ConvertType(out[1], new(bool)).(*bool)
outstruct.Claim = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte)
outstruct.Position = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int)
outstruct.Clock = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
return *outstruct, err
}
// ClaimData is a free data retrieval call binding the contract method 0xc6f0308c.
//
// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock)
func (_OutputBisectionGame *OutputBisectionGameSession) ClaimData(arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error) {
return _OutputBisectionGame.Contract.ClaimData(&_OutputBisectionGame.CallOpts, arg0)
}
// ClaimData is a free data retrieval call binding the contract method 0xc6f0308c.
//
// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) ClaimData(arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error) {
return _OutputBisectionGame.Contract.ClaimData(&_OutputBisectionGame.CallOpts, arg0)
}
// ClaimDataLen is a free data retrieval call binding the contract method 0x8980e0cc.
//
// Solidity: function claimDataLen() view returns(uint256 len_)
func (_OutputBisectionGame *OutputBisectionGameCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "claimDataLen")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// ClaimDataLen is a free data retrieval call binding the contract method 0x8980e0cc.
//
// Solidity: function claimDataLen() view returns(uint256 len_)
func (_OutputBisectionGame *OutputBisectionGameSession) ClaimDataLen() (*big.Int, error) {
return _OutputBisectionGame.Contract.ClaimDataLen(&_OutputBisectionGame.CallOpts)
}
// ClaimDataLen is a free data retrieval call binding the contract method 0x8980e0cc.
//
// Solidity: function claimDataLen() view returns(uint256 len_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) ClaimDataLen() (*big.Int, error) {
return _OutputBisectionGame.Contract.ClaimDataLen(&_OutputBisectionGame.CallOpts)
}
// CreatedAt is a free data retrieval call binding the contract method 0xcf09e0d0.
//
// Solidity: function createdAt() view returns(uint64)
func (_OutputBisectionGame *OutputBisectionGameCaller) CreatedAt(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "createdAt")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// CreatedAt is a free data retrieval call binding the contract method 0xcf09e0d0.
//
// Solidity: function createdAt() view returns(uint64)
func (_OutputBisectionGame *OutputBisectionGameSession) CreatedAt() (uint64, error) {
return _OutputBisectionGame.Contract.CreatedAt(&_OutputBisectionGame.CallOpts)
}
// CreatedAt is a free data retrieval call binding the contract method 0xcf09e0d0.
//
// Solidity: function createdAt() view returns(uint64)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) CreatedAt() (uint64, error) {
return _OutputBisectionGame.Contract.CreatedAt(&_OutputBisectionGame.CallOpts)
}
// ExtraData is a free data retrieval call binding the contract method 0x609d3334.
//
// Solidity: function extraData() pure returns(bytes extraData_)
func (_OutputBisectionGame *OutputBisectionGameCaller) ExtraData(opts *bind.CallOpts) ([]byte, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "extraData")
if err != nil {
return *new([]byte), err
}
out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
return out0, err
}
// ExtraData is a free data retrieval call binding the contract method 0x609d3334.
//
// Solidity: function extraData() pure returns(bytes extraData_)
func (_OutputBisectionGame *OutputBisectionGameSession) ExtraData() ([]byte, error) {
return _OutputBisectionGame.Contract.ExtraData(&_OutputBisectionGame.CallOpts)
}
// ExtraData is a free data retrieval call binding the contract method 0x609d3334.
//
// Solidity: function extraData() pure returns(bytes extraData_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) ExtraData() ([]byte, error) {
return _OutputBisectionGame.Contract.ExtraData(&_OutputBisectionGame.CallOpts)
}
// GameData is a free data retrieval call binding the contract method 0xfa24f743.
//
// Solidity: function gameData() view returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_)
func (_OutputBisectionGame *OutputBisectionGameCaller) GameData(opts *bind.CallOpts) (struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
}, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "gameData")
outstruct := new(struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
})
if err != nil {
return *outstruct, err
}
outstruct.GameType = *abi.ConvertType(out[0], new(uint8)).(*uint8)
outstruct.RootClaim = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte)
outstruct.ExtraData = *abi.ConvertType(out[2], new([]byte)).(*[]byte)
return *outstruct, err
}
// GameData is a free data retrieval call binding the contract method 0xfa24f743.
//
// Solidity: function gameData() view returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_)
func (_OutputBisectionGame *OutputBisectionGameSession) GameData() (struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
}, error) {
return _OutputBisectionGame.Contract.GameData(&_OutputBisectionGame.CallOpts)
}
// GameData is a free data retrieval call binding the contract method 0xfa24f743.
//
// Solidity: function gameData() view returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) GameData() (struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
}, error) {
return _OutputBisectionGame.Contract.GameData(&_OutputBisectionGame.CallOpts)
}
// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376.
//
// Solidity: function gameDuration() view returns(uint64 gameDuration_)
func (_OutputBisectionGame *OutputBisectionGameCaller) GameDuration(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "gameDuration")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376.
//
// Solidity: function gameDuration() view returns(uint64 gameDuration_)
func (_OutputBisectionGame *OutputBisectionGameSession) GameDuration() (uint64, error) {
return _OutputBisectionGame.Contract.GameDuration(&_OutputBisectionGame.CallOpts)
}
// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376.
//
// Solidity: function gameDuration() view returns(uint64 gameDuration_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) GameDuration() (uint64, error) {
return _OutputBisectionGame.Contract.GameDuration(&_OutputBisectionGame.CallOpts)
}
// GameType is a free data retrieval call binding the contract method 0xbbdc02db.
//
// Solidity: function gameType() view returns(uint8 gameType_)
func (_OutputBisectionGame *OutputBisectionGameCaller) GameType(opts *bind.CallOpts) (uint8, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "gameType")
if err != nil {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
}
// GameType is a free data retrieval call binding the contract method 0xbbdc02db.
//
// Solidity: function gameType() view returns(uint8 gameType_)
func (_OutputBisectionGame *OutputBisectionGameSession) GameType() (uint8, error) {
return _OutputBisectionGame.Contract.GameType(&_OutputBisectionGame.CallOpts)
}
// GameType is a free data retrieval call binding the contract method 0xbbdc02db.
//
// Solidity: function gameType() view returns(uint8 gameType_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) GameType() (uint8, error) {
return _OutputBisectionGame.Contract.GameType(&_OutputBisectionGame.CallOpts)
}
// GenesisBlockNumber is a free data retrieval call binding the contract method 0x0356fe3a.
//
// Solidity: function genesisBlockNumber() view returns(uint256 genesisBlockNumber_)
func (_OutputBisectionGame *OutputBisectionGameCaller) GenesisBlockNumber(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "genesisBlockNumber")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// GenesisBlockNumber is a free data retrieval call binding the contract method 0x0356fe3a.
//
// Solidity: function genesisBlockNumber() view returns(uint256 genesisBlockNumber_)
func (_OutputBisectionGame *OutputBisectionGameSession) GenesisBlockNumber() (*big.Int, error) {
return _OutputBisectionGame.Contract.GenesisBlockNumber(&_OutputBisectionGame.CallOpts)
}
// GenesisBlockNumber is a free data retrieval call binding the contract method 0x0356fe3a.
//
// Solidity: function genesisBlockNumber() view returns(uint256 genesisBlockNumber_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) GenesisBlockNumber() (*big.Int, error) {
return _OutputBisectionGame.Contract.GenesisBlockNumber(&_OutputBisectionGame.CallOpts)
}
// GenesisOutputRoot is a free data retrieval call binding the contract method 0x68800abf.
//
// Solidity: function genesisOutputRoot() view returns(bytes32 genesisOutputRoot_)
func (_OutputBisectionGame *OutputBisectionGameCaller) GenesisOutputRoot(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "genesisOutputRoot")
if err != nil {
return *new([32]byte), err
}
out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
return out0, err
}
// GenesisOutputRoot is a free data retrieval call binding the contract method 0x68800abf.
//
// Solidity: function genesisOutputRoot() view returns(bytes32 genesisOutputRoot_)
func (_OutputBisectionGame *OutputBisectionGameSession) GenesisOutputRoot() ([32]byte, error) {
return _OutputBisectionGame.Contract.GenesisOutputRoot(&_OutputBisectionGame.CallOpts)
}
// GenesisOutputRoot is a free data retrieval call binding the contract method 0x68800abf.
//
// Solidity: function genesisOutputRoot() view returns(bytes32 genesisOutputRoot_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) GenesisOutputRoot() ([32]byte, error) {
return _OutputBisectionGame.Contract.GenesisOutputRoot(&_OutputBisectionGame.CallOpts)
}
// L1Head is a free data retrieval call binding the contract method 0x6361506d.
//
// Solidity: function l1Head() view returns(bytes32)
func (_OutputBisectionGame *OutputBisectionGameCaller) L1Head(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "l1Head")
if err != nil {
return *new([32]byte), err
}
out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
return out0, err
}
// L1Head is a free data retrieval call binding the contract method 0x6361506d.
//
// Solidity: function l1Head() view returns(bytes32)
func (_OutputBisectionGame *OutputBisectionGameSession) L1Head() ([32]byte, error) {
return _OutputBisectionGame.Contract.L1Head(&_OutputBisectionGame.CallOpts)
}
// L1Head is a free data retrieval call binding the contract method 0x6361506d.
//
// Solidity: function l1Head() view returns(bytes32)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) L1Head() ([32]byte, error) {
return _OutputBisectionGame.Contract.L1Head(&_OutputBisectionGame.CallOpts)
}
// L2BlockNumber is a free data retrieval call binding the contract method 0x8b85902b.
//
// Solidity: function l2BlockNumber() pure returns(uint256 l2BlockNumber_)
func (_OutputBisectionGame *OutputBisectionGameCaller) L2BlockNumber(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "l2BlockNumber")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// L2BlockNumber is a free data retrieval call binding the contract method 0x8b85902b.
//
// Solidity: function l2BlockNumber() pure returns(uint256 l2BlockNumber_)
func (_OutputBisectionGame *OutputBisectionGameSession) L2BlockNumber() (*big.Int, error) {
return _OutputBisectionGame.Contract.L2BlockNumber(&_OutputBisectionGame.CallOpts)
}
// L2BlockNumber is a free data retrieval call binding the contract method 0x8b85902b.
//
// Solidity: function l2BlockNumber() pure returns(uint256 l2BlockNumber_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) L2BlockNumber() (*big.Int, error) {
return _OutputBisectionGame.Contract.L2BlockNumber(&_OutputBisectionGame.CallOpts)
}
// MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9.
//
// Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_)
func (_OutputBisectionGame *OutputBisectionGameCaller) MaxGameDepth(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "maxGameDepth")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9.
//
// Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_)
func (_OutputBisectionGame *OutputBisectionGameSession) MaxGameDepth() (*big.Int, error) {
return _OutputBisectionGame.Contract.MaxGameDepth(&_OutputBisectionGame.CallOpts)
}
// MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9.
//
// Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) MaxGameDepth() (*big.Int, error) {
return _OutputBisectionGame.Contract.MaxGameDepth(&_OutputBisectionGame.CallOpts)
}
// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4.
//
// Solidity: function resolvedAt() view returns(uint64)
func (_OutputBisectionGame *OutputBisectionGameCaller) ResolvedAt(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "resolvedAt")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4.
//
// Solidity: function resolvedAt() view returns(uint64)
func (_OutputBisectionGame *OutputBisectionGameSession) ResolvedAt() (uint64, error) {
return _OutputBisectionGame.Contract.ResolvedAt(&_OutputBisectionGame.CallOpts)
}
// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4.
//
// Solidity: function resolvedAt() view returns(uint64)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) ResolvedAt() (uint64, error) {
return _OutputBisectionGame.Contract.ResolvedAt(&_OutputBisectionGame.CallOpts)
}
// RootClaim is a free data retrieval call binding the contract method 0xbcef3b55.
//
// Solidity: function rootClaim() pure returns(bytes32 rootClaim_)
func (_OutputBisectionGame *OutputBisectionGameCaller) RootClaim(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "rootClaim")
if err != nil {
return *new([32]byte), err
}
out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
return out0, err
}
// RootClaim is a free data retrieval call binding the contract method 0xbcef3b55.
//
// Solidity: function rootClaim() pure returns(bytes32 rootClaim_)
func (_OutputBisectionGame *OutputBisectionGameSession) RootClaim() ([32]byte, error) {
return _OutputBisectionGame.Contract.RootClaim(&_OutputBisectionGame.CallOpts)
}
// RootClaim is a free data retrieval call binding the contract method 0xbcef3b55.
//
// Solidity: function rootClaim() pure returns(bytes32 rootClaim_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) RootClaim() ([32]byte, error) {
return _OutputBisectionGame.Contract.RootClaim(&_OutputBisectionGame.CallOpts)
}
// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308.
//
// Solidity: function splitDepth() view returns(uint256 splitDepth_)
func (_OutputBisectionGame *OutputBisectionGameCaller) SplitDepth(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "splitDepth")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308.
//
// Solidity: function splitDepth() view returns(uint256 splitDepth_)
func (_OutputBisectionGame *OutputBisectionGameSession) SplitDepth() (*big.Int, error) {
return _OutputBisectionGame.Contract.SplitDepth(&_OutputBisectionGame.CallOpts)
}
// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308.
//
// Solidity: function splitDepth() view returns(uint256 splitDepth_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) SplitDepth() (*big.Int, error) {
return _OutputBisectionGame.Contract.SplitDepth(&_OutputBisectionGame.CallOpts)
}
// Status is a free data retrieval call binding the contract method 0x200d2ed2.
//
// Solidity: function status() view returns(uint8)
func (_OutputBisectionGame *OutputBisectionGameCaller) Status(opts *bind.CallOpts) (uint8, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "status")
if err != nil {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
}
// Status is a free data retrieval call binding the contract method 0x200d2ed2.
//
// Solidity: function status() view returns(uint8)
func (_OutputBisectionGame *OutputBisectionGameSession) Status() (uint8, error) {
return _OutputBisectionGame.Contract.Status(&_OutputBisectionGame.CallOpts)
}
// Status is a free data retrieval call binding the contract method 0x200d2ed2.
//
// Solidity: function status() view returns(uint8)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) Status() (uint8, error) {
return _OutputBisectionGame.Contract.Status(&_OutputBisectionGame.CallOpts)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_OutputBisectionGame *OutputBisectionGameCaller) Version(opts *bind.CallOpts) (string, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "version")
if err != nil {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_OutputBisectionGame *OutputBisectionGameSession) Version() (string, error) {
return _OutputBisectionGame.Contract.Version(&_OutputBisectionGame.CallOpts)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) Version() (string, error) {
return _OutputBisectionGame.Contract.Version(&_OutputBisectionGame.CallOpts)
}
// Vm is a free data retrieval call binding the contract method 0x3a768463.
//
// Solidity: function vm() view returns(address vm_)
func (_OutputBisectionGame *OutputBisectionGameCaller) Vm(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _OutputBisectionGame.contract.Call(opts, &out, "vm")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// Vm is a free data retrieval call binding the contract method 0x3a768463.
//
// Solidity: function vm() view returns(address vm_)
func (_OutputBisectionGame *OutputBisectionGameSession) Vm() (common.Address, error) {
return _OutputBisectionGame.Contract.Vm(&_OutputBisectionGame.CallOpts)
}
// Vm is a free data retrieval call binding the contract method 0x3a768463.
//
// Solidity: function vm() view returns(address vm_)
func (_OutputBisectionGame *OutputBisectionGameCallerSession) Vm() (common.Address, error) {
return _OutputBisectionGame.Contract.Vm(&_OutputBisectionGame.CallOpts)
}
// AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6.
//
// Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns()
func (_OutputBisectionGame *OutputBisectionGameTransactor) AddLocalData(opts *bind.TransactOpts, _ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "addLocalData", _ident, _execLeafIdx, _partOffset)
}
// AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6.
//
// Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns()
func (_OutputBisectionGame *OutputBisectionGameSession) AddLocalData(_ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.AddLocalData(&_OutputBisectionGame.TransactOpts, _ident, _execLeafIdx, _partOffset)
}
// AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6.
//
// Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns()
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) AddLocalData(_ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.AddLocalData(&_OutputBisectionGame.TransactOpts, _ident, _execLeafIdx, _partOffset)
}
// Attack is a paid mutator transaction binding the contract method 0xc55cd0c7.
//
// Solidity: function attack(uint256 _parentIndex, bytes32 _claim) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactor) Attack(opts *bind.TransactOpts, _parentIndex *big.Int, _claim [32]byte) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "attack", _parentIndex, _claim)
}
// Attack is a paid mutator transaction binding the contract method 0xc55cd0c7.
//
// Solidity: function attack(uint256 _parentIndex, bytes32 _claim) payable returns()
func (_OutputBisectionGame *OutputBisectionGameSession) Attack(_parentIndex *big.Int, _claim [32]byte) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Attack(&_OutputBisectionGame.TransactOpts, _parentIndex, _claim)
}
// Attack is a paid mutator transaction binding the contract method 0xc55cd0c7.
//
// Solidity: function attack(uint256 _parentIndex, bytes32 _claim) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) Attack(_parentIndex *big.Int, _claim [32]byte) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Attack(&_OutputBisectionGame.TransactOpts, _parentIndex, _claim)
}
// Defend is a paid mutator transaction binding the contract method 0x35fef567.
//
// Solidity: function defend(uint256 _parentIndex, bytes32 _claim) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactor) Defend(opts *bind.TransactOpts, _parentIndex *big.Int, _claim [32]byte) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "defend", _parentIndex, _claim)
}
// Defend is a paid mutator transaction binding the contract method 0x35fef567.
//
// Solidity: function defend(uint256 _parentIndex, bytes32 _claim) payable returns()
func (_OutputBisectionGame *OutputBisectionGameSession) Defend(_parentIndex *big.Int, _claim [32]byte) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Defend(&_OutputBisectionGame.TransactOpts, _parentIndex, _claim)
}
// Defend is a paid mutator transaction binding the contract method 0x35fef567.
//
// Solidity: function defend(uint256 _parentIndex, bytes32 _claim) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) Defend(_parentIndex *big.Int, _claim [32]byte) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Defend(&_OutputBisectionGame.TransactOpts, _parentIndex, _claim)
}
// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c.
//
// Solidity: function initialize() returns()
func (_OutputBisectionGame *OutputBisectionGameTransactor) Initialize(opts *bind.TransactOpts) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "initialize")
}
// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c.
//
// Solidity: function initialize() returns()
func (_OutputBisectionGame *OutputBisectionGameSession) Initialize() (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Initialize(&_OutputBisectionGame.TransactOpts)
}
// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c.
//
// Solidity: function initialize() returns()
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) Initialize() (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Initialize(&_OutputBisectionGame.TransactOpts)
}
// Move is a paid mutator transaction binding the contract method 0x632247ea.
//
// Solidity: function move(uint256 _challengeIndex, bytes32 _claim, bool _isAttack) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactor) Move(opts *bind.TransactOpts, _challengeIndex *big.Int, _claim [32]byte, _isAttack bool) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "move", _challengeIndex, _claim, _isAttack)
}
// Move is a paid mutator transaction binding the contract method 0x632247ea.
//
// Solidity: function move(uint256 _challengeIndex, bytes32 _claim, bool _isAttack) payable returns()
func (_OutputBisectionGame *OutputBisectionGameSession) Move(_challengeIndex *big.Int, _claim [32]byte, _isAttack bool) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Move(&_OutputBisectionGame.TransactOpts, _challengeIndex, _claim, _isAttack)
}
// Move is a paid mutator transaction binding the contract method 0x632247ea.
//
// Solidity: function move(uint256 _challengeIndex, bytes32 _claim, bool _isAttack) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) Move(_challengeIndex *big.Int, _claim [32]byte, _isAttack bool) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Move(&_OutputBisectionGame.TransactOpts, _challengeIndex, _claim, _isAttack)
}
// Resolve is a paid mutator transaction binding the contract method 0x2810e1d6.
//
// Solidity: function resolve() returns(uint8 status_)
func (_OutputBisectionGame *OutputBisectionGameTransactor) Resolve(opts *bind.TransactOpts) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "resolve")
}
// Resolve is a paid mutator transaction binding the contract method 0x2810e1d6.
//
// Solidity: function resolve() returns(uint8 status_)
func (_OutputBisectionGame *OutputBisectionGameSession) Resolve() (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Resolve(&_OutputBisectionGame.TransactOpts)
}
// Resolve is a paid mutator transaction binding the contract method 0x2810e1d6.
//
// Solidity: function resolve() returns(uint8 status_)
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) Resolve() (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Resolve(&_OutputBisectionGame.TransactOpts)
}
// ResolveClaim is a paid mutator transaction binding the contract method 0xfdffbb28.
//
// Solidity: function resolveClaim(uint256 _claimIndex) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactor) ResolveClaim(opts *bind.TransactOpts, _claimIndex *big.Int) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "resolveClaim", _claimIndex)
}
// ResolveClaim is a paid mutator transaction binding the contract method 0xfdffbb28.
//
// Solidity: function resolveClaim(uint256 _claimIndex) payable returns()
func (_OutputBisectionGame *OutputBisectionGameSession) ResolveClaim(_claimIndex *big.Int) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.ResolveClaim(&_OutputBisectionGame.TransactOpts, _claimIndex)
}
// ResolveClaim is a paid mutator transaction binding the contract method 0xfdffbb28.
//
// Solidity: function resolveClaim(uint256 _claimIndex) payable returns()
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) ResolveClaim(_claimIndex *big.Int) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.ResolveClaim(&_OutputBisectionGame.TransactOpts, _claimIndex)
}
// Step is a paid mutator transaction binding the contract method 0xd8cc1a3c.
//
// Solidity: function step(uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
func (_OutputBisectionGame *OutputBisectionGameTransactor) Step(opts *bind.TransactOpts, _claimIndex *big.Int, _isAttack bool, _stateData []byte, _proof []byte) (*types.Transaction, error) {
return _OutputBisectionGame.contract.Transact(opts, "step", _claimIndex, _isAttack, _stateData, _proof)
}
// Step is a paid mutator transaction binding the contract method 0xd8cc1a3c.
//
// Solidity: function step(uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
func (_OutputBisectionGame *OutputBisectionGameSession) Step(_claimIndex *big.Int, _isAttack bool, _stateData []byte, _proof []byte) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Step(&_OutputBisectionGame.TransactOpts, _claimIndex, _isAttack, _stateData, _proof)
}
// Step is a paid mutator transaction binding the contract method 0xd8cc1a3c.
//
// Solidity: function step(uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
func (_OutputBisectionGame *OutputBisectionGameTransactorSession) Step(_claimIndex *big.Int, _isAttack bool, _stateData []byte, _proof []byte) (*types.Transaction, error) {
return _OutputBisectionGame.Contract.Step(&_OutputBisectionGame.TransactOpts, _claimIndex, _isAttack, _stateData, _proof)
}
// OutputBisectionGameMoveIterator is returned from FilterMove and is used to iterate over the raw logs and unpacked data for Move events raised by the OutputBisectionGame contract.
type OutputBisectionGameMoveIterator struct {
Event *OutputBisectionGameMove // 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 *OutputBisectionGameMoveIterator) 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(OutputBisectionGameMove)
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(OutputBisectionGameMove)
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 *OutputBisectionGameMoveIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *OutputBisectionGameMoveIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// OutputBisectionGameMove represents a Move event raised by the OutputBisectionGame contract.
type OutputBisectionGameMove struct {
ParentIndex *big.Int
Claim [32]byte
Claimant common.Address
Raw types.Log // Blockchain specific contextual infos
}
// FilterMove is a free log retrieval operation binding the contract event 0x9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be.
//
// Solidity: event Move(uint256 indexed parentIndex, bytes32 indexed claim, address indexed claimant)
func (_OutputBisectionGame *OutputBisectionGameFilterer) FilterMove(opts *bind.FilterOpts, parentIndex []*big.Int, claim [][32]byte, claimant []common.Address) (*OutputBisectionGameMoveIterator, error) {
var parentIndexRule []interface{}
for _, parentIndexItem := range parentIndex {
parentIndexRule = append(parentIndexRule, parentIndexItem)
}
var claimRule []interface{}
for _, claimItem := range claim {
claimRule = append(claimRule, claimItem)
}
var claimantRule []interface{}
for _, claimantItem := range claimant {
claimantRule = append(claimantRule, claimantItem)
}
logs, sub, err := _OutputBisectionGame.contract.FilterLogs(opts, "Move", parentIndexRule, claimRule, claimantRule)
if err != nil {
return nil, err
}
return &OutputBisectionGameMoveIterator{contract: _OutputBisectionGame.contract, event: "Move", logs: logs, sub: sub}, nil
}
// WatchMove is a free log subscription operation binding the contract event 0x9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be.
//
// Solidity: event Move(uint256 indexed parentIndex, bytes32 indexed claim, address indexed claimant)
func (_OutputBisectionGame *OutputBisectionGameFilterer) WatchMove(opts *bind.WatchOpts, sink chan<- *OutputBisectionGameMove, parentIndex []*big.Int, claim [][32]byte, claimant []common.Address) (event.Subscription, error) {
var parentIndexRule []interface{}
for _, parentIndexItem := range parentIndex {
parentIndexRule = append(parentIndexRule, parentIndexItem)
}
var claimRule []interface{}
for _, claimItem := range claim {
claimRule = append(claimRule, claimItem)
}
var claimantRule []interface{}
for _, claimantItem := range claimant {
claimantRule = append(claimantRule, claimantItem)
}
logs, sub, err := _OutputBisectionGame.contract.WatchLogs(opts, "Move", parentIndexRule, claimRule, claimantRule)
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(OutputBisectionGameMove)
if err := _OutputBisectionGame.contract.UnpackLog(event, "Move", 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
}
// ParseMove is a log parse operation binding the contract event 0x9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be.
//
// Solidity: event Move(uint256 indexed parentIndex, bytes32 indexed claim, address indexed claimant)
func (_OutputBisectionGame *OutputBisectionGameFilterer) ParseMove(log types.Log) (*OutputBisectionGameMove, error) {
event := new(OutputBisectionGameMove)
if err := _OutputBisectionGame.contract.UnpackLog(event, "Move", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// OutputBisectionGameResolvedIterator is returned from FilterResolved and is used to iterate over the raw logs and unpacked data for Resolved events raised by the OutputBisectionGame contract.
type OutputBisectionGameResolvedIterator struct {
Event *OutputBisectionGameResolved // 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 *OutputBisectionGameResolvedIterator) 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(OutputBisectionGameResolved)
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(OutputBisectionGameResolved)
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 *OutputBisectionGameResolvedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *OutputBisectionGameResolvedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// OutputBisectionGameResolved represents a Resolved event raised by the OutputBisectionGame contract.
type OutputBisectionGameResolved struct {
Status uint8
Raw types.Log // Blockchain specific contextual infos
}
// FilterResolved is a free log retrieval operation binding the contract event 0x5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da60.
//
// Solidity: event Resolved(uint8 indexed status)
func (_OutputBisectionGame *OutputBisectionGameFilterer) FilterResolved(opts *bind.FilterOpts, status []uint8) (*OutputBisectionGameResolvedIterator, error) {
var statusRule []interface{}
for _, statusItem := range status {
statusRule = append(statusRule, statusItem)
}
logs, sub, err := _OutputBisectionGame.contract.FilterLogs(opts, "Resolved", statusRule)
if err != nil {
return nil, err
}
return &OutputBisectionGameResolvedIterator{contract: _OutputBisectionGame.contract, event: "Resolved", logs: logs, sub: sub}, nil
}
// WatchResolved is a free log subscription operation binding the contract event 0x5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da60.
//
// Solidity: event Resolved(uint8 indexed status)
func (_OutputBisectionGame *OutputBisectionGameFilterer) WatchResolved(opts *bind.WatchOpts, sink chan<- *OutputBisectionGameResolved, status []uint8) (event.Subscription, error) {
var statusRule []interface{}
for _, statusItem := range status {
statusRule = append(statusRule, statusItem)
}
logs, sub, err := _OutputBisectionGame.contract.WatchLogs(opts, "Resolved", statusRule)
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(OutputBisectionGameResolved)
if err := _OutputBisectionGame.contract.UnpackLog(event, "Resolved", 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
}
// ParseResolved is a log parse operation binding the contract event 0x5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da60.
//
// Solidity: event Resolved(uint8 indexed status)
func (_OutputBisectionGame *OutputBisectionGameFilterer) ParseResolved(log types.Log) (*OutputBisectionGameResolved, error) {
event := new(OutputBisectionGameResolved)
if err := _OutputBisectionGame.contract.UnpackLog(event, "Resolved", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const OutputBisectionGameStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"createdAt\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1017\"},{\"astId\":1001,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"resolvedAt\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1017\"},{\"astId\":1002,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"status\",\"offset\":16,\"slot\":\"0\",\"type\":\"t_enum(GameStatus)1010\"},{\"astId\":1003,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"bondManager\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_contract(IBondManager)1009\"},{\"astId\":1004,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"l1Head\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_userDefinedValueType(Hash)1015\"},{\"astId\":1005,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"claimData\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\"},{\"astId\":1006,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"claims\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_mapping(t_userDefinedValueType(ClaimHash)1013,t_bool)\"},{\"astId\":1007,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"subgames\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\"},{\"astId\":1008,\"contract\":\"src/dispute/OutputBisectionGame.sol:OutputBisectionGame\",\"label\":\"subgameAtRootResolved\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_bool\"}],\"types\":{\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct IOutputBisectionGame.ClaimData[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(ClaimData)1011_storage\"},\"t_array(t_uint256)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"uint256[]\",\"numberOfBytes\":\"32\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(IBondManager)1009\":{\"encoding\":\"inplace\",\"label\":\"contract IBondManager\",\"numberOfBytes\":\"20\"},\"t_enum(GameStatus)1010\":{\"encoding\":\"inplace\",\"label\":\"enum GameStatus\",\"numberOfBytes\":\"1\"},\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e uint256[])\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_array(t_uint256)dyn_storage\"},\"t_mapping(t_userDefinedValueType(ClaimHash)1013,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(ClaimHash =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(ClaimHash)1013\",\"value\":\"t_bool\"},\"t_struct(ClaimData)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IOutputBisectionGame.ClaimData\",\"numberOfBytes\":\"96\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_userDefinedValueType(Claim)1012\":{\"encoding\":\"inplace\",\"label\":\"Claim\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(ClaimHash)1013\":{\"encoding\":\"inplace\",\"label\":\"ClaimHash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Clock)1014\":{\"encoding\":\"inplace\",\"label\":\"Clock\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Hash)1015\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Position)1016\":{\"encoding\":\"inplace\",\"label\":\"Position\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Timestamp)1017\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}"
var OutputBisectionGameStorageLayout = new(solc.StorageLayout)
var OutputBisectionGameDeployedBin = "0x6080604052600436106101b75760003560e01c80638b85902b116100ec578063d8cc1a3c1161008a578063f8f43ff611610064578063f8f43ff61461062b578063fa24f7431461064b578063fa315aa91461066f578063fdffbb28146106a257600080fd5b8063d8cc1a3c146105a5578063e1f0c376146105c5578063ec5e6308146105f857600080fd5b8063bcef3b55116100c6578063bcef3b55146104d0578063c55cd0c71461050d578063c6f0308c14610520578063cf09e0d01461058457600080fd5b80638b85902b1461041f5780638d450a951461045f578063bbdc02db1461049257600080fd5b806354fd4d50116101595780636361506d116101335780636361506d146103ac57806368800abf146103c25780638129fc1c146103f55780638980e0cc1461040a57600080fd5b806354fd4d501461032e578063609d333414610384578063632247ea1461039957600080fd5b80632810e1d6116101955780632810e1d61461027f57806335fef56714610294578063363cc427146102a95780633a768463146102fb57600080fd5b80630356fe3a146101bc57806319effeb4146101fe578063200d2ed214610244575b600080fd5b3480156101c857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561020a57600080fd5b5060005461022b9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101f5565b34801561025057600080fd5b5060005461027290700100000000000000000000000000000000900460ff1681565b6040516101f59190612ce5565b34801561028b57600080fd5b506102726106b5565b6102a76102a2366004612d26565b610886565b005b3480156102b557600080fd5b506001546102d69073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f5565b34801561030757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102d6565b34801561033a57600080fd5b506103776040518060400160405280600681526020017f302e302e3138000000000000000000000000000000000000000000000000000081525081565b6040516101f59190612db3565b34801561039057600080fd5b50610377610896565b6102a76103a7366004612ddb565b6108a8565b3480156103b857600080fd5b506101eb60025481565b3480156103ce57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561040157600080fd5b506102a7610f58565b34801561041657600080fd5b506003546101eb565b34801561042b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101eb565b34801561046b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561049e57600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f5565b3480156104dc57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101eb565b6102a761051b366004612d26565b61116e565b34801561052c57600080fd5b5061054061053b366004612e10565b61117a565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101f5565b34801561059057600080fd5b5060005461022b9067ffffffffffffffff1681565b3480156105b157600080fd5b506102a76105c0366004612e72565b6111eb565b3480156105d157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061022b565b34801561060457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b34801561063757600080fd5b506102a7610646366004612efc565b611786565b34801561065757600080fd5b50610660611c7b565b6040516101f593929190612f28565b34801561067b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101eb565b6102a76106b0366004612e10565b611cd8565b600080600054700100000000000000000000000000000000900460ff1660028111156106e3576106e3612cb6565b1461071a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065460ff16610756576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600360008154811061076a5761076a612f53565b6000918252602090912060039091020154640100000000900460ff16610791576002610794565b60015b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561084557610845612cb6565b02179055600281111561085a5761085a612cb6565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610892828260006108a8565b5050565b60606108a3602080612012565b905090565b60008054700100000000000000000000000000000000900460ff1660028111156108d4576108d4612cb6565b1461090b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003848154811061092057610920612f53565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff808216606085018190527001000000000000000000000000000000009092041660808401529193509091906109b890839086906120a916565b90506000610a58826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610a9a5750610a977f00000000000000000000000000000000000000000000000000000000000000006002612fb1565b81145b8015610aa4575084155b15610adb576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610b35576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b607f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8103610b7257610b72868885886120b1565b835160009063ffffffff90811614610bd2576003856000015163ffffffff1681548110610ba157610ba1612f53565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608085015160009067ffffffffffffffff1667ffffffffffffffff1642610c0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610c1f9190612fb1565b610c299190612fc9565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c9c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615610d1a576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060036040518060a001604052808d63ffffffff1681526020016000151581526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548160ff0219169083151502179055506040820151816001015560608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160020160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600160038c81548110610eab57610eab612f53565b600091825260208083206003928302018054941515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909516949094179093558d82526005909252604090209054610f0c90600190612fc9565b8154600181018355600092835260208320015560405133918c918e917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a45050505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001351161100f576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff16179055604636111561105a5763c407e0256000526004601cfd5b6040805160a08101825263ffffffff8152600060208201526003918101367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff90931692909217949094178155604083015181850155606083015160809093015182167001000000000000000000000000000000000292909116919091176002909101556111689043612fc9565b40600255565b610892828260016108a8565b6003818154811061118a57600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b60008054700100000000000000000000000000000000900460ff16600281111561121757611217612cb6565b1461124e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003878154811061126357611263612f53565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112c27f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b61135e826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161461139f576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561147c576113f27f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612fc9565b6001901b611411846fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16611425919061300f565b1561145057611447611438600186613023565b865463ffffffff166000612304565b60010154611472565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611496565b846001015491506114938460016114389190613054565b90505b600882901b60088a8a6040516114ad929190613088565b6040518091039020901b146114ee576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114f98c6123e8565b9050600082600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e14ced328d8d8d8d886040518663ffffffff1660e01b81526004016115639594939291906130e1565b6020604051808303816000875af1158015611582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a6919061311b565b600285810154929091149250600091611651906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116ed896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6116f79190613134565b6117019190613155565b67ffffffffffffffff161590508115158103611749576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156117b2576117b2612cb6565b146117e9576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806117f886612417565b9350935093509350600061180e858585856127e4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561187d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a1919061317c565b905060018903611963576002546040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018b9052602481018490526044810191909152602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4015b6020604051808303816000875af1158015611939573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195d919061311b565b50611c70565b600289036119da576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101879052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60038903611a51576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a90526024810183905260448101859052602060648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b60048903611bc55760006fffffffffffffffffffffffffffffffff861615611ae957611aaf6fffffffffffffffffffffffffffffffff87167f00000000000000000000000000000000000000000000000000000000000000006128a4565b611ad9907f0000000000000000000000000000000000000000000000000000000000000000612fb1565b611ae4906001612fb1565b611b0b565b7f00000000000000000000000000000000000000000000000000000000000000005b6040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018c90526024810185905260c082901b604482015260086064820152608481018a905290915073ffffffffffffffffffffffffffffffffffffffff8316906352f0f3ad9060a4016020604051808303816000875af1158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe919061311b565b5050611c70565b60058903611c3e576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390524660c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a40161191a565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611cd1610896565b9050909192565b60008054700100000000000000000000000000000000900460ff166002811115611d0457611d04612cb6565b14611d3b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611d5057611d50612f53565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611dc090700100000000000000000000000000000000900467ffffffffffffffff1642612fc9565b6002830154611df09190700100000000000000000000000000000000900460401c67ffffffffffffffff16612fb1565b11611e27576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260056020526040902082158015611e45575060065460ff165b15611e7c576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e8a57508215155b15611ec1576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f8f576000838281548110611ee257611ee2612f53565b6000918252602080832090910154808352600590915260409091205490915015611f38576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038281548110611f4d57611f4d612f53565b600091825260209091206003909102018054909150640100000000900460ff16611f7c57600193505050611f8f565b505080611f88906131b9565b9050611ec5565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600560205260408120611fd891612c7c565b8360000361200c57600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061204984367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003612fb1565b90508267ffffffffffffffff1667ffffffffffffffff81111561206e5761206e6131f1565b6040519080825280601f01601f191660200182016040528015612098576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60006120be836001613054565b905060006120ce82866001612304565b9050600086901a83806121bf575061210760027f000000000000000000000000000000000000000000000000000000000000000061300f565b6002838101546121a9906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121b39190613155565b67ffffffffffffffff16145b156122175760ff8116600114806121d9575060ff81166002145b612212576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b612255565b60ff811615612255576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401611006565b50505050505050565b6000806122eb837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261234d576123486fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000612959565b612368565b612368856fffffffffffffffffffffffffffffffff16612b20565b90506003848154811061237d5761237d612f53565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146123e057815460038054909163ffffffff169081106123cb576123cb612f53565b9060005260206000209060030201915061238e565b509392505050565b60008060008060006123f986612417565b935093509350935061240d848484846127e4565b9695505050505050565b600080600080600085905060006003828154811061243757612437612f53565b600091825260209091206002600390920201908101549091507f00000000000000000000000000000000000000000000000000000000000000009061250e906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161254f576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60028301547f000000000000000000000000000000000000000000000000000000000000000090612616906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16925082111561269257825463ffffffff1661265c7f00000000000000000000000000000000000000000000000000000000000000006001612fb1565b8303612666578391505b6003818154811061267957612679612f53565b9060005260206000209060030201935080945050612553565b600280820154908401546fffffffffffffffffffffffffffffffff91821691166000816126bf8460011c90565b6fffffffffffffffffffffffffffffffff1614905080156127925760006126f7836fffffffffffffffffffffffffffffffff1661225e565b67ffffffffffffffff16111561274857600061271f612717600185613023565b896001612304565b6001810154600290910154909c506fffffffffffffffffffffffffffffffff169a5061276c9050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600186015460028701549099506fffffffffffffffffffffffffffffffff1697506127d6565b60006127a2612717846001613054565b6001808901546002808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b6000836fffffffffffffffffffffffffffffffff1660000361284b57828260405160200161282e9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b60405160208183030381529060405280519060200120905061289c565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080612931847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b6000816129f8846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612a39576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a4283612b20565b905081612ae1826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612b1a57612b17612afe836001612fb1565b6fffffffffffffffffffffffffffffffff831690612bcc565b90505b92915050565b60008119600183011681612bb4827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080612c59847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190612c9a9190612c9d565b50565b5b80821115612cb25760008155600101612c9e565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612d20577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215612d3957600080fd5b50508035926020909101359150565b6000815180845260005b81811015612d6e57602081850181015186830182015201612d52565b81811115612d80576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612b176020830184612d48565b80358015158114612dd657600080fd5b919050565b600080600060608486031215612df057600080fd5b8335925060208401359150612e0760408501612dc6565b90509250925092565b600060208284031215612e2257600080fd5b5035919050565b60008083601f840112612e3b57600080fd5b50813567ffffffffffffffff811115612e5357600080fd5b602083019150836020828501011115612e6b57600080fd5b9250929050565b60008060008060008060808789031215612e8b57600080fd5b86359550612e9b60208801612dc6565b9450604087013567ffffffffffffffff80821115612eb857600080fd5b612ec48a838b01612e29565b90965094506060890135915080821115612edd57600080fd5b50612eea89828a01612e29565b979a9699509497509295939492505050565b600080600060608486031215612f1157600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612f4a6060830184612d48565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612fc457612fc4612f82565b500190565b600082821015612fdb57612fdb612f82565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261301e5761301e612fe0565b500690565b60006fffffffffffffffffffffffffffffffff8381169083168181101561304c5761304c612f82565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561307f5761307f612f82565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006130f5606083018789613098565b8281036020840152613108818688613098565b9150508260408301529695505050505050565b60006020828403121561312d57600080fd5b5051919050565b600067ffffffffffffffff8381169083168181101561304c5761304c612f82565b600067ffffffffffffffff8084168061317057613170612fe0565b92169190910692915050565b60006020828403121561318e57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146131b257600080fd5b9392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036131ea576131ea612f82565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(OutputBisectionGameStorageLayoutJSON), OutputBisectionGameStorageLayout); err != nil {
panic(err)
}
layouts["OutputBisectionGame"] = OutputBisectionGameStorageLayout
deployedBytecodes["OutputBisectionGame"] = OutputBisectionGameDeployedBin
immutableReferences["OutputBisectionGame"] = true
}
...@@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) ...@@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout)
var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806352f0f3ad1461007757806361238bde1461009d5780638542cf50146100c8575b600080fd5b61008a6100853660046104df565b610163565b6040519081526020015b60405180910390f35b61008a6100ab36600461051a565b600160209081526000928352604080842090915290825290205481565b6100f66100d636600461051a565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610094565b61011961011436600461051a565b610238565b60408051928352602083019190915201610094565b61014161013c36600461053c565b610329565b005b61008a6101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080600080600060a086880312156104f757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806040838503121561052d57600080fd5b50508035926020909101359150565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806352f0f3ad1461007757806361238bde1461009d5780638542cf50146100c8575b600080fd5b61008a6100853660046104df565b610163565b6040519081526020015b60405180910390f35b61008a6100ab36600461051a565b600160209081526000928352604080842090915290825290205481565b6100f66100d636600461051a565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610094565b61011961011436600461051a565b610238565b60408051928352602083019190915201610094565b61014161013c36600461053c565b610329565b005b61008a6101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080600080600060a086880312156104f757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806040838503121561052d57600080fd5b50508035926020909101359150565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a"
var PreimageOracleDeployedSourceMap = "306:3911:144:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1367:1211;;;;;;:::i;:::-;;:::i;:::-;;;619:25:324;;;607:2;592:18;1367:1211:144;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1073:14:324;;1066:22;1048:41;;1036:2;1021:18;680:66:144;908:187:324;789:536:144;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:324;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:144;1100:248:324;2620:1595:144;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:144;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:144:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:324;906:62:144;;;2890:21:324;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:144;;;;;;;;-1:-1:-1;1099:14:144;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:144;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:144:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:144:o;552:449:143:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:143:o;14:454:324:-;109:6;117;125;133;141;194:3;182:9;173:7;169:23;165:33;162:53;;;211:1;208;201:12;162:53;-1:-1:-1;;234:23:324;;;304:2;289:18;;276:32;;-1:-1:-1;355:2:324;340:18;;327:32;;406:2;391:18;;378:32;;-1:-1:-1;457:3:324;442:19;429:33;;-1:-1:-1;14:454:324;-1:-1:-1;14:454:324:o;655:248::-;723:6;731;784:2;772:9;763:7;759:23;755:32;752:52;;;800:1;797;790:12;752:52;-1:-1:-1;;823:23:324;;;893:2;878:18;;;865:32;;-1:-1:-1;655:248:324:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:324;;2017:180;-1:-1:-1;2017:180:324:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:324;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:324;;3055:125::o" var PreimageOracleDeployedSourceMap = "306:3911:144:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1367:1211;;;;;;:::i;:::-;;:::i;:::-;;;619:25:321;;;607:2;592:18;1367:1211:144;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1073:14:321;;1066:22;1048:41;;1036:2;1021:18;680:66:144;908:187:321;789:536:144;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:321;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:144;1100:248:321;2620:1595:144;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:144;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:144:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:321;906:62:144;;;2890:21:321;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:144;;;;;;;;-1:-1:-1;1099:14:144;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:144;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:144:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:144:o;552:449:143:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:143:o;14:454:321:-;109:6;117;125;133;141;194:3;182:9;173:7;169:23;165:33;162:53;;;211:1;208;201:12;162:53;-1:-1:-1;;234:23:321;;;304:2;289:18;;276:32;;-1:-1:-1;355:2:321;340:18;;327:32;;406:2;391:18;;378:32;;-1:-1:-1;457:3:321;442:19;429:33;;-1:-1:-1;14:454:321;-1:-1:-1;14:454:321:o;655:248::-;723:6;731;784:2;772:9;763:7;759:23;755:32;752:52;;;800:1;797;790:12;752:52;-1:-1:-1;;823:23:321;;;893:2;878:18;;;865:32;;-1:-1:-1;655:248:321:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:321;;2017:180;-1:-1:-1;2017:180:321:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:321;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:321;;3055:125::o"
func init() { func init() {
......
...@@ -212,12 +212,12 @@ type DeployConfig struct { ...@@ -212,12 +212,12 @@ type DeployConfig struct {
// game can run for before it is ready to be resolved. Each side receives half of this value // game can run for before it is ready to be resolved. Each side receives half of this value
// on their chess clock at the inception of the dispute. // on their chess clock at the inception of the dispute.
FaultGameMaxDuration uint64 `json:"faultGameMaxDuration"` FaultGameMaxDuration uint64 `json:"faultGameMaxDuration"`
// OutputBisectionGameGenesisBlock is the block number for genesis. // FaultGameGenesisBlock is the block number for genesis.
OutputBisectionGameGenesisBlock uint64 `json:"outputBisectionGameGenesisBlock"` FaultGameGenesisBlock uint64 `json:"faultGameGenesisBlock"`
// OutputBisectionGameGenesisOutputRoot is the output root for the genesis block. // FaultGameGenesisOutputRoot is the output root for the genesis block.
OutputBisectionGameGenesisOutputRoot common.Hash `json:"outputBisectionGameGenesisOutputRoot"` FaultGameGenesisOutputRoot common.Hash `json:"faultGameGenesisOutputRoot"`
// OutputBisectionGameSplitDepth is the depth at which the output bisection game splits. // FaultGameSplitDepth is the depth at which the fault dispute game splits from output roots to execution trace claims.
OutputBisectionGameSplitDepth uint64 `json:"outputBisectionGameSplitDepth"` FaultGameSplitDepth uint64 `json:"faultGameSplitDepth"`
// FundDevAccounts configures whether or not to fund the dev accounts. Should only be used // FundDevAccounts configures whether or not to fund the dev accounts. Should only be used
// during devnet deployments. // during devnet deployments.
FundDevAccounts bool `json:"fundDevAccounts"` FundDevAccounts bool `json:"fundDevAccounts"`
......
...@@ -68,9 +68,9 @@ ...@@ -68,9 +68,9 @@
"faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000", "faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameMaxDepth": 63, "faultGameMaxDepth": 63,
"faultGameMaxDuration": 604800, "faultGameMaxDuration": 604800,
"outputBisectionGameGenesisBlock": 0, "faultGameGenesisBlock": 0,
"outputBisectionGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"outputBisectionGameSplitDepth": 0, "faultGameSplitDepth": 0,
"systemConfigStartBlock": 0, "systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000"
......
...@@ -28,7 +28,6 @@ var ( ...@@ -28,7 +28,6 @@ var (
datadir = "./test_data" datadir = "./test_data"
cannonL2 = "http://example.com:9545" cannonL2 = "http://example.com:9545"
rollupRpc = "http://example.com:8555" rollupRpc = "http://example.com:8555"
alphabetTrace = "abcdefghijz"
) )
func TestLogLevel(t *testing.T) { func TestLogLevel(t *testing.T) {
...@@ -50,7 +49,7 @@ func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) { ...@@ -50,7 +49,7 @@ func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet)) cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet))
defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, datadir, config.TraceTypeAlphabet) defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, datadir, config.TraceTypeAlphabet)
// Add in the extra CLI options required when using alphabet trace type // Add in the extra CLI options required when using alphabet trace type
defaultCfg.AlphabetTrace = alphabetTrace defaultCfg.RollupRpc = rollupRpc
require.Equal(t, defaultCfg, cfg) require.Equal(t, defaultCfg, cfg)
} }
...@@ -58,7 +57,7 @@ func TestDefaultConfigIsValid(t *testing.T) { ...@@ -58,7 +57,7 @@ func TestDefaultConfigIsValid(t *testing.T) {
cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, datadir, config.TraceTypeAlphabet) cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, datadir, config.TraceTypeAlphabet)
// Add in options that are required based on the specific trace type // Add in options that are required based on the specific trace type
// To avoid needing to specify unused options, these aren't included in the params for NewConfig // To avoid needing to specify unused options, these aren't included in the params for NewConfig
cfg.AlphabetTrace = alphabetTrace cfg.RollupRpc = rollupRpc
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
} }
...@@ -96,19 +95,17 @@ func TestTraceType(t *testing.T) { ...@@ -96,19 +95,17 @@ func TestTraceType(t *testing.T) {
func TestMultipleTraceTypes(t *testing.T) { func TestMultipleTraceTypes(t *testing.T) {
t.Run("WithAllOptions", func(t *testing.T) { t.Run("WithAllOptions", func(t *testing.T) {
argsMap := requiredArgs(config.TraceTypeCannon) argsMap := requiredArgs(config.TraceTypeCannon)
addRequiredOutputCannonArgs(argsMap) addRequiredOutputArgs(argsMap)
addRequiredAlphabetArgs(argsMap)
args := toArgList(argsMap) args := toArgList(argsMap)
// Add extra trace types (cannon is already specified) // Add extra trace types (cannon is already specified)
args = append(args, args = append(args,
"--trace-type", config.TraceTypeOutputCannon.String(),
"--trace-type", config.TraceTypeAlphabet.String()) "--trace-type", config.TraceTypeAlphabet.String())
cfg := configForArgs(t, args) cfg := configForArgs(t, args)
require.Equal(t, []config.TraceType{config.TraceTypeCannon, config.TraceTypeOutputCannon, config.TraceTypeAlphabet}, cfg.TraceTypes) require.Equal(t, []config.TraceType{config.TraceTypeCannon, config.TraceTypeAlphabet}, cfg.TraceTypes)
}) })
t.Run("WithSomeOptions", func(t *testing.T) { t.Run("WithSomeOptions", func(t *testing.T) {
argsMap := requiredArgs(config.TraceTypeCannon) argsMap := requiredArgs(config.TraceTypeCannon)
addRequiredAlphabetArgs(argsMap) addRequiredOutputArgs(argsMap)
args := toArgList(argsMap) args := toArgList(argsMap)
// Add extra trace types (cannon is already specified) // Add extra trace types (cannon is already specified)
args = append(args, args = append(args,
...@@ -270,20 +267,16 @@ func TestDataDir(t *testing.T) { ...@@ -270,20 +267,16 @@ func TestDataDir(t *testing.T) {
} }
func TestRollupRpc(t *testing.T) { func TestRollupRpc(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("RequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--rollup-rpc")) verifyArgsInvalid(t, "flag rollup-rpc is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--rollup-rpc"))
})
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--rollup-rpc"))
}) })
t.Run("RequiredForOutputCannonTrace", func(t *testing.T) { t.Run("RequiredForCannonTrace", func(t *testing.T) {
verifyArgsInvalid(t, "flag rollup-rpc is required", addRequiredArgsExcept(config.TraceTypeOutputCannon, "--rollup-rpc")) verifyArgsInvalid(t, "flag rollup-rpc is required", addRequiredArgsExcept(config.TraceTypeCannon, "--rollup-rpc"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeOutputCannon)) cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon))
require.Equal(t, rollupRpc, cfg.RollupRpc) require.Equal(t, rollupRpc, cfg.RollupRpc)
}) })
} }
...@@ -462,41 +455,25 @@ func requiredArgs(traceType config.TraceType) map[string]string { ...@@ -462,41 +455,25 @@ func requiredArgs(traceType config.TraceType) map[string]string {
"--datadir": datadir, "--datadir": datadir,
} }
switch traceType { switch traceType {
case config.TraceTypeAlphabet:
addRequiredAlphabetArgs(args)
case config.TraceTypeCannon: case config.TraceTypeCannon:
addRequiredCannonArgs(args) addRequiredCannonArgs(args)
case config.TraceTypeOutputCannon: case config.TraceTypeAlphabet:
addRequiredOutputCannonArgs(args) addRequiredOutputArgs(args)
case config.TraceTypeOutputAlphabet:
addRequiredOutputAlphabetArgs(args)
} }
return args return args
} }
func addRequiredAlphabetArgs(args map[string]string) {
args["--alphabet"] = alphabetTrace
}
func addRequiredOutputAlphabetArgs(args map[string]string) {
addRequiredOutputArgs(args)
}
func addRequiredOutputCannonArgs(args map[string]string) {
addRequiredCannonArgs(args)
addRequiredOutputArgs(args)
}
func addRequiredOutputArgs(args map[string]string) {
args["--rollup-rpc"] = rollupRpc
}
func addRequiredCannonArgs(args map[string]string) { func addRequiredCannonArgs(args map[string]string) {
args["--cannon-network"] = cannonNetwork args["--cannon-network"] = cannonNetwork
args["--cannon-bin"] = cannonBin args["--cannon-bin"] = cannonBin
args["--cannon-server"] = cannonServer args["--cannon-server"] = cannonServer
args["--cannon-prestate"] = cannonPreState args["--cannon-prestate"] = cannonPreState
args["--cannon-l2"] = cannonL2 args["--cannon-l2"] = cannonL2
addRequiredOutputArgs(args)
}
func addRequiredOutputArgs(args map[string]string) {
args["--rollup-rpc"] = rollupRpc
} }
func toArgList(req map[string]string) []string { func toArgList(req map[string]string) []string {
......
...@@ -23,7 +23,6 @@ var ( ...@@ -23,7 +23,6 @@ var (
ErrMissingCannonBin = errors.New("missing cannon bin") ErrMissingCannonBin = errors.New("missing cannon bin")
ErrMissingCannonServer = errors.New("missing cannon server") ErrMissingCannonServer = errors.New("missing cannon server")
ErrMissingCannonAbsolutePreState = errors.New("missing cannon absolute pre-state") ErrMissingCannonAbsolutePreState = errors.New("missing cannon absolute pre-state")
ErrMissingAlphabetTrace = errors.New("missing alphabet trace")
ErrMissingL1EthRPC = errors.New("missing l1 eth rpc url") ErrMissingL1EthRPC = errors.New("missing l1 eth rpc url")
ErrMissingGameFactoryAddress = errors.New("missing game factory address") ErrMissingGameFactoryAddress = errors.New("missing game factory address")
ErrMissingCannonSnapshotFreq = errors.New("missing cannon snapshot freq") ErrMissingCannonSnapshotFreq = errors.New("missing cannon snapshot freq")
...@@ -39,10 +38,8 @@ var ( ...@@ -39,10 +38,8 @@ var (
type TraceType string type TraceType string
const ( const (
TraceTypeAlphabet TraceType = "alphabet" TraceTypeAlphabet TraceType = "alphabet"
TraceTypeCannon TraceType = "cannon" TraceTypeCannon TraceType = "cannon"
TraceTypeOutputCannon TraceType = "output_cannon"
TraceTypeOutputAlphabet TraceType = "output_alphabet"
// Mainnet games // Mainnet games
CannonFaultGameID = 0 CannonFaultGameID = 0
...@@ -51,7 +48,7 @@ const ( ...@@ -51,7 +48,7 @@ const (
AlphabetFaultGameID = 255 AlphabetFaultGameID = 255
) )
var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypeOutputCannon, TraceTypeOutputAlphabet} var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon}
// GameIdToString maps game IDs to their string representation. // GameIdToString maps game IDs to their string representation.
var GameIdToString = map[uint8]string{ var GameIdToString = map[uint8]string{
...@@ -111,9 +108,6 @@ type Config struct { ...@@ -111,9 +108,6 @@ type Config struct {
TraceTypes []TraceType // Type of traces supported TraceTypes []TraceType // Type of traces supported
// Specific to the alphabet trace provider
AlphabetTrace string // String for the AlphabetTraceProvider
// Specific to the output cannon trace type // Specific to the output cannon trace type
RollupRpc string RollupRpc string
...@@ -167,6 +161,9 @@ func (c Config) Check() error { ...@@ -167,6 +161,9 @@ func (c Config) Check() error {
if c.L1EthRpc == "" { if c.L1EthRpc == "" {
return ErrMissingL1EthRPC return ErrMissingL1EthRPC
} }
if c.RollupRpc == "" {
return ErrMissingRollupRpc
}
if c.GameFactoryAddress == (common.Address{}) { if c.GameFactoryAddress == (common.Address{}) {
return ErrMissingGameFactoryAddress return ErrMissingGameFactoryAddress
} }
...@@ -179,12 +176,7 @@ func (c Config) Check() error { ...@@ -179,12 +176,7 @@ func (c Config) Check() error {
if c.MaxConcurrency == 0 { if c.MaxConcurrency == 0 {
return ErrMaxConcurrencyZero return ErrMaxConcurrencyZero
} }
if c.TraceTypeEnabled(TraceTypeOutputCannon) || c.TraceTypeEnabled(TraceTypeOutputAlphabet) { if c.TraceTypeEnabled(TraceTypeCannon) {
if c.RollupRpc == "" {
return ErrMissingRollupRpc
}
}
if c.TraceTypeEnabled(TraceTypeCannon) || c.TraceTypeEnabled(TraceTypeOutputCannon) {
if c.CannonBin == "" { if c.CannonBin == "" {
return ErrMissingCannonBin return ErrMissingCannonBin
} }
...@@ -222,9 +214,6 @@ func (c Config) Check() error { ...@@ -222,9 +214,6 @@ func (c Config) Check() error {
return ErrMissingCannonInfoFreq return ErrMissingCannonInfoFreq
} }
} }
if c.TraceTypeEnabled(TraceTypeAlphabet) && c.AlphabetTrace == "" {
return ErrMissingAlphabetTrace
}
if err := c.TxMgrConfig.Check(); err != nil { if err := c.TxMgrConfig.Check(); err != nil {
return err return err
} }
......
...@@ -13,7 +13,6 @@ import ( ...@@ -13,7 +13,6 @@ import (
var ( var (
validL1EthRpc = "http://localhost:8545" validL1EthRpc = "http://localhost:8545"
validGameFactoryAddress = common.Address{0x23} validGameFactoryAddress = common.Address{0x23}
validAlphabetTrace = "abcdefgh"
validCannonBin = "./bin/cannon" validCannonBin = "./bin/cannon"
validCannonOpProgramBin = "./bin/op-program" validCannonOpProgramBin = "./bin/op-program"
validCannonNetwork = "mainnet" validCannonNetwork = "mainnet"
...@@ -25,19 +24,14 @@ var ( ...@@ -25,19 +24,14 @@ var (
func validConfig(traceType TraceType) Config { func validConfig(traceType TraceType) Config {
cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validDatadir, traceType) cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validDatadir, traceType)
switch traceType { if traceType == TraceTypeCannon {
case TraceTypeAlphabet:
cfg.AlphabetTrace = validAlphabetTrace
case TraceTypeCannon, TraceTypeOutputCannon:
cfg.CannonBin = validCannonBin cfg.CannonBin = validCannonBin
cfg.CannonServer = validCannonOpProgramBin cfg.CannonServer = validCannonOpProgramBin
cfg.CannonAbsolutePreState = validCannonAbsolutPreState cfg.CannonAbsolutePreState = validCannonAbsolutPreState
cfg.CannonL2 = validCannonL2 cfg.CannonL2 = validCannonL2
cfg.CannonNetwork = validCannonNetwork cfg.CannonNetwork = validCannonNetwork
} }
if traceType == TraceTypeOutputCannon || traceType == TraceTypeOutputAlphabet { cfg.RollupRpc = validRollupRpc
cfg.RollupRpc = validRollupRpc
}
return cfg return cfg
} }
...@@ -78,18 +72,6 @@ func TestGameAllowlistNotRequired(t *testing.T) { ...@@ -78,18 +72,6 @@ func TestGameAllowlistNotRequired(t *testing.T) {
require.NoError(t, config.Check()) require.NoError(t, config.Check())
} }
func TestAlphabetTraceRequired(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config.AlphabetTrace = ""
require.ErrorIs(t, config.Check(), ErrMissingAlphabetTrace)
}
func TestAlphabetTraceNotRequiredForOutputAlphabet(t *testing.T) {
config := validConfig(TraceTypeOutputAlphabet)
config.AlphabetTrace = ""
require.NoError(t, config.Check())
}
func TestCannonBinRequired(t *testing.T) { func TestCannonBinRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(TraceTypeCannon)
config.CannonBin = "" config.CannonBin = ""
...@@ -134,14 +116,14 @@ func TestHttpPollInterval(t *testing.T) { ...@@ -134,14 +116,14 @@ func TestHttpPollInterval(t *testing.T) {
}) })
} }
func TestRollupRpcRequired_OutputCannon(t *testing.T) { func TestRollupRpcRequired_Cannon(t *testing.T) {
config := validConfig(TraceTypeOutputCannon) config := validConfig(TraceTypeCannon)
config.RollupRpc = "" config.RollupRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingRollupRpc) require.ErrorIs(t, config.Check(), ErrMissingRollupRpc)
} }
func TestRollupRpcRequired_OutputAlphabet(t *testing.T) { func TestRollupRpcRequired_Alphabet(t *testing.T) {
config := validConfig(TraceTypeOutputAlphabet) config := validConfig(TraceTypeAlphabet)
config.RollupRpc = "" config.RollupRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingRollupRpc) require.ErrorIs(t, config.Check(), ErrMissingRollupRpc)
} }
...@@ -208,10 +190,9 @@ func TestNetworkMustBeValid(t *testing.T) { ...@@ -208,10 +190,9 @@ func TestNetworkMustBeValid(t *testing.T) {
func TestRequireConfigForMultipleTraceTypes(t *testing.T) { func TestRequireConfigForMultipleTraceTypes(t *testing.T) {
cfg := validConfig(TraceTypeCannon) cfg := validConfig(TraceTypeCannon)
cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeAlphabet, TraceTypeOutputCannon} cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeAlphabet}
// Set all required options and check its valid // Set all required options and check its valid
cfg.RollupRpc = validRollupRpc cfg.RollupRpc = validRollupRpc
cfg.AlphabetTrace = validAlphabetTrace
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
// Require cannon specific args // Require cannon specific args
...@@ -219,11 +200,6 @@ func TestRequireConfigForMultipleTraceTypes(t *testing.T) { ...@@ -219,11 +200,6 @@ func TestRequireConfigForMultipleTraceTypes(t *testing.T) {
require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2) require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2)
cfg.CannonL2 = validCannonL2 cfg.CannonL2 = validCannonL2
// Require alphabet specific args
cfg.AlphabetTrace = ""
require.ErrorIs(t, cfg.Check(), ErrMissingAlphabetTrace)
cfg.AlphabetTrace = validAlphabetTrace
// Require output cannon specific args // Require output cannon specific args
cfg.RollupRpc = "" cfg.RollupRpc = ""
require.ErrorIs(t, cfg.Check(), ErrMissingRollupRpc) require.ErrorIs(t, cfg.Check(), ErrMissingRollupRpc)
......
...@@ -73,11 +73,6 @@ var ( ...@@ -73,11 +73,6 @@ var (
Usage: "HTTP provider URL for the rollup node", Usage: "HTTP provider URL for the rollup node",
EnvVars: prefixEnvVars("ROLLUP_RPC"), EnvVars: prefixEnvVars("ROLLUP_RPC"),
} }
AlphabetFlag = &cli.StringFlag{
Name: "alphabet",
Usage: "Correct Alphabet Trace (alphabet trace type only)",
EnvVars: prefixEnvVars("ALPHABET"),
}
CannonNetworkFlag = &cli.StringFlag{ CannonNetworkFlag = &cli.StringFlag{
Name: "cannon-network", Name: "cannon-network",
Usage: fmt.Sprintf( Usage: fmt.Sprintf(
...@@ -149,7 +144,6 @@ var optionalFlags = []cli.Flag{ ...@@ -149,7 +144,6 @@ var optionalFlags = []cli.Flag{
MaxConcurrencyFlag, MaxConcurrencyFlag,
HTTPPollInterval, HTTPPollInterval,
RollupRpcFlag, RollupRpcFlag,
AlphabetFlag,
GameAllowlistFlag, GameAllowlistFlag,
CannonNetworkFlag, CannonNetworkFlag,
CannonRollupConfigFlag, CannonRollupConfigFlag,
...@@ -213,18 +207,10 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error { ...@@ -213,18 +207,10 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error {
if err := CheckCannonFlags(ctx); err != nil { if err := CheckCannonFlags(ctx); err != nil {
return err return err
} }
case config.TraceTypeAlphabet:
if !ctx.IsSet(AlphabetFlag.Name) {
return fmt.Errorf("flag %s is required", "alphabet")
}
case config.TraceTypeOutputCannon:
if err := CheckCannonFlags(ctx); err != nil {
return err
}
if !ctx.IsSet(RollupRpcFlag.Name) { if !ctx.IsSet(RollupRpcFlag.Name) {
return fmt.Errorf("flag %s is required", RollupRpcFlag.Name) return fmt.Errorf("flag %s is required", RollupRpcFlag.Name)
} }
case config.TraceTypeOutputAlphabet: case config.TraceTypeAlphabet:
if !ctx.IsSet(RollupRpcFlag.Name) { if !ctx.IsSet(RollupRpcFlag.Name) {
return fmt.Errorf("flag %s is required", RollupRpcFlag.Name) return fmt.Errorf("flag %s is required", RollupRpcFlag.Name)
} }
...@@ -291,7 +277,6 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) { ...@@ -291,7 +277,6 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
MaxConcurrency: maxConcurrency, MaxConcurrency: maxConcurrency,
PollInterval: ctx.Duration(HTTPPollInterval.Name), PollInterval: ctx.Duration(HTTPPollInterval.Name),
RollupRpc: ctx.String(RollupRpcFlag.Name), RollupRpc: ctx.String(RollupRpcFlag.Name),
AlphabetTrace: ctx.String(AlphabetFlag.Name),
CannonNetwork: ctx.String(CannonNetworkFlag.Name), CannonNetwork: ctx.String(CannonNetworkFlag.Name),
CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name), CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name),
CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name), CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name),
......
...@@ -13,42 +13,25 @@ import ( ...@@ -13,42 +13,25 @@ import (
) )
const ( const (
methodGameDurationV0 = "GAME_DURATION" methodGameDuration = "gameDuration"
methodMaxGameDepthV0 = "MAX_GAME_DEPTH" methodMaxGameDepth = "maxGameDepth"
methodAbsolutePrestateV0 = "ABSOLUTE_PRESTATE" methodAbsolutePrestate = "absolutePrestate"
methodGameDurationV1 = "gameDuration" methodStatus = "status"
methodMaxGameDepthV1 = "maxGameDepth" methodClaimCount = "claimDataLen"
methodAbsolutePrestateV1 = "absolutePrestate" methodClaim = "claimData"
methodStatus = "status" methodL1Head = "l1Head"
methodClaimCount = "claimDataLen" methodResolve = "resolve"
methodClaim = "claimData" methodResolveClaim = "resolveClaim"
methodL1Head = "l1Head" methodAttack = "attack"
methodResolve = "resolve" methodDefend = "defend"
methodResolveClaim = "resolveClaim" methodStep = "step"
methodAttack = "attack" methodAddLocalData = "addLocalData"
methodDefend = "defend" methodVM = "vm"
methodStep = "step"
methodAddLocalData = "addLocalData"
methodVMV0 = "VM"
methodVMV1 = "vm"
) )
type disputeGameContract struct { type disputeGameContract struct {
multiCaller *batching.MultiCaller multiCaller *batching.MultiCaller
contract *batching.BoundContract contract *batching.BoundContract
// The version byte signifies the version of the dispute game contract due to mismatching function selectors.
// 0 = `FaultDisputeGame`
// 1 = `OutputBisectionGame`
version uint8
}
// contractProposal matches the structure for output root proposals used by the contracts.
// It must exactly match the contract structure. The exposed API uses Proposal to decouple the contract
// and challenger representations of the proposal data.
type contractProposal struct {
Index *big.Int
L2BlockNumber *big.Int
OutputRoot common.Hash
} }
type Proposal struct { type Proposal struct {
...@@ -56,21 +39,7 @@ type Proposal struct { ...@@ -56,21 +39,7 @@ type Proposal struct {
OutputRoot common.Hash OutputRoot common.Hash
} }
func asProposal(p contractProposal) Proposal {
return Proposal{
L2BlockNumber: p.L2BlockNumber,
OutputRoot: p.OutputRoot,
}
}
func (f *disputeGameContract) GetGameDuration(ctx context.Context) (uint64, error) { func (f *disputeGameContract) GetGameDuration(ctx context.Context) (uint64, error) {
var methodGameDuration string
if f.version == 1 {
methodGameDuration = methodGameDurationV1
} else {
methodGameDuration = methodGameDurationV0
}
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodGameDuration)) result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodGameDuration))
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to fetch game duration: %w", err) return 0, fmt.Errorf("failed to fetch game duration: %w", err)
...@@ -79,13 +48,6 @@ func (f *disputeGameContract) GetGameDuration(ctx context.Context) (uint64, erro ...@@ -79,13 +48,6 @@ func (f *disputeGameContract) GetGameDuration(ctx context.Context) (uint64, erro
} }
func (f *disputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, error) { func (f *disputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, error) {
var methodMaxGameDepth string
if f.version == 1 {
methodMaxGameDepth = methodMaxGameDepthV1
} else {
methodMaxGameDepth = methodMaxGameDepthV0
}
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodMaxGameDepth)) result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodMaxGameDepth))
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to fetch max game depth: %w", err) return 0, fmt.Errorf("failed to fetch max game depth: %w", err)
...@@ -94,13 +56,6 @@ func (f *disputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, erro ...@@ -94,13 +56,6 @@ func (f *disputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, erro
} }
func (f *disputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { func (f *disputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) {
var methodAbsolutePrestate string
if f.version == 1 {
methodAbsolutePrestate = methodAbsolutePrestateV1
} else {
methodAbsolutePrestate = methodAbsolutePrestateV0
}
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodAbsolutePrestate)) result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodAbsolutePrestate))
if err != nil { if err != nil {
return common.Hash{}, fmt.Errorf("failed to fetch absolute prestate hash: %w", err) return common.Hash{}, fmt.Errorf("failed to fetch absolute prestate hash: %w", err)
...@@ -164,13 +119,6 @@ func (f *disputeGameContract) GetAllClaims(ctx context.Context) ([]types.Claim, ...@@ -164,13 +119,6 @@ func (f *disputeGameContract) GetAllClaims(ctx context.Context) ([]types.Claim,
} }
func (f *disputeGameContract) vm(ctx context.Context) (*VMContract, error) { func (f *disputeGameContract) vm(ctx context.Context) (*VMContract, error) {
var methodVM string
if f.version == 1 {
methodVM = methodVMV1
} else {
methodVM = methodVMV0
}
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodVM)) result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodVM))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch VM addr: %w", err) return nil, fmt.Errorf("failed to fetch VM addr: %w", err)
......
...@@ -49,7 +49,7 @@ func runCommonDisputeGameTests(t *testing.T, setup disputeGameSetupFunc) { ...@@ -49,7 +49,7 @@ func runCommonDisputeGameTests(t *testing.T, setup disputeGameSetupFunc) {
func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) { func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) {
tests := []struct { tests := []struct {
methodAlias string methodAlias string
method func(game *disputeGameContract) string method string
args []interface{} args []interface{}
result interface{} result interface{}
expected interface{} // Defaults to expecting the same as result expected interface{} // Defaults to expecting the same as result
...@@ -57,7 +57,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) { ...@@ -57,7 +57,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) {
}{ }{
{ {
methodAlias: "status", methodAlias: "status",
method: func(game *disputeGameContract) string { return methodStatus }, method: methodStatus,
result: types.GameStatusChallengerWon, result: types.GameStatusChallengerWon,
call: func(game *disputeGameContract) (any, error) { call: func(game *disputeGameContract) (any, error) {
return game.GetStatus(context.Background()) return game.GetStatus(context.Background())
...@@ -65,50 +65,32 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) { ...@@ -65,50 +65,32 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) {
}, },
{ {
methodAlias: "gameDuration", methodAlias: "gameDuration",
method: func(game *disputeGameContract) string { method: methodGameDuration,
if game.version == 1 { result: uint64(5566),
return methodGameDurationV1
} else {
return methodGameDurationV0
}
},
result: uint64(5566),
call: func(game *disputeGameContract) (any, error) { call: func(game *disputeGameContract) (any, error) {
return game.GetGameDuration(context.Background()) return game.GetGameDuration(context.Background())
}, },
}, },
{ {
methodAlias: "maxGameDepth", methodAlias: "maxGameDepth",
method: func(game *disputeGameContract) string { method: methodMaxGameDepth,
if game.version == 1 { result: big.NewInt(128),
return methodMaxGameDepthV1 expected: uint64(128),
} else {
return methodMaxGameDepthV0
}
},
result: big.NewInt(128),
expected: uint64(128),
call: func(game *disputeGameContract) (any, error) { call: func(game *disputeGameContract) (any, error) {
return game.GetMaxGameDepth(context.Background()) return game.GetMaxGameDepth(context.Background())
}, },
}, },
{ {
methodAlias: "absolutePrestate", methodAlias: "absolutePrestate",
method: func(game *disputeGameContract) string { method: methodAbsolutePrestate,
if game.version == 1 { result: common.Hash{0xab},
return methodAbsolutePrestateV1
} else {
return methodAbsolutePrestateV0
}
},
result: common.Hash{0xab},
call: func(game *disputeGameContract) (any, error) { call: func(game *disputeGameContract) (any, error) {
return game.GetAbsolutePrestateHash(context.Background()) return game.GetAbsolutePrestateHash(context.Background())
}, },
}, },
{ {
methodAlias: "claimCount", methodAlias: "claimCount",
method: func(game *disputeGameContract) string { return methodClaimCount }, method: methodClaimCount,
result: big.NewInt(9876), result: big.NewInt(9876),
expected: uint64(9876), expected: uint64(9876),
call: func(game *disputeGameContract) (any, error) { call: func(game *disputeGameContract) (any, error) {
...@@ -117,7 +99,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) { ...@@ -117,7 +99,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) {
}, },
{ {
methodAlias: "l1Head", methodAlias: "l1Head",
method: func(game *disputeGameContract) string { return methodL1Head }, method: methodL1Head,
result: common.Hash{0xdd, 0xbb}, result: common.Hash{0xdd, 0xbb},
call: func(game *disputeGameContract) (any, error) { call: func(game *disputeGameContract) (any, error) {
return game.GetL1Head(context.Background()) return game.GetL1Head(context.Background())
...@@ -125,7 +107,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) { ...@@ -125,7 +107,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) {
}, },
{ {
methodAlias: "resolve", methodAlias: "resolve",
method: func(game *disputeGameContract) string { return methodResolve }, method: methodResolve,
result: types.GameStatusInProgress, result: types.GameStatusInProgress,
call: func(game *disputeGameContract) (any, error) { call: func(game *disputeGameContract) (any, error) {
return game.CallResolve(context.Background()) return game.CallResolve(context.Background())
...@@ -136,7 +118,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) { ...@@ -136,7 +118,7 @@ func runSimpleGettersTest(t *testing.T, setup disputeGameSetupFunc) {
test := test test := test
t.Run(test.methodAlias, func(t *testing.T) { t.Run(test.methodAlias, func(t *testing.T) {
stubRpc, game := setup(t) stubRpc, game := setup(t)
stubRpc.SetResponse(fdgAddr, test.method(game), batching.BlockLatest, nil, []interface{}{test.result}) stubRpc.SetResponse(fdgAddr, test.method, batching.BlockLatest, nil, []interface{}{test.result})
status, err := test.call(game) status, err := test.call(game)
require.NoError(t, err) require.NoError(t, err)
expected := test.expected expected := test.expected
......
...@@ -12,8 +12,11 @@ import ( ...@@ -12,8 +12,11 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )
const ( var (
methodProposals = "proposals" methodGenesisBlockNumber = "genesisBlockNumber"
methodGenesisOutputRoot = "genesisOutputRoot"
methodSplitDepth = "splitDepth"
methodL2BlockNumber = "l2BlockNumber"
) )
type FaultDisputeGameContract struct { type FaultDisputeGameContract struct {
...@@ -21,7 +24,7 @@ type FaultDisputeGameContract struct { ...@@ -21,7 +24,7 @@ type FaultDisputeGameContract struct {
} }
func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCaller) (*FaultDisputeGameContract, error) { func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCaller) (*FaultDisputeGameContract, error) {
fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() contractAbi, err := bindings.FaultDisputeGameMetaData.GetAbi()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to load fault dispute game ABI: %w", err) return nil, fmt.Errorf("failed to load fault dispute game ABI: %w", err)
} }
...@@ -29,37 +32,58 @@ func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCall ...@@ -29,37 +32,58 @@ func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCall
return &FaultDisputeGameContract{ return &FaultDisputeGameContract{
disputeGameContract: disputeGameContract{ disputeGameContract: disputeGameContract{
multiCaller: caller, multiCaller: caller,
contract: batching.NewBoundContract(fdgAbi, addr), contract: batching.NewBoundContract(contractAbi, addr),
version: 0,
}, },
}, nil }, nil
} }
// GetProposals returns the agreed and disputed proposals // GetBlockRange returns the block numbers of the absolute pre-state block (typically genesis or the bedrock activation block)
func (f *FaultDisputeGameContract) GetProposals(ctx context.Context) (Proposal, Proposal, error) { // and the post-state block (that the proposed output root is for).
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodProposals)) func (c *FaultDisputeGameContract) GetBlockRange(ctx context.Context) (prestateBlock uint64, poststateBlock uint64, retErr error) {
results, err := c.multiCaller.Call(ctx, batching.BlockLatest,
c.contract.Call(methodGenesisBlockNumber),
c.contract.Call(methodL2BlockNumber))
if err != nil { if err != nil {
return Proposal{}, Proposal{}, fmt.Errorf("failed to fetch proposals: %w", err) retErr = fmt.Errorf("failed to retrieve game block range: %w", err)
return
} }
if len(results) != 2 {
retErr = fmt.Errorf("expected 2 results but got %v", len(results))
return
}
prestateBlock = results[0].GetBigInt(0).Uint64()
poststateBlock = results[1].GetBigInt(0).Uint64()
return
}
func (c *FaultDisputeGameContract) GetGenesisOutputRoot(ctx context.Context) (common.Hash, error) {
genesisOutputRoot, err := c.multiCaller.SingleCall(ctx, batching.BlockLatest, c.contract.Call(methodGenesisOutputRoot))
if err != nil {
return common.Hash{}, fmt.Errorf("failed to retrieve genesis output root: %w", err)
}
return genesisOutputRoot.GetHash(0), nil
}
var agreed, disputed contractProposal func (c *FaultDisputeGameContract) GetSplitDepth(ctx context.Context) (uint64, error) {
result.GetStruct(0, &agreed) splitDepth, err := c.multiCaller.SingleCall(ctx, batching.BlockLatest, c.contract.Call(methodSplitDepth))
result.GetStruct(1, &disputed) if err != nil {
return asProposal(agreed), asProposal(disputed), nil return 0, fmt.Errorf("failed to retrieve split depth: %w", err)
}
return splitDepth.GetBigInt(0).Uint64(), nil
} }
func (f *FaultDisputeGameContract) UpdateOracleTx(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) { func (f *FaultDisputeGameContract) UpdateOracleTx(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) {
if data.IsLocal { if data.IsLocal {
return f.addLocalDataTx(data) return f.addLocalDataTx(claimIdx, data)
} }
return f.addGlobalDataTx(ctx, data) return f.addGlobalDataTx(ctx, data)
} }
func (f *FaultDisputeGameContract) addLocalDataTx(data *types.PreimageOracleData) (txmgr.TxCandidate, error) { func (f *FaultDisputeGameContract) addLocalDataTx(claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) {
call := f.contract.Call( call := f.contract.Call(
methodAddLocalData, methodAddLocalData,
data.GetIdent(), data.GetIdent(),
types.NoLocalContext, new(big.Int).SetUint64(claimIdx),
new(big.Int).SetUint64(uint64(data.OracleOffset)), new(big.Int).SetUint64(uint64(data.OracleOffset)),
) )
return call.ToTxCandidate() return call.ToTxCandidate()
......
...@@ -20,39 +20,34 @@ func TestFaultDisputeGameContract_CommonTests(t *testing.T) { ...@@ -20,39 +20,34 @@ func TestFaultDisputeGameContract_CommonTests(t *testing.T) {
}) })
} }
func TestGetProposals(t *testing.T) { func TestGetBlockRange(t *testing.T) {
stubRpc, game := setupFaultDisputeGameTest(t) stubRpc, contract := setupFaultDisputeGameTest(t)
agreedIndex := big.NewInt(5) expectedStart := uint64(65)
agreedBlockNum := big.NewInt(6) expectedEnd := uint64(102)
agreedRoot := common.Hash{0xaa} stubRpc.SetResponse(fdgAddr, methodGenesisBlockNumber, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(expectedStart)})
disputedIndex := big.NewInt(7) stubRpc.SetResponse(fdgAddr, methodL2BlockNumber, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(expectedEnd)})
disputedBlockNum := big.NewInt(8) start, end, err := contract.GetBlockRange(context.Background())
disputedRoot := common.Hash{0xdd} require.NoError(t, err)
agreed := contractProposal{ require.Equal(t, expectedStart, start)
Index: agreedIndex, require.Equal(t, expectedEnd, end)
L2BlockNumber: agreedBlockNum, }
OutputRoot: agreedRoot,
} func TestGetSplitDepth(t *testing.T) {
disputed := contractProposal{ stubRpc, contract := setupFaultDisputeGameTest(t)
Index: disputedIndex, expectedSplitDepth := uint64(15)
L2BlockNumber: disputedBlockNum, stubRpc.SetResponse(fdgAddr, methodSplitDepth, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(expectedSplitDepth)})
OutputRoot: disputedRoot, splitDepth, err := contract.GetSplitDepth(context.Background())
} require.NoError(t, err)
expectedAgreed := Proposal{ require.Equal(t, expectedSplitDepth, splitDepth)
L2BlockNumber: agreed.L2BlockNumber, }
OutputRoot: agreed.OutputRoot,
} func TestGetGenesisOutputRoot(t *testing.T) {
expectedDisputed := Proposal{ stubRpc, contract := setupFaultDisputeGameTest(t)
L2BlockNumber: disputed.L2BlockNumber, expectedOutputRoot := common.HexToHash("0x1234")
OutputRoot: disputed.OutputRoot, stubRpc.SetResponse(fdgAddr, methodGenesisOutputRoot, batching.BlockLatest, nil, []interface{}{expectedOutputRoot})
} genesisOutputRoot, err := contract.GetGenesisOutputRoot(context.Background())
stubRpc.SetResponse(fdgAddr, methodProposals, batching.BlockLatest, []interface{}{}, []interface{}{
agreed, disputed,
})
actualAgreed, actualDisputed, err := game.GetProposals(context.Background())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, expectedAgreed, actualAgreed) require.Equal(t, expectedOutputRoot, genesisOutputRoot)
require.Equal(t, expectedDisputed, actualDisputed)
} }
func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) { func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) {
...@@ -67,7 +62,7 @@ func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) { ...@@ -67,7 +62,7 @@ func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) {
claimIdx := uint64(6) claimIdx := uint64(6)
stubRpc.SetResponse(fdgAddr, methodAddLocalData, batching.BlockLatest, []interface{}{ stubRpc.SetResponse(fdgAddr, methodAddLocalData, batching.BlockLatest, []interface{}{
data.GetIdent(), data.GetIdent(),
faultTypes.NoLocalContext, new(big.Int).SetUint64(claimIdx),
new(big.Int).SetUint64(uint64(data.OracleOffset)), new(big.Int).SetUint64(uint64(data.OracleOffset)),
}, nil) }, nil)
tx, err := game.UpdateOracleTx(context.Background(), claimIdx, data) tx, err := game.UpdateOracleTx(context.Background(), claimIdx, data)
...@@ -84,7 +79,7 @@ func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) { ...@@ -84,7 +79,7 @@ func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) {
OracleOffset: 16, OracleOffset: 16,
} }
claimIdx := uint64(6) claimIdx := uint64(6)
stubRpc.SetResponse(fdgAddr, methodVMV0, batching.BlockLatest, nil, []interface{}{vmAddr}) stubRpc.SetResponse(fdgAddr, methodVM, batching.BlockLatest, nil, []interface{}{vmAddr})
stubRpc.SetResponse(vmAddr, methodOracle, batching.BlockLatest, nil, []interface{}{oracleAddr}) stubRpc.SetResponse(vmAddr, methodOracle, batching.BlockLatest, nil, []interface{}{oracleAddr})
stubRpc.SetResponse(oracleAddr, methodLoadKeccak256PreimagePart, batching.BlockLatest, []interface{}{ stubRpc.SetResponse(oracleAddr, methodLoadKeccak256PreimagePart, batching.BlockLatest, []interface{}{
new(big.Int).SetUint64(uint64(data.OracleOffset)), new(big.Int).SetUint64(uint64(data.OracleOffset)),
......
package contracts
import (
"context"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
)
var (
methodGenesisBlockNumber = "genesisBlockNumber"
methodGenesisOutputRoot = "genesisOutputRoot"
methodSplitDepth = "splitDepth"
methodL2BlockNumber = "l2BlockNumber"
)
type OutputBisectionGameContract struct {
disputeGameContract
}
func NewOutputBisectionGameContract(addr common.Address, caller *batching.MultiCaller) (*OutputBisectionGameContract, error) {
contractAbi, err := bindings.OutputBisectionGameMetaData.GetAbi()
if err != nil {
return nil, fmt.Errorf("failed to load output bisection game ABI: %w", err)
}
return &OutputBisectionGameContract{
disputeGameContract: disputeGameContract{
multiCaller: caller,
contract: batching.NewBoundContract(contractAbi, addr),
version: 1,
},
}, nil
}
// GetBlockRange returns the block numbers of the absolute pre-state block (typically genesis or the bedrock activation block)
// and the post-state block (that the proposed output root is for).
func (c *OutputBisectionGameContract) GetBlockRange(ctx context.Context) (prestateBlock uint64, poststateBlock uint64, retErr error) {
results, err := c.multiCaller.Call(ctx, batching.BlockLatest,
c.contract.Call(methodGenesisBlockNumber),
c.contract.Call(methodL2BlockNumber))
if err != nil {
retErr = fmt.Errorf("failed to retrieve game block range: %w", err)
return
}
if len(results) != 2 {
retErr = fmt.Errorf("expected 2 results but got %v", len(results))
return
}
prestateBlock = results[0].GetBigInt(0).Uint64()
poststateBlock = results[1].GetBigInt(0).Uint64()
return
}
func (c *OutputBisectionGameContract) GetGenesisOutputRoot(ctx context.Context) (common.Hash, error) {
genesisOutputRoot, err := c.multiCaller.SingleCall(ctx, batching.BlockLatest, c.contract.Call(methodGenesisOutputRoot))
if err != nil {
return common.Hash{}, fmt.Errorf("failed to retrieve genesis output root: %w", err)
}
return genesisOutputRoot.GetHash(0), nil
}
func (c *OutputBisectionGameContract) GetSplitDepth(ctx context.Context) (uint64, error) {
splitDepth, err := c.multiCaller.SingleCall(ctx, batching.BlockLatest, c.contract.Call(methodSplitDepth))
if err != nil {
return 0, fmt.Errorf("failed to retrieve split depth: %w", err)
}
return splitDepth.GetBigInt(0).Uint64(), nil
}
func (f *OutputBisectionGameContract) UpdateOracleTx(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) {
if data.IsLocal {
return f.addLocalDataTx(claimIdx, data)
}
return f.addGlobalDataTx(ctx, data)
}
func (f *OutputBisectionGameContract) addLocalDataTx(claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) {
call := f.contract.Call(
methodAddLocalData,
data.GetIdent(),
new(big.Int).SetUint64(claimIdx),
new(big.Int).SetUint64(uint64(data.OracleOffset)),
)
return call.ToTxCandidate()
}
func (f *OutputBisectionGameContract) addGlobalDataTx(ctx context.Context, data *types.PreimageOracleData) (txmgr.TxCandidate, error) {
vm, err := f.vm(ctx)
if err != nil {
return txmgr.TxCandidate{}, err
}
oracle, err := vm.Oracle(ctx)
if err != nil {
return txmgr.TxCandidate{}, err
}
return oracle.AddGlobalDataTx(data)
}
package contracts
import (
"context"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestOutputBisectionGameContract_CommonTests(t *testing.T) {
runCommonDisputeGameTests(t, func(t *testing.T) (*batchingTest.AbiBasedRpc, *disputeGameContract) {
stubRpc, contract := setupOutputBisectionGameTest(t)
return stubRpc, &contract.disputeGameContract
})
}
func TestGetBlockRange(t *testing.T) {
stubRpc, contract := setupOutputBisectionGameTest(t)
expectedStart := uint64(65)
expectedEnd := uint64(102)
stubRpc.SetResponse(fdgAddr, methodGenesisBlockNumber, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(expectedStart)})
stubRpc.SetResponse(fdgAddr, methodL2BlockNumber, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(expectedEnd)})
start, end, err := contract.GetBlockRange(context.Background())
require.NoError(t, err)
require.Equal(t, expectedStart, start)
require.Equal(t, expectedEnd, end)
}
func TestGetSplitDepth(t *testing.T) {
stubRpc, contract := setupOutputBisectionGameTest(t)
expectedSplitDepth := uint64(15)
stubRpc.SetResponse(fdgAddr, methodSplitDepth, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(expectedSplitDepth)})
splitDepth, err := contract.GetSplitDepth(context.Background())
require.NoError(t, err)
require.Equal(t, expectedSplitDepth, splitDepth)
}
func TestGetGenesisOutputRoot(t *testing.T) {
stubRpc, contract := setupOutputBisectionGameTest(t)
expectedOutputRoot := common.HexToHash("0x1234")
stubRpc.SetResponse(fdgAddr, methodGenesisOutputRoot, batching.BlockLatest, nil, []interface{}{expectedOutputRoot})
genesisOutputRoot, err := contract.GetGenesisOutputRoot(context.Background())
require.NoError(t, err)
require.Equal(t, expectedOutputRoot, genesisOutputRoot)
}
func TestOutputBisectionGame_UpdateOracleTx(t *testing.T) {
t.Run("Local", func(t *testing.T) {
stubRpc, game := setupOutputBisectionGameTest(t)
data := &faultTypes.PreimageOracleData{
IsLocal: true,
OracleKey: common.Hash{0xbc}.Bytes(),
OracleData: []byte{1, 2, 3, 4, 5, 6, 7},
OracleOffset: 16,
}
claimIdx := uint64(6)
stubRpc.SetResponse(fdgAddr, methodAddLocalData, batching.BlockLatest, []interface{}{
data.GetIdent(),
new(big.Int).SetUint64(claimIdx),
new(big.Int).SetUint64(uint64(data.OracleOffset)),
}, nil)
tx, err := game.UpdateOracleTx(context.Background(), claimIdx, data)
require.NoError(t, err)
stubRpc.VerifyTxCandidate(tx)
})
t.Run("Global", func(t *testing.T) {
stubRpc, game := setupOutputBisectionGameTest(t)
data := &faultTypes.PreimageOracleData{
IsLocal: false,
OracleKey: common.Hash{0xbc}.Bytes(),
OracleData: []byte{1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15},
OracleOffset: 16,
}
claimIdx := uint64(6)
stubRpc.SetResponse(fdgAddr, methodVMV1, batching.BlockLatest, nil, []interface{}{vmAddr})
stubRpc.SetResponse(vmAddr, methodOracle, batching.BlockLatest, nil, []interface{}{oracleAddr})
stubRpc.SetResponse(oracleAddr, methodLoadKeccak256PreimagePart, batching.BlockLatest, []interface{}{
new(big.Int).SetUint64(uint64(data.OracleOffset)),
data.GetPreimageWithoutSize(),
}, nil)
tx, err := game.UpdateOracleTx(context.Background(), claimIdx, data)
require.NoError(t, err)
stubRpc.VerifyTxCandidate(tx)
})
}
func setupOutputBisectionGameTest(t *testing.T) (*batchingTest.AbiBasedRpc, *OutputBisectionGameContract) {
fdgAbi, err := bindings.OutputBisectionGameMetaData.GetAbi()
require.NoError(t, err)
vmAbi, err := bindings.MIPSMetaData.GetAbi()
require.NoError(t, err)
oracleAbi, err := bindings.PreimageOracleMetaData.GetAbi()
require.NoError(t, err)
stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAddr, fdgAbi)
stubRpc.AddContract(vmAddr, vmAbi)
stubRpc.AddContract(oracleAddr, oracleAbi)
caller := batching.NewMultiCaller(stubRpc, batching.DefaultBatchSize)
game, err := NewOutputBisectionGameContract(fdgAddr, caller)
require.NoError(t, err)
return stubRpc, game
}
...@@ -6,8 +6,6 @@ import ( ...@@ -6,8 +6,6 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
...@@ -21,10 +19,8 @@ import ( ...@@ -21,10 +19,8 @@ import (
) )
var ( var (
cannonGameType = uint8(0) cannonGameType = uint8(0)
outputCannonGameType = uint8(1) alphabetGameType = uint8(255)
outputAlphabetGameType = uint8(254)
alphabetGameType = uint8(255)
) )
type CloseFunc func() type CloseFunc func()
...@@ -45,7 +41,7 @@ func RegisterGameTypes( ...@@ -45,7 +41,7 @@ func RegisterGameTypes(
) (CloseFunc, error) { ) (CloseFunc, error) {
var closer CloseFunc var closer CloseFunc
var l2Client *ethclient.Client var l2Client *ethclient.Client
if cfg.TraceTypeEnabled(config.TraceTypeCannon) || cfg.TraceTypeEnabled(config.TraceTypeOutputCannon) { if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
l2, err := ethclient.DialContext(ctx, cfg.CannonL2) l2, err := ethclient.DialContext(ctx, cfg.CannonL2)
if err != nil { if err != nil {
return nil, fmt.Errorf("dial l2 client %v: %w", cfg.CannonL2, err) return nil, fmt.Errorf("dial l2 client %v: %w", cfg.CannonL2, err)
...@@ -53,31 +49,26 @@ func RegisterGameTypes( ...@@ -53,31 +49,26 @@ func RegisterGameTypes(
l2Client = l2 l2Client = l2
closer = l2Client.Close closer = l2Client.Close
} }
if cfg.TraceTypeEnabled(config.TraceTypeOutputCannon) {
registerOutputCannon(registry, ctx, logger, m, cfg, rollupClient, txMgr, caller, l2Client)
}
if cfg.TraceTypeEnabled(config.TraceTypeOutputAlphabet) {
registerOutputAlphabet(registry, ctx, logger, m, rollupClient, txMgr, caller)
}
if cfg.TraceTypeEnabled(config.TraceTypeCannon) { if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
registerCannon(registry, ctx, logger, m, cfg, txMgr, caller, l2Client) registerCannon(registry, ctx, logger, m, cfg, rollupClient, txMgr, caller, l2Client)
} }
if cfg.TraceTypeEnabled(config.TraceTypeAlphabet) { if cfg.TraceTypeEnabled(config.TraceTypeAlphabet) {
registerAlphabet(registry, ctx, logger, m, cfg.AlphabetTrace, txMgr, caller) registerAlphabet(registry, ctx, logger, m, rollupClient, txMgr, caller)
} }
return closer, nil return closer, nil
} }
func registerOutputAlphabet( func registerAlphabet(
registry Registry, registry Registry,
ctx context.Context, ctx context.Context,
logger log.Logger, logger log.Logger,
m metrics.Metricer, m metrics.Metricer,
rollupClient outputs.OutputRollupClient, rollupClient outputs.OutputRollupClient,
txMgr txmgr.TxManager, txMgr txmgr.TxManager,
caller *batching.MultiCaller) { caller *batching.MultiCaller,
) {
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewOutputBisectionGameContract(game.Proxy, caller) contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -101,10 +92,10 @@ func registerOutputAlphabet( ...@@ -101,10 +92,10 @@ func registerOutputAlphabet(
genesisValidator := NewPrestateValidator(contract.GetGenesisOutputRoot, prestateProvider) genesisValidator := NewPrestateValidator(contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{prestateValidator, genesisValidator}, creator) return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{prestateValidator, genesisValidator}, creator)
} }
registry.RegisterGameType(outputAlphabetGameType, playerCreator) registry.RegisterGameType(alphabetGameType, playerCreator)
} }
func registerOutputCannon( func registerCannon(
registry Registry, registry Registry,
ctx context.Context, ctx context.Context,
logger log.Logger, logger log.Logger,
...@@ -113,9 +104,10 @@ func registerOutputCannon( ...@@ -113,9 +104,10 @@ func registerOutputCannon(
rollupClient outputs.OutputRollupClient, rollupClient outputs.OutputRollupClient,
txMgr txmgr.TxManager, txMgr txmgr.TxManager,
caller *batching.MultiCaller, caller *batching.MultiCaller,
l2Client cannon.L2HeaderSource) { l2Client cannon.L2HeaderSource,
) {
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewOutputBisectionGameContract(game.Proxy, caller) contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -139,58 +131,5 @@ func registerOutputCannon( ...@@ -139,58 +131,5 @@ func registerOutputCannon(
genesisValidator := NewPrestateValidator(contract.GetGenesisOutputRoot, prestateProvider) genesisValidator := NewPrestateValidator(contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{prestateValidator, genesisValidator}, creator) return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{prestateValidator, genesisValidator}, creator)
} }
registry.RegisterGameType(outputCannonGameType, playerCreator)
}
func registerCannon(
registry Registry,
ctx context.Context,
logger log.Logger,
m metrics.Metricer,
cfg *config.Config,
txMgr txmgr.TxManager,
caller *batching.MultiCaller,
l2Client cannon.L2HeaderSource) {
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller)
if err != nil {
return nil, err
}
prestateProvider := cannon.NewPrestateProvider(cfg.CannonAbsolutePreState)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
localInputs, err := cannon.FetchLocalInputs(ctx, contract, l2Client)
if err != nil {
return nil, fmt.Errorf("failed to fetch cannon local inputs: %w", err)
}
provider := cannon.NewTraceProvider(logger, m, cfg, faultTypes.NoLocalContext, localInputs, dir, gameDepth)
return trace.NewSimpleTraceAccessor(provider), nil
}
validator := NewPrestateValidator(contract.GetAbsolutePrestateHash, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{validator}, creator)
}
registry.RegisterGameType(cannonGameType, playerCreator) registry.RegisterGameType(cannonGameType, playerCreator)
} }
func registerAlphabet(
registry Registry,
ctx context.Context,
logger log.Logger,
m metrics.Metricer,
alphabetTrace string,
txMgr txmgr.TxManager,
caller *batching.MultiCaller) {
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller)
if err != nil {
return nil, err
}
prestateProvider := &alphabet.AlphabetPrestateProvider{}
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
traceProvider := alphabet.NewTraceProvider(alphabetTrace, gameDepth)
return trace.NewSimpleTraceAccessor(traceProvider), nil
}
validator := NewPrestateValidator(contract.GetAbsolutePrestateHash, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{validator}, creator)
}
registry.RegisterGameType(alphabetGameType, playerCreator)
}
...@@ -54,31 +54,12 @@ func WithPrivKey(key *ecdsa.PrivateKey) Option { ...@@ -54,31 +54,12 @@ func WithPrivKey(key *ecdsa.PrivateKey) Option {
} }
} }
func WithAlphabet(alphabet string) Option {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeAlphabet)
c.AlphabetTrace = alphabet
}
}
func WithPollInterval(pollInterval time.Duration) Option { func WithPollInterval(pollInterval time.Duration) Option {
return func(c *config.Config) { return func(c *config.Config) {
c.PollInterval = pollInterval c.PollInterval = pollInterval
} }
} }
func WithCannon(
t *testing.T,
rollupCfg *rollup.Config,
l2Genesis *core.Genesis,
l2Endpoint string,
) Option {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeCannon)
applyCannonConfig(c, t, rollupCfg, l2Genesis, l2Endpoint)
}
}
func applyCannonConfig( func applyCannonConfig(
c *config.Config, c *config.Config,
t *testing.T, t *testing.T,
...@@ -96,34 +77,34 @@ func applyCannonConfig( ...@@ -96,34 +77,34 @@ func applyCannonConfig(
genesisBytes, err := json.Marshal(l2Genesis) genesisBytes, err := json.Marshal(l2Genesis)
require.NoError(err, "marshall l2 genesis config") require.NoError(err, "marshall l2 genesis config")
genesisFile := filepath.Join(c.Datadir, "l2-genesis.json") genesisFile := filepath.Join(c.Datadir, "l2-genesis.json")
require.NoError(os.WriteFile(genesisFile, genesisBytes, 0644)) require.NoError(os.WriteFile(genesisFile, genesisBytes, 0o644))
c.CannonL2GenesisPath = genesisFile c.CannonL2GenesisPath = genesisFile
rollupBytes, err := json.Marshal(rollupCfg) rollupBytes, err := json.Marshal(rollupCfg)
require.NoError(err, "marshall rollup config") require.NoError(err, "marshall rollup config")
rollupFile := filepath.Join(c.Datadir, "rollup.json") rollupFile := filepath.Join(c.Datadir, "rollup.json")
require.NoError(os.WriteFile(rollupFile, rollupBytes, 0644)) require.NoError(os.WriteFile(rollupFile, rollupBytes, 0o644))
c.CannonRollupConfigPath = rollupFile c.CannonRollupConfigPath = rollupFile
} }
func WithOutputCannon( func WithCannon(
t *testing.T, t *testing.T,
rollupCfg *rollup.Config, rollupCfg *rollup.Config,
l2Genesis *core.Genesis, l2Genesis *core.Genesis,
rollupEndpoint string, rollupEndpoint string,
l2Endpoint string) Option { l2Endpoint string,
) Option {
return func(c *config.Config) { return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeOutputCannon) c.TraceTypes = append(c.TraceTypes, config.TraceTypeCannon)
c.RollupRpc = rollupEndpoint c.RollupRpc = rollupEndpoint
applyCannonConfig(c, t, rollupCfg, l2Genesis, l2Endpoint) applyCannonConfig(c, t, rollupCfg, l2Genesis, l2Endpoint)
} }
} }
func WithOutputAlphabet(alphabet string, rollupEndpoint string) Option { func WithAlphabet(rollupEndpoint string) Option {
return func(c *config.Config) { return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeOutputAlphabet) c.TraceTypes = append(c.TraceTypes, config.TraceTypeAlphabet)
c.RollupRpc = rollupEndpoint c.RollupRpc = rollupEndpoint
c.AlphabetTrace = alphabet
} }
} }
......
...@@ -9,14 +9,13 @@ import ( ...@@ -9,14 +9,13 @@ import (
type AlphabetGameHelper struct { type AlphabetGameHelper struct {
FaultGameHelper FaultGameHelper
claimedAlphabet string
} }
func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint string, name string, options ...challenger.Option) *challenger.Helper { func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint string, name string, options ...challenger.Option) *challenger.Helper {
opts := []challenger.Option{ opts := []challenger.Option{
challenger.WithFactoryAddress(g.factoryAddr), challenger.WithFactoryAddress(g.factoryAddr),
challenger.WithGameAddress(g.addr), challenger.WithGameAddress(g.addr),
challenger.WithAlphabet(g.claimedAlphabet), challenger.WithAlphabet(g.system.RollupEndpoint("sequencer")),
} }
opts = append(opts, options...) opts = append(opts, options...)
c := challenger.NewChallenger(g.t, ctx, l1Endpoint, name, opts...) c := challenger.NewChallenger(g.t, ctx, l1Endpoint, name, opts...)
......
...@@ -33,7 +33,7 @@ func (g *FaultGameHelper) Addr() common.Address { ...@@ -33,7 +33,7 @@ func (g *FaultGameHelper) Addr() common.Address {
} }
func (g *FaultGameHelper) GameDuration(ctx context.Context) time.Duration { func (g *FaultGameHelper) GameDuration(ctx context.Context) time.Duration {
duration, err := g.game.GAMEDURATION(&bind.CallOpts{Context: ctx}) duration, err := g.game.GameDuration(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "failed to get game duration") g.require.NoError(err, "failed to get game duration")
return time.Duration(duration) * time.Second return time.Duration(duration) * time.Second
} }
...@@ -59,7 +59,7 @@ func (g *FaultGameHelper) WaitForClaimCount(ctx context.Context, count int64) { ...@@ -59,7 +59,7 @@ func (g *FaultGameHelper) WaitForClaimCount(ctx context.Context, count int64) {
} }
func (g *FaultGameHelper) MaxDepth(ctx context.Context) int64 { func (g *FaultGameHelper) MaxDepth(ctx context.Context) int64 {
depth, err := g.game.MAXGAMEDEPTH(&bind.CallOpts{Context: ctx}) depth, err := g.game.MaxGameDepth(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "Failed to load game depth") g.require.NoError(err, "Failed to load game depth")
return depth.Int64() return depth.Int64()
} }
...@@ -293,6 +293,7 @@ func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove fu ...@@ -293,6 +293,7 @@ func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove fu
func (g *FaultGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) { func (g *FaultGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) {
return g.waitForNewClaim(ctx, checkPoint, defaultTimeout) return g.waitForNewClaim(ctx, checkPoint, defaultTimeout)
} }
func (g *FaultGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64, timeout time.Duration) (int64, error) { func (g *FaultGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64, timeout time.Duration) (int64, error) {
timedCtx, cancel := context.WithTimeout(ctx, timeout) timedCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()
......
...@@ -32,10 +32,9 @@ import ( ...@@ -32,10 +32,9 @@ import (
) )
const ( const (
alphabetGameType uint8 = 255 cannonGameType uint8 = 0
outputCannonGameType uint8 = 1 alphabetGameType uint8 = 255
outputAlphabetGameType uint8 = 254 alphabetGameDepth = 4
alphabetGameDepth = 4
) )
var lastAlphabetTraceIndex = big.NewInt(1<<alphabetGameDepth - 1) var lastAlphabetTraceIndex = big.NewInt(1<<alphabetGameDepth - 1)
...@@ -61,8 +60,6 @@ func (s Status) String() string { ...@@ -61,8 +60,6 @@ func (s Status) String() string {
} }
} }
var CorrectAlphabet = "abcdefghijklmnop"
type DisputeSystem interface { type DisputeSystem interface {
NodeEndpoint(name string) string NodeEndpoint(name string) string
NodeClient(name string) *ethclient.Client NodeClient(name string) *ethclient.Client
...@@ -82,7 +79,6 @@ type FactoryHelper struct { ...@@ -82,7 +79,6 @@ type FactoryHelper struct {
opts *bind.TransactOpts opts *bind.TransactOpts
factoryAddr common.Address factoryAddr common.Address
factory *bindings.DisputeGameFactory factory *bindings.DisputeGameFactory
blockOracle *bindings.BlockOracle
l2ooHelper *l2oo.L2OOHelper l2ooHelper *l2oo.L2OOHelper
} }
...@@ -98,8 +94,6 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) * ...@@ -98,8 +94,6 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) *
factoryAddr := l1Deployments.DisputeGameFactoryProxy factoryAddr := l1Deployments.DisputeGameFactoryProxy
factory, err := bindings.NewDisputeGameFactory(factoryAddr, client) factory, err := bindings.NewDisputeGameFactory(factoryAddr, client)
require.NoError(err) require.NoError(err)
blockOracle, err := bindings.NewBlockOracle(l1Deployments.BlockOracle, client)
require.NoError(err)
return &FactoryHelper{ return &FactoryHelper{
t: t, t: t,
...@@ -109,49 +103,10 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) * ...@@ -109,49 +103,10 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) *
opts: opts, opts: opts,
factory: factory, factory: factory,
factoryAddr: factoryAddr, factoryAddr: factoryAddr,
blockOracle: blockOracle,
l2ooHelper: l2oo.NewL2OOHelperReadOnly(t, l1Deployments, client), l2ooHelper: l2oo.NewL2OOHelperReadOnly(t, l1Deployments, client),
} }
} }
func (h *FactoryHelper) StartAlphabetGame(ctx context.Context, claimedAlphabet string) *AlphabetGameHelper {
extraData, _, _ := h.createDisputeGameExtraData(ctx)
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()
trace := alphabet.NewTraceProvider(claimedAlphabet, alphabetGameDepth)
pos := faultTypes.NewPosition(alphabetGameDepth, lastAlphabetTraceIndex)
rootClaim, err := trace.Get(ctx, pos)
h.require.NoError(err, "get root claim")
tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return h.factory.Create(opts, alphabetGameType, rootClaim, extraData)
})
h.require.NoError(err, "create fault dispute game")
h.opts.GasLimit = 0
rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash())
h.require.NoError(err, "wait for create fault dispute game receipt to be OK")
h.require.Len(rcpt.Logs, 1, "should have emitted a single DisputeGameCreated event")
createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[0])
h.require.NoError(err)
game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.client)
h.require.NoError(err)
return &AlphabetGameHelper{
FaultGameHelper: FaultGameHelper{
t: h.t,
require: h.require,
system: h.system,
client: h.client,
opts: h.opts,
game: game,
factoryAddr: h.factoryAddr,
addr: createdEvent.DisputeProxy,
},
claimedAlphabet: claimedAlphabet,
}
}
func (h *FactoryHelper) StartOutputCannonGameWithCorrectRoot(ctx context.Context, l2Node string, l2BlockNumber uint64) *OutputCannonGameHelper { func (h *FactoryHelper) StartOutputCannonGameWithCorrectRoot(ctx context.Context, l2Node string, l2BlockNumber uint64) *OutputCannonGameHelper {
h.waitForBlockToBeSafe(l2Node, l2BlockNumber) h.waitForBlockToBeSafe(l2Node, l2BlockNumber)
output, err := h.system.RollupClient(l2Node).OutputAtBlock(ctx, l2BlockNumber) output, err := h.system.RollupClient(l2Node).OutputAtBlock(ctx, l2BlockNumber)
...@@ -169,7 +124,7 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string ...@@ -169,7 +124,7 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string
defer cancel() defer cancel()
tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return h.factory.Create(opts, outputCannonGameType, rootClaim, extraData) return h.factory.Create(opts, cannonGameType, rootClaim, extraData)
}) })
h.require.NoError(err, "create fault dispute game") h.require.NoError(err, "create fault dispute game")
rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash()) rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash())
...@@ -177,7 +132,7 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string ...@@ -177,7 +132,7 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string
h.require.Len(rcpt.Logs, 1, "should have emitted a single DisputeGameCreated event") h.require.Len(rcpt.Logs, 1, "should have emitted a single DisputeGameCreated event")
createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[0]) createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[0])
h.require.NoError(err) h.require.NoError(err)
game, err := bindings.NewOutputBisectionGame(createdEvent.DisputeProxy, h.client) game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.client)
h.require.NoError(err) h.require.NoError(err)
prestateBlock, err := game.GenesisBlockNumber(&bind.CallOpts{Context: ctx}) prestateBlock, err := game.GenesisBlockNumber(&bind.CallOpts{Context: ctx})
...@@ -218,7 +173,7 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri ...@@ -218,7 +173,7 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri
rootClaim, err := trace.Get(ctx, pos) rootClaim, err := trace.Get(ctx, pos)
h.require.NoError(err, "get root claim") h.require.NoError(err, "get root claim")
tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return h.factory.Create(opts, outputAlphabetGameType, rootClaim, extraData) return h.factory.Create(opts, alphabetGameType, rootClaim, extraData)
}) })
h.require.NoError(err, "create output bisection game") h.require.NoError(err, "create output bisection game")
rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash()) rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash())
...@@ -226,7 +181,7 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri ...@@ -226,7 +181,7 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri
h.require.Len(rcpt.Logs, 1, "should have emitted a single DisputeGameCreated event") h.require.Len(rcpt.Logs, 1, "should have emitted a single DisputeGameCreated event")
createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[0]) createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[0])
h.require.NoError(err) h.require.NoError(err)
game, err := bindings.NewOutputBisectionGame(createdEvent.DisputeProxy, h.client) game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.client)
h.require.NoError(err) h.require.NoError(err)
prestateBlock, err := game.GenesisBlockNumber(&bind.CallOpts{Context: ctx}) prestateBlock, err := game.GenesisBlockNumber(&bind.CallOpts{Context: ctx})
...@@ -250,7 +205,6 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri ...@@ -250,7 +205,6 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri
correctOutputProvider: provider, correctOutputProvider: provider,
system: h.system, system: h.system,
}, },
claimedAlphabet: claimedAlphabet,
} }
} }
...@@ -268,15 +222,6 @@ func (h *FactoryHelper) waitForBlockToBeSafe(l2Node string, l2BlockNumber uint64 ...@@ -268,15 +222,6 @@ func (h *FactoryHelper) waitForBlockToBeSafe(l2Node string, l2BlockNumber uint64
h.require.NoErrorf(err, "Block number %v did not become safe", l2BlockNumber) h.require.NoErrorf(err, "Block number %v did not become safe", l2BlockNumber)
} }
func (h *FactoryHelper) createDisputeGameExtraData(ctx context.Context) (extraData []byte, l1Head *big.Int, l2BlockNumber uint64) {
l2BlockNumber = h.waitForProposals(ctx)
l1Head = h.checkpointL1Block(ctx)
extraData = make([]byte, 64)
binary.BigEndian.PutUint64(extraData[24:], l2BlockNumber)
binary.BigEndian.PutUint64(extraData[56:], l1Head.Uint64())
return
}
func (h *FactoryHelper) StartChallenger(ctx context.Context, name string, options ...challenger.Option) *challenger.Helper { func (h *FactoryHelper) StartChallenger(ctx context.Context, name string, options ...challenger.Option) *challenger.Helper {
opts := []challenger.Option{ opts := []challenger.Option{
challenger.WithFactoryAddress(h.factoryAddr), challenger.WithFactoryAddress(h.factoryAddr),
...@@ -288,26 +233,3 @@ func (h *FactoryHelper) StartChallenger(ctx context.Context, name string, option ...@@ -288,26 +233,3 @@ func (h *FactoryHelper) StartChallenger(ctx context.Context, name string, option
}) })
return c return c
} }
// waitForProposals waits until there are at least two proposals in the output oracle
// This is the minimum required for creating a game.
// Returns the l2 block number of the latest available proposal
func (h *FactoryHelper) waitForProposals(ctx context.Context) uint64 {
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()
latestOutputIdx := h.l2ooHelper.WaitForProposals(ctx, 2)
return h.l2ooHelper.GetL2Output(ctx, latestOutputIdx).L2BlockNumber.Uint64()
}
// checkpointL1Block stores the current L1 block in the oracle
// Returns the L1 block number that was stored as the checkpoint
func (h *FactoryHelper) checkpointL1Block(ctx context.Context) *big.Int {
ctx, cancel := context.WithTimeout(ctx, 1*time.Minute)
defer cancel()
// Store the current block in the oracle
tx, err := h.blockOracle.Checkpoint(h.opts)
h.require.NoError(err)
r, err := wait.ForReceiptOK(ctx, h.client, tx.Hash())
h.require.NoError(err, "failed to store block in block oracle")
return new(big.Int).Sub(r.BlockNumber, big.NewInt(1))
}
...@@ -8,7 +8,6 @@ import ( ...@@ -8,7 +8,6 @@ import (
type OutputAlphabetGameHelper struct { type OutputAlphabetGameHelper struct {
OutputGameHelper OutputGameHelper
claimedAlphabet string
} }
func (g *OutputAlphabetGameHelper) StartChallenger( func (g *OutputAlphabetGameHelper) StartChallenger(
...@@ -18,7 +17,7 @@ func (g *OutputAlphabetGameHelper) StartChallenger( ...@@ -18,7 +17,7 @@ func (g *OutputAlphabetGameHelper) StartChallenger(
options ...challenger.Option, options ...challenger.Option,
) *challenger.Helper { ) *challenger.Helper {
opts := []challenger.Option{ opts := []challenger.Option{
challenger.WithOutputAlphabet(g.claimedAlphabet, g.system.RollupEndpoint(l2Node)), challenger.WithAlphabet(g.system.RollupEndpoint(l2Node)),
challenger.WithFactoryAddress(g.factoryAddr), challenger.WithFactoryAddress(g.factoryAddr),
challenger.WithGameAddress(g.addr), challenger.WithGameAddress(g.addr),
} }
......
...@@ -26,7 +26,7 @@ func (g *OutputCannonGameHelper) StartChallenger( ...@@ -26,7 +26,7 @@ func (g *OutputCannonGameHelper) StartChallenger(
rollupEndpoint := g.system.RollupEndpoint(l2Node) rollupEndpoint := g.system.RollupEndpoint(l2Node)
l2Endpoint := g.system.NodeEndpoint(l2Node) l2Endpoint := g.system.NodeEndpoint(l2Node)
opts := []challenger.Option{ opts := []challenger.Option{
challenger.WithOutputCannon(g.t, g.system.RollupCfg(), g.system.L2Genesis(), rollupEndpoint, l2Endpoint), challenger.WithCannon(g.t, g.system.RollupCfg(), g.system.L2Genesis(), rollupEndpoint, l2Endpoint),
challenger.WithFactoryAddress(g.factoryAddr), challenger.WithFactoryAddress(g.factoryAddr),
challenger.WithGameAddress(g.addr), challenger.WithGameAddress(g.addr),
} }
...@@ -40,7 +40,7 @@ func (g *OutputCannonGameHelper) StartChallenger( ...@@ -40,7 +40,7 @@ func (g *OutputCannonGameHelper) StartChallenger(
func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node string, options ...challenger.Option) *OutputHonestHelper { func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node string, options ...challenger.Option) *OutputHonestHelper {
opts := []challenger.Option{ opts := []challenger.Option{
challenger.WithOutputCannon(g.t, g.system.RollupCfg(), g.system.L2Genesis(), g.system.RollupEndpoint(l2Node), g.system.NodeEndpoint(l2Node)), challenger.WithCannon(g.t, g.system.RollupCfg(), g.system.L2Genesis(), g.system.RollupEndpoint(l2Node), g.system.NodeEndpoint(l2Node)),
challenger.WithFactoryAddress(g.factoryAddr), challenger.WithFactoryAddress(g.factoryAddr),
challenger.WithGameAddress(g.addr), challenger.WithGameAddress(g.addr),
} }
...@@ -50,7 +50,7 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s ...@@ -50,7 +50,7 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s
logger := testlog.Logger(g.t, log.LvlInfo).New("role", "HonestHelper", "game", g.addr) logger := testlog.Logger(g.t, log.LvlInfo).New("role", "HonestHelper", "game", g.addr)
l2Client := g.system.NodeClient(l2Node) l2Client := g.system.NodeClient(l2Node)
caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize) caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize)
contract, err := contracts.NewOutputBisectionGameContract(g.addr, caller) contract, err := contracts.NewFaultDisputeGameContract(g.addr, caller)
g.require.NoError(err, "Failed to create game contact") g.require.NoError(err, "Failed to create game contact")
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
......
...@@ -25,7 +25,7 @@ type OutputGameHelper struct { ...@@ -25,7 +25,7 @@ type OutputGameHelper struct {
require *require.Assertions require *require.Assertions
client *ethclient.Client client *ethclient.Client
opts *bind.TransactOpts opts *bind.TransactOpts
game *bindings.OutputBisectionGame game *bindings.FaultDisputeGame
factoryAddr common.Address factoryAddr common.Address
addr common.Address addr common.Address
correctOutputProvider *outputs.OutputTraceProvider correctOutputProvider *outputs.OutputTraceProvider
......
...@@ -14,7 +14,7 @@ type OutputHonestHelper struct { ...@@ -14,7 +14,7 @@ type OutputHonestHelper struct {
t *testing.T t *testing.T
require *require.Assertions require *require.Assertions
game *OutputGameHelper game *OutputGameHelper
contract *contracts.OutputBisectionGameContract contract *contracts.FaultDisputeGameContract
correctTrace types.TraceAccessor correctTrace types.TraceAccessor
} }
......
package faultproofs
import (
"context"
"testing"
"time"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/stretchr/testify/require"
)
func TestChallengerCompleteDisputeGame(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1))
tests := []struct {
name string
rootClaimAlphabet string
otherAlphabet string
expectedResult disputegame.Status
expectStep bool
}{
{
name: "ChallengerWins_DefenseStep",
rootClaimAlphabet: "abcdexyz",
otherAlphabet: disputegame.CorrectAlphabet,
expectedResult: disputegame.StatusChallengerWins,
expectStep: true,
},
{
name: "DefenderWins_DefenseStep",
rootClaimAlphabet: disputegame.CorrectAlphabet,
otherAlphabet: "abcdexyz",
expectedResult: disputegame.StatusDefenderWins,
expectStep: false,
},
{
name: "ChallengerWins_AttackStep",
rootClaimAlphabet: "abcdefghzyx",
otherAlphabet: disputegame.CorrectAlphabet,
expectedResult: disputegame.StatusChallengerWins,
expectStep: true,
},
{
name: "DefenderWins_AttackStep",
rootClaimAlphabet: disputegame.CorrectAlphabet,
otherAlphabet: "abcdexyz",
expectedResult: disputegame.StatusDefenderWins,
expectStep: false,
},
{
name: "DefenderIncorrectAtTraceZero",
rootClaimAlphabet: "zyxwvut",
otherAlphabet: disputegame.CorrectAlphabet,
expectedResult: disputegame.StatusChallengerWins,
expectStep: true,
},
{
name: "ChallengerIncorrectAtTraceZero",
rootClaimAlphabet: disputegame.CorrectAlphabet,
otherAlphabet: "zyxwvut",
expectedResult: disputegame.StatusDefenderWins,
expectStep: false,
},
{
name: "DefenderIncorrectAtLastTraceIndex",
rootClaimAlphabet: "abcdefghijklmnoz",
otherAlphabet: disputegame.CorrectAlphabet,
expectedResult: disputegame.StatusChallengerWins,
expectStep: true,
},
{
name: "ChallengerIncorrectAtLastTraceIndex",
rootClaimAlphabet: disputegame.CorrectAlphabet,
otherAlphabet: "abcdefghijklmnoz",
expectedResult: disputegame.StatusDefenderWins,
expectStep: false,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1))
ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t)
t.Cleanup(sys.Close)
disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys)
game := disputeGameFactory.StartAlphabetGame(ctx, test.rootClaimAlphabet)
require.NotNil(t, game)
gameDuration := game.GameDuration(ctx)
game.StartChallenger(ctx, sys.NodeEndpoint("l1"), "Defender",
challenger.WithPrivKey(sys.Cfg.Secrets.Mallory),
)
game.StartChallenger(ctx, sys.NodeEndpoint("l1"), "Challenger",
challenger.WithAlphabet(test.otherAlphabet),
challenger.WithPrivKey(sys.Cfg.Secrets.Alice),
)
// Wait for a claim at the maximum depth that has been countered to indicate we're ready to resolve the game
game.WaitForClaimAtMaxDepth(ctx, test.expectStep)
sys.TimeTravelClock.AdvanceTime(gameDuration)
require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForInactivity(ctx, 10, true)
game.LogGameData(ctx)
require.EqualValues(t, test.expectedResult, game.Status(ctx))
})
}
}
func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1))
testCase := func(t *testing.T, isRootCorrect bool) {
ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t)
t.Cleanup(sys.Close)
disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys)
rootClaimedAlphabet := disputegame.CorrectAlphabet
if !isRootCorrect {
rootClaimedAlphabet = "abcdexyz"
}
game := disputeGameFactory.StartAlphabetGame(ctx, rootClaimedAlphabet)
require.NotNil(t, game)
gameDuration := game.GameDuration(ctx)
// Start honest challenger
game.StartChallenger(ctx, sys.NodeEndpoint("l1"), "Challenger",
challenger.WithAlphabet(disputegame.CorrectAlphabet),
challenger.WithPrivKey(sys.Cfg.Secrets.Alice),
// Ensures the challenger responds to all claims before test timeout
challenger.WithPollInterval(time.Millisecond*400),
)
// Start dishonest challenger
dishonestHelper := game.CreateDishonestHelper(disputegame.CorrectAlphabet, 4, !isRootCorrect)
dishonestHelper.ExhaustDishonestClaims(ctx)
// Wait until we've reached max depth before checking for inactivity
game.WaitForClaimAtDepth(ctx, int(game.MaxDepth(ctx)))
// Wait for 4 blocks of no challenger responses. The challenger may still be stepping on invalid claims at max depth
game.WaitForInactivity(ctx, 4, false)
sys.TimeTravelClock.AdvanceTime(gameDuration)
require.NoError(t, wait.ForNextBlock(ctx, l1Client))
expectedStatus := disputegame.StatusChallengerWins
if isRootCorrect {
expectedStatus = disputegame.StatusDefenderWins
}
game.WaitForInactivity(ctx, 10, true)
game.LogGameData(ctx)
require.EqualValues(t, expectedStatus, game.Status(ctx))
}
t.Run("RootCorrect", func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1))
testCase(t, true)
})
t.Run("RootIncorrect", func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1))
testCase(t, false)
})
}
...@@ -26,8 +26,8 @@ func TestMultipleGameTypes(t *testing.T) { ...@@ -26,8 +26,8 @@ func TestMultipleGameTypes(t *testing.T) {
// Start a challenger with both cannon and alphabet support // Start a challenger with both cannon and alphabet support
gameFactory.StartChallenger(ctx, "TowerDefense", gameFactory.StartChallenger(ctx, "TowerDefense",
challenger.WithOutputCannon(t, sys.RollupConfig, sys.L2GenesisCfg, sys.RollupEndpoint("sequencer"), sys.NodeEndpoint("sequencer")), challenger.WithCannon(t, sys.RollupConfig, sys.L2GenesisCfg, sys.RollupEndpoint("sequencer"), sys.NodeEndpoint("sequencer")),
challenger.WithOutputAlphabet(disputegame.CorrectAlphabet, sys.RollupEndpoint("sequencer")), challenger.WithAlphabet(sys.RollupEndpoint("sequencer")),
challenger.WithPrivKey(sys.Cfg.Secrets.Alice), challenger.WithPrivKey(sys.Cfg.Secrets.Alice),
) )
......
...@@ -49,9 +49,9 @@ ...@@ -49,9 +49,9 @@
"faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98", "faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98",
"faultGameMaxDepth": 44, "faultGameMaxDepth": 44,
"faultGameMaxDuration": 1200, "faultGameMaxDuration": 1200,
"outputBisectionGameGenesisBlock": 0, "faultGameGenesisBlock": 0,
"outputBisectionGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"outputBisectionGameSplitDepth": 14, "faultGameSplitDepth": 14,
"systemConfigStartBlock": 0, "systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000"
......
...@@ -30,10 +30,8 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; ...@@ -30,10 +30,8 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol";
import { OutputBisectionGame } from "src/dispute/OutputBisectionGame.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { MIPS } from "src/cannon/MIPS.sol"; import { MIPS } from "src/cannon/MIPS.sol";
import { BlockOracle } from "src/dispute/BlockOracle.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol";
import { StorageSetter } from "src/universal/StorageSetter.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol";
...@@ -43,7 +41,6 @@ import { Chains } from "scripts/Chains.sol"; ...@@ -43,7 +41,6 @@ import { Chains } from "scripts/Chains.sol";
import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol";
import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";
import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; import { AlphabetVM } from "test/mocks/AlphabetVM.sol";
import { AlphabetVM2 } from "test/mocks/AlphabetVM2.sol";
import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeTypes.sol";
import { ChainAssertions } from "scripts/ChainAssertions.sol"; import { ChainAssertions } from "scripts/ChainAssertions.sol";
import { Types } from "scripts/Types.sol"; import { Types } from "scripts/Types.sol";
...@@ -290,9 +287,6 @@ contract Deploy is Deployer { ...@@ -290,9 +287,6 @@ contract Deploy is Deployer {
deployImplementations(); deployImplementations();
initializeImplementations(); initializeImplementations();
setCannonOutputBisectionGameImplementation();
setAlphabetOutputBisectionGameImplementation();
setAlphabetFaultGameImplementation(); setAlphabetFaultGameImplementation();
setCannonFaultGameImplementation(); setCannonFaultGameImplementation();
...@@ -326,7 +320,6 @@ contract Deploy is Deployer { ...@@ -326,7 +320,6 @@ contract Deploy is Deployer {
deployL1StandardBridge(); deployL1StandardBridge();
deployL1ERC721Bridge(); deployL1ERC721Bridge();
deployDisputeGameFactory(); deployDisputeGameFactory();
deployBlockOracle();
deployPreimageOracle(); deployPreimageOracle();
deployMips(); deployMips();
} }
...@@ -569,16 +562,6 @@ contract Deploy is Deployer { ...@@ -569,16 +562,6 @@ contract Deploy is Deployer {
addr_ = address(factory); addr_ = address(factory);
} }
/// @notice Deploy the BlockOracle
function deployBlockOracle() public onlyDevnet broadcast returns (address addr_) {
console.log("Deploying BlockOracle implementation");
BlockOracle oracle = new BlockOracle{ salt: _implSalt() }();
save("BlockOracle", address(oracle));
console.log("BlockOracle deployed at %s", address(oracle));
addr_ = address(oracle);
}
/// @notice Deploy the ProtocolVersions /// @notice Deploy the ProtocolVersions
function deployProtocolVersions() public broadcast returns (address addr_) { function deployProtocolVersions() public broadcast returns (address addr_) {
console.log("Deploying ProtocolVersions implementation"); console.log("Deploying ProtocolVersions implementation");
...@@ -1019,35 +1002,6 @@ contract Deploy is Deployer { ...@@ -1019,35 +1002,6 @@ contract Deploy is Deployer {
_gameType: GameTypes.CANNON, _gameType: GameTypes.CANNON,
_absolutePrestate: loadMipsAbsolutePrestate(), _absolutePrestate: loadMipsAbsolutePrestate(),
_faultVm: IBigStepper(mustGetAddress("Mips")), _faultVm: IBigStepper(mustGetAddress("Mips")),
_maxGameDepth: 30 // Hard code depth for legacy game to keep e2e tests fast
});
}
/// @notice Sets the implementation for the `OUTPUT_CANNON` game type in the `DisputeGameFactory`
function setCannonOutputBisectionGameImplementation() public onlyDevnet broadcast {
console.log("Setting Cannon OutputBisectionGame implementation");
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
_setFaultGameImplementation({
_factory: factory,
_gameType: GameTypes.OUTPUT_CANNON,
_absolutePrestate: loadMipsAbsolutePrestate(),
_faultVm: IBigStepper(mustGetAddress("Mips")),
_maxGameDepth: cfg.faultGameMaxDepth()
});
}
/// @notice Sets the implementation for the `OUTPUT_ALPHABET` game type in the `DisputeGameFactory`
function setAlphabetOutputBisectionGameImplementation() public onlyDevnet broadcast {
console.log("Setting Alphabet OutputBisectionGame implementation");
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
Claim outputAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate()));
_setFaultGameImplementation({
_factory: factory,
_gameType: GameTypes.OUTPUT_ALPHABET,
_absolutePrestate: outputAbsolutePrestate,
_faultVm: IBigStepper(new AlphabetVM2(outputAbsolutePrestate)),
_maxGameDepth: cfg.faultGameMaxDepth() _maxGameDepth: cfg.faultGameMaxDepth()
}); });
} }
...@@ -1057,15 +1011,14 @@ contract Deploy is Deployer { ...@@ -1057,15 +1011,14 @@ contract Deploy is Deployer {
console.log("Setting Alphabet FaultDisputeGame implementation"); console.log("Setting Alphabet FaultDisputeGame implementation");
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
// Set the Alphabet FaultDisputeGame implementation in the factory. Claim outputAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate()));
Claim alphabetAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate()));
_setFaultGameImplementation({ _setFaultGameImplementation({
_factory: factory, _factory: factory,
_gameType: GameTypes.ALPHABET, _gameType: GameTypes.ALPHABET,
_absolutePrestate: alphabetAbsolutePrestate, _absolutePrestate: outputAbsolutePrestate,
_faultVm: IBigStepper(new AlphabetVM(alphabetAbsolutePrestate)), _faultVm: IBigStepper(new AlphabetVM(outputAbsolutePrestate)),
_maxGameDepth: 4 // The max game depth of the alphabet game is always 4. _maxGameDepth: cfg.faultGameMaxDepth()
}); });
} }
/// @notice Sets the implementation for the given fault game type in the `DisputeGameFactory`. /// @notice Sets the implementation for the given fault game type in the `DisputeGameFactory`.
...@@ -1086,49 +1039,24 @@ contract Deploy is Deployer { ...@@ -1086,49 +1039,24 @@ contract Deploy is Deployer {
return; return;
} }
string memory deployed; _factory.setImplementation(
if ( _gameType,
GameType.unwrap(_gameType) == GameType.unwrap(GameTypes.OUTPUT_ALPHABET) new FaultDisputeGame({
|| GameType.unwrap(_gameType) == GameType.unwrap(GameTypes.OUTPUT_CANNON) _gameType: _gameType,
) { _absolutePrestate: _absolutePrestate,
deployed = "OutputBisectionGame"; _genesisBlockNumber: cfg.faultGameGenesisBlock(),
_factory.setImplementation( _genesisOutputRoot: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
_gameType, _maxGameDepth: _maxGameDepth,
new OutputBisectionGame({ _splitDepth: cfg.faultGameSplitDepth(),
_gameType: _gameType, _gameDuration: Duration.wrap(uint64(cfg.faultGameMaxDuration())),
_absolutePrestate: _absolutePrestate, _vm: _faultVm
_genesisBlockNumber: cfg.outputBisectionGameGenesisBlock(), })
_genesisOutputRoot: Hash.wrap(cfg.outputBisectionGameGenesisOutputRoot()), );
_maxGameDepth: _maxGameDepth,
_splitDepth: cfg.outputBisectionGameSplitDepth(),
_gameDuration: Duration.wrap(uint64(cfg.faultGameMaxDuration())),
_vm: _faultVm
})
);
} else {
deployed = "FaultDisputeGame";
_factory.setImplementation(
_gameType,
new FaultDisputeGame({
_gameType: _gameType,
_absolutePrestate: _absolutePrestate,
_maxGameDepth: _maxGameDepth,
_gameDuration: Duration.wrap(uint64(cfg.faultGameMaxDuration())),
_vm: _faultVm,
_l2oo: L2OutputOracle(mustGetAddress("L2OutputOracleProxy")),
_blockOracle: BlockOracle(mustGetAddress("BlockOracle"))
})
);
}
uint8 rawGameType = GameType.unwrap(_gameType); uint8 rawGameType = GameType.unwrap(_gameType);
string memory gameTypeString; string memory gameTypeString;
if (rawGameType == GameType.unwrap(GameTypes.CANNON)) { if (rawGameType == GameType.unwrap(GameTypes.CANNON)) {
gameTypeString = "Cannon"; gameTypeString = "Cannon";
} else if (rawGameType == GameType.unwrap(GameTypes.OUTPUT_CANNON)) {
gameTypeString = "OutputBisectionCannon";
} else if (rawGameType == GameType.unwrap(GameTypes.OUTPUT_ALPHABET)) {
gameTypeString = "OutputBisectionAlphabet";
} else if (rawGameType == GameType.unwrap(GameTypes.ALPHABET)) { } else if (rawGameType == GameType.unwrap(GameTypes.ALPHABET)) {
gameTypeString = "Alphabet"; gameTypeString = "Alphabet";
} else { } else {
...@@ -1136,8 +1064,7 @@ contract Deploy is Deployer { ...@@ -1136,8 +1064,7 @@ contract Deploy is Deployer {
} }
console.log( console.log(
"DisputeGameFactoryProxy: set `%s` implementation (Backend: %s | GameType: %s)", "DisputeGameFactoryProxy: set `FaultDisputeGame` implementation (Backend: %s | GameType: %s)",
deployed,
gameTypeString, gameTypeString,
vm.toString(rawGameType) vm.toString(rawGameType)
); );
......
...@@ -48,11 +48,11 @@ contract DeployConfig is Script { ...@@ -48,11 +48,11 @@ contract DeployConfig is Script {
uint256 public eip1559Denominator; uint256 public eip1559Denominator;
uint256 public eip1559Elasticity; uint256 public eip1559Elasticity;
uint256 public faultGameAbsolutePrestate; uint256 public faultGameAbsolutePrestate;
uint256 public faultGameGenesisBlock;
bytes32 public faultGameGenesisOutputRoot;
uint256 public faultGameMaxDepth; uint256 public faultGameMaxDepth;
uint256 public faultGameSplitDepth;
uint256 public faultGameMaxDuration; uint256 public faultGameMaxDuration;
uint256 public outputBisectionGameGenesisBlock;
bytes32 public outputBisectionGameGenesisOutputRoot;
uint256 public outputBisectionGameSplitDepth;
uint256 public systemConfigStartBlock; uint256 public systemConfigStartBlock;
uint256 public requiredProtocolVersion; uint256 public requiredProtocolVersion;
uint256 public recommendedProtocolVersion; uint256 public recommendedProtocolVersion;
...@@ -106,10 +106,10 @@ contract DeployConfig is Script { ...@@ -106,10 +106,10 @@ contract DeployConfig is Script {
if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) { if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) {
faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate"); faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate");
faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth"); faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth");
faultGameSplitDepth = stdJson.readUint(_json, "$.faultGameSplitDepth");
faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration"); faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration");
outputBisectionGameGenesisBlock = stdJson.readUint(_json, "$.outputBisectionGameGenesisBlock"); faultGameGenesisBlock = stdJson.readUint(_json, "$.faultGameGenesisBlock");
outputBisectionGameGenesisOutputRoot = stdJson.readBytes32(_json, "$.outputBisectionGameGenesisOutputRoot"); faultGameGenesisOutputRoot = stdJson.readBytes32(_json, "$.faultGameGenesisOutputRoot");
outputBisectionGameSplitDepth = stdJson.readUint(_json, "$.outputBisectionGameSplitDepth");
} }
} }
......
...@@ -20,12 +20,19 @@ import { LibPosition } from "../src/dispute/lib/LibPosition.sol"; ...@@ -20,12 +20,19 @@ import { LibPosition } from "../src/dispute/lib/LibPosition.sol";
*/ */
contract FaultDisputeGameViz is Script, FaultDisputeGame_Init { contract FaultDisputeGameViz is Script, FaultDisputeGame_Init {
/// @dev The root claim of the game. /// @dev The root claim of the game.
Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32(uint256(10))); Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32(uint256(1)));
/// @dev The absolute prestate of the trace. /// @dev The absolute prestate of the trace.
Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32(uint256(0))); Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32((uint256(3) << 248) | uint256(0)));
function setUp() public override { function setUp() public override {
super.init(ROOT_CLAIM, ABSOLUTE_PRESTATE); super.setUp();
super.init({
rootClaim: ROOT_CLAIM,
absolutePrestate: ABSOLUTE_PRESTATE,
l2BlockNumber: 0x10,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
} }
/** /**
......
...@@ -87,26 +87,26 @@ ...@@ -87,26 +87,26 @@
"initCodeHash": "0x0da844fb4dd22f252ff631524f01f45edf43bca7558fe45f71d711b79af01742", "initCodeHash": "0x0da844fb4dd22f252ff631524f01f45edf43bca7558fe45f71d711b79af01742",
"sourceCodeHash": "0x1afb1d392e8f6a58ff86ea7f648e0d1756d4ba8d0d964279d58a390deaa53b7e" "sourceCodeHash": "0x1afb1d392e8f6a58ff86ea7f648e0d1756d4ba8d0d964279d58a390deaa53b7e"
}, },
"src/dispute/BlockOracle.sol": {
"initCodeHash": "0x183ce41fb2842c9853f08955ddd91e345126028fad64e07ed14f593cbf9c88bc",
"sourceCodeHash": "0xabbfe0def64318b467e098bb518100a4cbf7ad4e803d13fbb187f25df35de8dd"
},
"src/dispute/DisputeGameFactory.sol": { "src/dispute/DisputeGameFactory.sol": {
"initCodeHash": "0x84a15994d275bea8a96af83a46849e74eb573aa579db86350b6fe358bd61ec57", "initCodeHash": "0x84a15994d275bea8a96af83a46849e74eb573aa579db86350b6fe358bd61ec57",
"sourceCodeHash": "0x64290a5d8138c46d2ecd308e3ef62ba04663049cce8a271b9a686ddd2e630391" "sourceCodeHash": "0x64290a5d8138c46d2ecd308e3ef62ba04663049cce8a271b9a686ddd2e630391"
}, },
"src/dispute/FaultDisputeGame.sol": { "src/dispute/FaultDisputeGame.sol": {
"initCodeHash": "0x77ae981180b9c2fc9cf33b7862551f74368e8889f68c2f535f46730d1272eba3", "initCodeHash": "0xbd89fd5227cf5c52309cbaa24175351491180f6ff5b7a40a542bfc0e80d6ec00",
"sourceCodeHash": "0xa995b54dce03ddf5c9c47451bd7181996b91398ad66b54ab0b8cbf582863a33e" "sourceCodeHash": "0xbf39a67d44f5bcdaf65b202c393c538a87903a172056f4fb548645120f38d88c"
}, },
"src/dispute/OutputBisectionGame.sol": { "src/legacy/BlockOracle.sol": {
"initCodeHash": "0x10596ff55c460324b6b442fe19d7f849e6dd8202c9b4514ca979ca02be339060", "initCodeHash": "0x183ce41fb2842c9853f08955ddd91e345126028fad64e07ed14f593cbf9c88bc",
"sourceCodeHash": "0xe0fada6499eb1a24a4e1ccce50568f0b10617dec0fc8af189bff2c9ab4c320ce" "sourceCodeHash": "0xabbfe0def64318b467e098bb518100a4cbf7ad4e803d13fbb187f25df35de8dd"
}, },
"src/legacy/DeployerWhitelist.sol": { "src/legacy/DeployerWhitelist.sol": {
"initCodeHash": "0x8de80fb23b26dd9d849f6328e56ea7c173cd9e9ce1f05c9beea559d1720deb3d", "initCodeHash": "0x8de80fb23b26dd9d849f6328e56ea7c173cd9e9ce1f05c9beea559d1720deb3d",
"sourceCodeHash": "0xb518a9f56136a910f2450098b4823c9982f93883fe4a9ef6f6b0a89355965d38" "sourceCodeHash": "0xb518a9f56136a910f2450098b4823c9982f93883fe4a9ef6f6b0a89355965d38"
}, },
"src/legacy/FaultDisputeGame.sol": {
"initCodeHash": "0xbd89fd5227cf5c52309cbaa24175351491180f6ff5b7a40a542bfc0e80d6ec00",
"sourceCodeHash": "0xdc119ac6d4766e6ee88fcaff31f7ef3b8f5ac79055bc426dd3c6872f3df0eb30"
},
"src/legacy/L1BlockNumber.sol": { "src/legacy/L1BlockNumber.sol": {
"initCodeHash": "0xd586c4f93caf1753e53fcdc05eb547c1f3a69afda2904ae9f9d851b73e1c9c1d", "initCodeHash": "0xd586c4f93caf1753e53fcdc05eb547c1f3a69afda2904ae9f9d851b73e1c9c1d",
"sourceCodeHash": "0x2a42b124a918a987da60934d9059a72d4fe13dba2609b9f80146f9c8a3fc8293" "sourceCodeHash": "0x2a42b124a918a987da60934d9059a72d4fe13dba2609b9f80146f9c8a3fc8293"
......
...@@ -684,220 +684,220 @@ ...@@ -684,220 +684,220 @@
"filename_relative": "src/universal/Proxy.sol" "filename_relative": "src/universal/Proxy.sol"
}, },
{ {
"id": "89460308ae3bd86a612657eb7bfe28221ced6a7a7fe723ec2a19149bfc819cb5", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium",
"confidence": "High",
"check": "locked-ether",
"description": "Contract locking ether found:\n\tContract L2OutputOracle (src/L1/L2OutputOracle.sol#14-296) has payable functions:\n\t - L2OutputOracle.proposeL2Output(bytes32,uint256,bytes32,uint256) (src/L1/L2OutputOracle.sol#168-215)\n\tBut does not have a function to withdraw the ether\n",
"type": "contract",
"name": "L2OutputOracle",
"start": 611,
"length": 12768,
"filename_relative": "src/L1/L2OutputOracle.sol"
},
{
"id": "89460308ae3bd86a612657eb7bfe28221ced6a7a7fe723ec2a19149bfc819cb5",
"impact": "Medium",
"confidence": "High",
"check": "locked-ether",
"description": "Contract locking ether found:\n\tContract L2OutputOracle (src/L1/L2OutputOracle.sol#14-296) has payable functions:\n\t - L2OutputOracle.proposeL2Output(bytes32,uint256,bytes32,uint256) (src/L1/L2OutputOracle.sol#168-215)\n\tBut does not have a function to withdraw the ether\n",
"type": "function",
"name": "proposeL2Output",
"start": 7598,
"length": 1981,
"filename_relative": "src/L1/L2OutputOracle.sol"
},
{
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "contract", "type": "contract",
"name": "FaultDisputeGame", "name": "LegacyFaultDisputeGame",
"start": 1080, "start": 1236,
"length": 24930, "length": 24996,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "attack", "name": "attack",
"start": 2181, "start": 2214,
"length": 69, "length": 69,
"filename_relative": "src/dispute/interfaces/IFaultDisputeGame.sol" "filename_relative": "src/legacy/interfaces/IFaultDisputeGame.sol"
}, },
{ {
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "defend", "name": "defend",
"start": 2454, "start": 2487,
"length": 69, "length": 69,
"filename_relative": "src/dispute/interfaces/IFaultDisputeGame.sol" "filename_relative": "src/legacy/interfaces/IFaultDisputeGame.sol"
}, },
{ {
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "resolveClaim", "name": "resolveClaim",
"start": 4428, "start": 4461,
"length": 60, "length": 60,
"filename_relative": "src/dispute/interfaces/IFaultDisputeGame.sol" "filename_relative": "src/legacy/interfaces/IFaultDisputeGame.sol"
}, },
{ {
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "move", "name": "move",
"start": 9008, "start": 9194,
"length": 3953, "length": 3953,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "attack", "name": "attack",
"start": 13005, "start": 13197,
"length": 118, "length": 118,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "defend", "name": "defend",
"start": 13167, "start": 13365,
"length": 119, "length": 119,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81", "id": "574efbeca53c81e42e08184eeed2138dd615e78ba64270f3978b4a962f26f079",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#24-557) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#51)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#56)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#83)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#271-273)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#276-278)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract LegacyFaultDisputeGame (src/legacy/FaultDisputeGame.sol#26-559) has payable functions:\n\t - ILegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#51)\n\t - ILegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/interfaces/IFaultDisputeGame.sol#56)\n\t - ILegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/interfaces/IFaultDisputeGame.sol#83)\n\t - LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t - LegacyFaultDisputeGame.attack(uint256,Claim) (src/legacy/FaultDisputeGame.sol#273-275)\n\t - LegacyFaultDisputeGame.defend(uint256,Claim) (src/legacy/FaultDisputeGame.sol#278-280)\n\t - LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "resolveClaim", "name": "resolveClaim",
"start": 17110, "start": 17332,
"length": 2033, "length": 2033,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "89460308ae3bd86a612657eb7bfe28221ced6a7a7fe723ec2a19149bfc819cb5",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract L2OutputOracle (src/L1/L2OutputOracle.sol#14-296) has payable functions:\n\t - L2OutputOracle.proposeL2Output(bytes32,uint256,bytes32,uint256) (src/L1/L2OutputOracle.sol#168-215)\n\tBut does not have a function to withdraw the ether\n",
"type": "contract", "type": "contract",
"name": "OutputBisectionGame", "name": "L2OutputOracle",
"start": 973, "start": 611,
"length": 32905, "length": 12768,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/L1/L2OutputOracle.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "89460308ae3bd86a612657eb7bfe28221ced6a7a7fe723ec2a19149bfc819cb5",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract L2OutputOracle (src/L1/L2OutputOracle.sol#14-296) has payable functions:\n\t - L2OutputOracle.proposeL2Output(bytes32,uint256,bytes32,uint256) (src/L1/L2OutputOracle.sol#168-215)\n\tBut does not have a function to withdraw the ether\n",
"type": "function",
"name": "proposeL2Output",
"start": 7598,
"length": 1981,
"filename_relative": "src/L1/L2OutputOracle.sol"
},
{
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium",
"confidence": "High",
"check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "contract",
"name": "FaultDisputeGame",
"start": 961,
"length": 32911,
"filename_relative": "src/dispute/FaultDisputeGame.sol"
},
{
"id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium",
"confidence": "High",
"check": "locked-ether",
"description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "attack", "name": "attack",
"start": 1139, "start": 1133,
"length": 69, "length": 69,
"filename_relative": "src/dispute/interfaces/IOutputBisectionGame.sol" "filename_relative": "src/dispute/interfaces/IFaultDisputeGame.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "defend", "name": "defend",
"start": 1412, "start": 1406,
"length": 69, "length": 69,
"filename_relative": "src/dispute/interfaces/IOutputBisectionGame.sol" "filename_relative": "src/dispute/interfaces/IFaultDisputeGame.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "resolveClaim", "name": "resolveClaim",
"start": 3429, "start": 3423,
"length": 60, "length": 60,
"filename_relative": "src/dispute/interfaces/IOutputBisectionGame.sol" "filename_relative": "src/dispute/interfaces/IFaultDisputeGame.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "move", "name": "move",
"start": 9620, "start": 9596,
"length": 4512, "length": 4545,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "attack", "name": "attack",
"start": 14179, "start": 14185,
"length": 118, "length": 118,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "defend", "name": "defend",
"start": 14344, "start": 14347,
"length": 119, "length": 119,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "a163cee00f9eadca42657b9e68feeb6933902bdb0d38f8fa1490a82a355b68dc", "id": "99c01b42fc96fd11586bce47c0e6edbb6697d3feda3cfe6ede5b03b79ac5af81",
"impact": "Medium", "impact": "Medium",
"confidence": "High", "confidence": "High",
"check": "locked-ether", "check": "locked-ether",
"description": "Contract locking ether found:\n\tContract OutputBisectionGame (src/dispute/OutputBisectionGame.sol#22-700) has payable functions:\n\t - IOutputBisectionGame.attack(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#30)\n\t - IOutputBisectionGame.defend(uint256,Claim) (src/dispute/interfaces/IOutputBisectionGame.sol#35)\n\t - IOutputBisectionGame.resolveClaim(uint256) (src/dispute/interfaces/IOutputBisectionGame.sol#62)\n\t - OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t - OutputBisectionGame.attack(uint256,Claim) (src/dispute/OutputBisectionGame.sol#287-289)\n\t - OutputBisectionGame.defend(uint256,Claim) (src/dispute/OutputBisectionGame.sol#292-294)\n\t - OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\tBut does not have a function to withdraw the ether\n", "description": "Contract locking ether found:\n\tContract FaultDisputeGame (src/dispute/FaultDisputeGame.sol#22-701) has payable functions:\n\t - IFaultDisputeGame.attack(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#30)\n\t - IFaultDisputeGame.defend(uint256,Claim) (src/dispute/interfaces/IFaultDisputeGame.sol#35)\n\t - IFaultDisputeGame.resolveClaim(uint256) (src/dispute/interfaces/IFaultDisputeGame.sol#62)\n\t - FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t - FaultDisputeGame.attack(uint256,Claim) (src/dispute/FaultDisputeGame.sol#288-290)\n\t - FaultDisputeGame.defend(uint256,Claim) (src/dispute/FaultDisputeGame.sol#293-295)\n\t - FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\tBut does not have a function to withdraw the ether\n",
"type": "function", "type": "function",
"name": "resolveClaim", "name": "resolveClaim",
"start": 18011, "start": 18005,
"length": 2043, "length": 2043,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "c0920fe4b6b04a2b81f69b85402d465719d06978441052f49a6582415934a1bf", "id": "c0920fe4b6b04a2b81f69b85402d465719d06978441052f49a6582415934a1bf",
...@@ -1056,40 +1056,40 @@ ...@@ -1056,40 +1056,40 @@
"filename_relative": "src/EAS/resolver/SchemaResolver.sol" "filename_relative": "src/EAS/resolver/SchemaResolver.sol"
}, },
{ {
"id": "0e1e451177ca06fd343007706a5c0c9d51f9fe188265e5d192703a2a4db433fc", "id": "02c295f90e42732f4b43ba4b3368c636e999d79a4751c1771896a7e9062f24fe",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "reentrancy-no-eth", "check": "reentrancy-no-eth",
"description": "Reentrancy in FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#121-184):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim) (src/dispute/FaultDisputeGame.sol#177)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/FaultDisputeGame.sol#183)\n\tFaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#68) can be used in cross function reentrancies:\n\t- FaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#68)\n\t- FaultDisputeGame.claimDataLen() (src/dispute/FaultDisputeGame.sol#532-534)\n\t- FaultDisputeGame.findTraceAncestor(Position,uint256) (src/dispute/FaultDisputeGame.sol#546-556)\n\t- FaultDisputeGame.initialize() (src/dispute/FaultDisputeGame.sol#448-529)\n\t- FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t- FaultDisputeGame.resolve() (src/dispute/FaultDisputeGame.sol#360-369)\n\t- FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\t- FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#121-184)\n", "description": "Reentrancy in LegacyFaultDisputeGame.step(uint256,bool,bytes,bytes) (src/legacy/FaultDisputeGame.sol#123-186):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim) (src/legacy/FaultDisputeGame.sol#179)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/legacy/FaultDisputeGame.sol#185)\n\tLegacyFaultDisputeGame.claimData (src/legacy/FaultDisputeGame.sol#70) can be used in cross function reentrancies:\n\t- LegacyFaultDisputeGame.claimData (src/legacy/FaultDisputeGame.sol#70)\n\t- LegacyFaultDisputeGame.claimDataLen() (src/legacy/FaultDisputeGame.sol#534-536)\n\t- LegacyFaultDisputeGame.findTraceAncestor(Position,uint256) (src/legacy/FaultDisputeGame.sol#548-558)\n\t- LegacyFaultDisputeGame.initialize() (src/legacy/FaultDisputeGame.sol#450-531)\n\t- LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t- LegacyFaultDisputeGame.resolve() (src/legacy/FaultDisputeGame.sol#362-371)\n\t- LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\t- LegacyFaultDisputeGame.step(uint256,bool,bytes,bytes) (src/legacy/FaultDisputeGame.sol#123-186)\n",
"type": "function", "type": "function",
"name": "step", "name": "step",
"start": 5018, "start": 5204,
"length": 3685, "length": 3685,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "0e1e451177ca06fd343007706a5c0c9d51f9fe188265e5d192703a2a4db433fc", "id": "02c295f90e42732f4b43ba4b3368c636e999d79a4751c1771896a7e9062f24fe",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "reentrancy-no-eth", "check": "reentrancy-no-eth",
"description": "Reentrancy in FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#121-184):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim) (src/dispute/FaultDisputeGame.sol#177)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/FaultDisputeGame.sol#183)\n\tFaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#68) can be used in cross function reentrancies:\n\t- FaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#68)\n\t- FaultDisputeGame.claimDataLen() (src/dispute/FaultDisputeGame.sol#532-534)\n\t- FaultDisputeGame.findTraceAncestor(Position,uint256) (src/dispute/FaultDisputeGame.sol#546-556)\n\t- FaultDisputeGame.initialize() (src/dispute/FaultDisputeGame.sol#448-529)\n\t- FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t- FaultDisputeGame.resolve() (src/dispute/FaultDisputeGame.sol#360-369)\n\t- FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\t- FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#121-184)\n", "description": "Reentrancy in LegacyFaultDisputeGame.step(uint256,bool,bytes,bytes) (src/legacy/FaultDisputeGame.sol#123-186):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim) (src/legacy/FaultDisputeGame.sol#179)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/legacy/FaultDisputeGame.sol#185)\n\tLegacyFaultDisputeGame.claimData (src/legacy/FaultDisputeGame.sol#70) can be used in cross function reentrancies:\n\t- LegacyFaultDisputeGame.claimData (src/legacy/FaultDisputeGame.sol#70)\n\t- LegacyFaultDisputeGame.claimDataLen() (src/legacy/FaultDisputeGame.sol#534-536)\n\t- LegacyFaultDisputeGame.findTraceAncestor(Position,uint256) (src/legacy/FaultDisputeGame.sol#548-558)\n\t- LegacyFaultDisputeGame.initialize() (src/legacy/FaultDisputeGame.sol#450-531)\n\t- LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t- LegacyFaultDisputeGame.resolve() (src/legacy/FaultDisputeGame.sol#362-371)\n\t- LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\t- LegacyFaultDisputeGame.step(uint256,bool,bytes,bytes) (src/legacy/FaultDisputeGame.sol#123-186)\n",
"type": "node", "type": "node",
"name": "validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim)", "name": "validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim)",
"start": 8264, "start": 8450,
"length": 80, "length": 80,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "0e1e451177ca06fd343007706a5c0c9d51f9fe188265e5d192703a2a4db433fc", "id": "02c295f90e42732f4b43ba4b3368c636e999d79a4751c1771896a7e9062f24fe",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "reentrancy-no-eth", "check": "reentrancy-no-eth",
"description": "Reentrancy in FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#121-184):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim) (src/dispute/FaultDisputeGame.sol#177)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/FaultDisputeGame.sol#183)\n\tFaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#68) can be used in cross function reentrancies:\n\t- FaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#68)\n\t- FaultDisputeGame.claimDataLen() (src/dispute/FaultDisputeGame.sol#532-534)\n\t- FaultDisputeGame.findTraceAncestor(Position,uint256) (src/dispute/FaultDisputeGame.sol#546-556)\n\t- FaultDisputeGame.initialize() (src/dispute/FaultDisputeGame.sol#448-529)\n\t- FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#190-268)\n\t- FaultDisputeGame.resolve() (src/dispute/FaultDisputeGame.sol#360-369)\n\t- FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#372-422)\n\t- FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#121-184)\n", "description": "Reentrancy in LegacyFaultDisputeGame.step(uint256,bool,bytes,bytes) (src/legacy/FaultDisputeGame.sol#123-186):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,0) == Claim.unwrap(postState.claim) (src/legacy/FaultDisputeGame.sol#179)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/legacy/FaultDisputeGame.sol#185)\n\tLegacyFaultDisputeGame.claimData (src/legacy/FaultDisputeGame.sol#70) can be used in cross function reentrancies:\n\t- LegacyFaultDisputeGame.claimData (src/legacy/FaultDisputeGame.sol#70)\n\t- LegacyFaultDisputeGame.claimDataLen() (src/legacy/FaultDisputeGame.sol#534-536)\n\t- LegacyFaultDisputeGame.findTraceAncestor(Position,uint256) (src/legacy/FaultDisputeGame.sol#548-558)\n\t- LegacyFaultDisputeGame.initialize() (src/legacy/FaultDisputeGame.sol#450-531)\n\t- LegacyFaultDisputeGame.move(uint256,Claim,bool) (src/legacy/FaultDisputeGame.sol#192-270)\n\t- LegacyFaultDisputeGame.resolve() (src/legacy/FaultDisputeGame.sol#362-371)\n\t- LegacyFaultDisputeGame.resolveClaim(uint256) (src/legacy/FaultDisputeGame.sol#374-424)\n\t- LegacyFaultDisputeGame.step(uint256,bool,bytes,bytes) (src/legacy/FaultDisputeGame.sol#123-186)\n",
"type": "node", "type": "node",
"name": "parent.countered = true", "name": "parent.countered = true",
"start": 8673, "start": 8859,
"length": 23, "length": 23,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "1349b68c3b08ecdf27782bd74d9fecadf1739eef738171cbbba403c77a29f424", "id": "1349b68c3b08ecdf27782bd74d9fecadf1739eef738171cbbba403c77a29f424",
...@@ -1176,40 +1176,40 @@ ...@@ -1176,40 +1176,40 @@
"filename_relative": "src/L1/DelayedVetoable.sol" "filename_relative": "src/L1/DelayedVetoable.sol"
}, },
{ {
"id": "d82cfe766b00c59f366ae7274ce981a0720d0b8df7cbbcdb554745f33a3a7992", "id": "d88c6033eee20fb40bd07078b2901d30fffb58b210979c8669346c8edd606ba1",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "reentrancy-no-eth", "check": "reentrancy-no-eth",
"description": "Reentrancy in OutputBisectionGame.step(uint256,bool,bytes,bytes) (src/dispute/OutputBisectionGame.sol#124-191):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim) (src/dispute/OutputBisectionGame.sol#184)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/OutputBisectionGame.sol#190)\n\tOutputBisectionGame.claimData (src/dispute/OutputBisectionGame.sol#72) can be used in cross function reentrancies:\n\t- OutputBisectionGame.claimData (src/dispute/OutputBisectionGame.sol#72)\n\t- OutputBisectionGame.claimDataLen() (src/dispute/OutputBisectionGame.sol#486-488)\n\t- OutputBisectionGame.findStartingAndDisputedOutputs(uint256) (src/dispute/OutputBisectionGame.sol#604-665)\n\t- OutputBisectionGame.findTraceAncestor(Position,uint256,bool) (src/dispute/OutputBisectionGame.sol#577-595)\n\t- OutputBisectionGame.initialize() (src/dispute/OutputBisectionGame.sol#440-483)\n\t- OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t- OutputBisectionGame.resolve() (src/dispute/OutputBisectionGame.sol#349-361)\n\t- OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\t- OutputBisectionGame.step(uint256,bool,bytes,bytes) (src/dispute/OutputBisectionGame.sol#124-191)\n", "description": "Reentrancy in FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim) (src/dispute/FaultDisputeGame.sol#184)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/FaultDisputeGame.sol#190)\n\tFaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#72) can be used in cross function reentrancies:\n\t- FaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#72)\n\t- FaultDisputeGame.claimDataLen() (src/dispute/FaultDisputeGame.sol#487-489)\n\t- FaultDisputeGame.findStartingAndDisputedOutputs(uint256) (src/dispute/FaultDisputeGame.sol#605-666)\n\t- FaultDisputeGame.findTraceAncestor(Position,uint256,bool) (src/dispute/FaultDisputeGame.sol#578-596)\n\t- FaultDisputeGame.initialize() (src/dispute/FaultDisputeGame.sol#441-484)\n\t- FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t- FaultDisputeGame.resolve() (src/dispute/FaultDisputeGame.sol#350-362)\n\t- FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\t- FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191)\n",
"type": "function", "type": "function",
"name": "step", "name": "step",
"start": 5053, "start": 5029,
"length": 4262, "length": 4262,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "d82cfe766b00c59f366ae7274ce981a0720d0b8df7cbbcdb554745f33a3a7992", "id": "d88c6033eee20fb40bd07078b2901d30fffb58b210979c8669346c8edd606ba1",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "reentrancy-no-eth", "check": "reentrancy-no-eth",
"description": "Reentrancy in OutputBisectionGame.step(uint256,bool,bytes,bytes) (src/dispute/OutputBisectionGame.sol#124-191):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim) (src/dispute/OutputBisectionGame.sol#184)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/OutputBisectionGame.sol#190)\n\tOutputBisectionGame.claimData (src/dispute/OutputBisectionGame.sol#72) can be used in cross function reentrancies:\n\t- OutputBisectionGame.claimData (src/dispute/OutputBisectionGame.sol#72)\n\t- OutputBisectionGame.claimDataLen() (src/dispute/OutputBisectionGame.sol#486-488)\n\t- OutputBisectionGame.findStartingAndDisputedOutputs(uint256) (src/dispute/OutputBisectionGame.sol#604-665)\n\t- OutputBisectionGame.findTraceAncestor(Position,uint256,bool) (src/dispute/OutputBisectionGame.sol#577-595)\n\t- OutputBisectionGame.initialize() (src/dispute/OutputBisectionGame.sol#440-483)\n\t- OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t- OutputBisectionGame.resolve() (src/dispute/OutputBisectionGame.sol#349-361)\n\t- OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\t- OutputBisectionGame.step(uint256,bool,bytes,bytes) (src/dispute/OutputBisectionGame.sol#124-191)\n", "description": "Reentrancy in FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim) (src/dispute/FaultDisputeGame.sol#184)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/FaultDisputeGame.sol#190)\n\tFaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#72) can be used in cross function reentrancies:\n\t- FaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#72)\n\t- FaultDisputeGame.claimDataLen() (src/dispute/FaultDisputeGame.sol#487-489)\n\t- FaultDisputeGame.findStartingAndDisputedOutputs(uint256) (src/dispute/FaultDisputeGame.sol#605-666)\n\t- FaultDisputeGame.findTraceAncestor(Position,uint256,bool) (src/dispute/FaultDisputeGame.sol#578-596)\n\t- FaultDisputeGame.initialize() (src/dispute/FaultDisputeGame.sol#441-484)\n\t- FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t- FaultDisputeGame.resolve() (src/dispute/FaultDisputeGame.sol#350-362)\n\t- FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\t- FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191)\n",
"type": "node", "type": "node",
"name": "validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim)", "name": "validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim)",
"start": 8860, "start": 8836,
"length": 96, "length": 96,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "d82cfe766b00c59f366ae7274ce981a0720d0b8df7cbbcdb554745f33a3a7992", "id": "d88c6033eee20fb40bd07078b2901d30fffb58b210979c8669346c8edd606ba1",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "reentrancy-no-eth", "check": "reentrancy-no-eth",
"description": "Reentrancy in OutputBisectionGame.step(uint256,bool,bytes,bytes) (src/dispute/OutputBisectionGame.sol#124-191):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim) (src/dispute/OutputBisectionGame.sol#184)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/OutputBisectionGame.sol#190)\n\tOutputBisectionGame.claimData (src/dispute/OutputBisectionGame.sol#72) can be used in cross function reentrancies:\n\t- OutputBisectionGame.claimData (src/dispute/OutputBisectionGame.sol#72)\n\t- OutputBisectionGame.claimDataLen() (src/dispute/OutputBisectionGame.sol#486-488)\n\t- OutputBisectionGame.findStartingAndDisputedOutputs(uint256) (src/dispute/OutputBisectionGame.sol#604-665)\n\t- OutputBisectionGame.findTraceAncestor(Position,uint256,bool) (src/dispute/OutputBisectionGame.sol#577-595)\n\t- OutputBisectionGame.initialize() (src/dispute/OutputBisectionGame.sol#440-483)\n\t- OutputBisectionGame.move(uint256,Claim,bool) (src/dispute/OutputBisectionGame.sol#197-284)\n\t- OutputBisectionGame.resolve() (src/dispute/OutputBisectionGame.sol#349-361)\n\t- OutputBisectionGame.resolveClaim(uint256) (src/dispute/OutputBisectionGame.sol#364-414)\n\t- OutputBisectionGame.step(uint256,bool,bytes,bytes) (src/dispute/OutputBisectionGame.sol#124-191)\n", "description": "Reentrancy in FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,Hash.unwrap(uuid)) == Claim.unwrap(postState.claim) (src/dispute/FaultDisputeGame.sol#184)\n\tState variables written after the call(s):\n\t- parent.countered = true (src/dispute/FaultDisputeGame.sol#190)\n\tFaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#72) can be used in cross function reentrancies:\n\t- FaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#72)\n\t- FaultDisputeGame.claimDataLen() (src/dispute/FaultDisputeGame.sol#487-489)\n\t- FaultDisputeGame.findStartingAndDisputedOutputs(uint256) (src/dispute/FaultDisputeGame.sol#605-666)\n\t- FaultDisputeGame.findTraceAncestor(Position,uint256,bool) (src/dispute/FaultDisputeGame.sol#578-596)\n\t- FaultDisputeGame.initialize() (src/dispute/FaultDisputeGame.sol#441-484)\n\t- FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-285)\n\t- FaultDisputeGame.resolve() (src/dispute/FaultDisputeGame.sol#350-362)\n\t- FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#365-415)\n\t- FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191)\n",
"type": "node", "type": "node",
"name": "parent.countered = true", "name": "parent.countered = true",
"start": 9285, "start": 9261,
"length": 23, "length": 23,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "138bfe0b87067edda58ea1bb24d88b46c26dd0da82a6818486cf28b4cb185d01", "id": "138bfe0b87067edda58ea1bb24d88b46c26dd0da82a6818486cf28b4cb185d01",
...@@ -1284,40 +1284,40 @@ ...@@ -1284,40 +1284,40 @@
"filename_relative": "src/L1/OptimismPortal.sol" "filename_relative": "src/L1/OptimismPortal.sol"
}, },
{ {
"id": "0369380fef18a61639eac6a12773df792e9969e7bb20eddde54ccf3a263a0987", "id": "01e4a30204e01c626968d72223b5421cd6ee8535aa9c3c37062220c6a62f4fed",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "uninitialized-local", "check": "uninitialized-local",
"description": "FaultDisputeGame.move(uint256,Claim,bool).grandparentClock (src/dispute/FaultDisputeGame.sol#215) is a local variable never initialized\n", "description": "FaultDisputeGame.findStartingAndDisputedOutputs(uint256).currentDepth (src/dispute/FaultDisputeGame.sol#623) is a local variable never initialized\n",
"type": "variable", "type": "variable",
"name": "grandparentClock", "name": "currentDepth",
"start": 10602, "start": 29599,
"length": 22, "length": 20,
"filename_relative": "src/dispute/FaultDisputeGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "b806faf2b63e910b939c5ff4b591b1109887080a010986f2af2c30787dbc2a10", "id": "0369380fef18a61639eac6a12773df792e9969e7bb20eddde54ccf3a263a0987",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "uninitialized-local", "check": "uninitialized-local",
"description": "OutputBisectionGame.findStartingAndDisputedOutputs(uint256).currentDepth (src/dispute/OutputBisectionGame.sol#622) is a local variable never initialized\n", "description": "FaultDisputeGame.move(uint256,Claim,bool).grandparentClock (src/dispute/FaultDisputeGame.sol#232) is a local variable never initialized\n",
"type": "variable", "type": "variable",
"name": "currentDepth", "name": "grandparentClock",
"start": 29605, "start": 11770,
"length": 20, "length": 22,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/dispute/FaultDisputeGame.sol"
}, },
{ {
"id": "c27cc53c209fdabd18ab2c8f2cddf2053516bcaaa39122d29702ac143d835a2f", "id": "2a84ddcc045ebc504f7f95046a892a3a6f19683987f1607a97ba6d09a2e13c45",
"impact": "Medium", "impact": "Medium",
"confidence": "Medium", "confidence": "Medium",
"check": "uninitialized-local", "check": "uninitialized-local",
"description": "OutputBisectionGame.move(uint256,Claim,bool).grandparentClock (src/dispute/OutputBisectionGame.sol#232) is a local variable never initialized\n", "description": "LegacyFaultDisputeGame.move(uint256,Claim,bool).grandparentClock (src/legacy/FaultDisputeGame.sol#217) is a local variable never initialized\n",
"type": "variable", "type": "variable",
"name": "grandparentClock", "name": "grandparentClock",
"start": 11794, "start": 10788,
"length": 22, "length": 22,
"filename_relative": "src/dispute/OutputBisectionGame.sol" "filename_relative": "src/legacy/FaultDisputeGame.sol"
}, },
{ {
"id": "9ad67b006fc175893dd26d35a020a52dd8524709d87cca61212ee0e147eb992b", "id": "9ad67b006fc175893dd26d35a020a52dd8524709d87cca61212ee0e147eb992b",
......
...@@ -11,11 +11,26 @@ ...@@ -11,11 +11,26 @@
"name": "_absolutePrestate", "name": "_absolutePrestate",
"type": "bytes32" "type": "bytes32"
}, },
{
"internalType": "uint256",
"name": "_genesisBlockNumber",
"type": "uint256"
},
{
"internalType": "Hash",
"name": "_genesisOutputRoot",
"type": "bytes32"
},
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_maxGameDepth", "name": "_maxGameDepth",
"type": "uint256" "type": "uint256"
}, },
{
"internalType": "uint256",
"name": "_splitDepth",
"type": "uint256"
},
{ {
"internalType": "Duration", "internalType": "Duration",
"name": "_gameDuration", "name": "_gameDuration",
...@@ -25,16 +40,6 @@ ...@@ -25,16 +40,6 @@
"internalType": "contract IBigStepper", "internalType": "contract IBigStepper",
"name": "_vm", "name": "_vm",
"type": "address" "type": "address"
},
{
"internalType": "contract L2OutputOracle",
"name": "_l2oo",
"type": "address"
},
{
"internalType": "contract BlockOracle",
"name": "_blockOracle",
"type": "address"
} }
], ],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
...@@ -42,82 +47,17 @@ ...@@ -42,82 +47,17 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "ABSOLUTE_PRESTATE", "name": "absolutePrestate",
"outputs": [ "outputs": [
{ {
"internalType": "Claim", "internalType": "Claim",
"name": "", "name": "absolutePrestate_",
"type": "bytes32" "type": "bytes32"
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "BLOCK_ORACLE",
"outputs": [
{
"internalType": "contract BlockOracle",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "GAME_DURATION",
"outputs": [
{
"internalType": "Duration",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "L2_OUTPUT_ORACLE",
"outputs": [
{
"internalType": "contract L2OutputOracle",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_GAME_DEPTH",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VM",
"outputs": [
{
"internalType": "contract IBigStepper",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -126,9 +66,9 @@ ...@@ -126,9 +66,9 @@
"type": "uint256" "type": "uint256"
}, },
{ {
"internalType": "bytes32", "internalType": "uint256",
"name": "_localContext", "name": "_execLeafIdx",
"type": "bytes32" "type": "uint256"
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
...@@ -291,6 +231,19 @@ ...@@ -291,6 +231,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "gameDuration",
"outputs": [
{
"internalType": "Duration",
"name": "gameDuration_",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "gameType", "name": "gameType",
...@@ -306,22 +259,35 @@ ...@@ -306,22 +259,35 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "initialize", "name": "genesisBlockNumber",
"outputs": [], "outputs": [
"stateMutability": "nonpayable", {
"internalType": "uint256",
"name": "genesisBlockNumber_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
"inputs": [], "inputs": [],
"name": "l1BlockNumber", "name": "genesisOutputRoot",
"outputs": [ "outputs": [
{ {
"internalType": "uint256", "internalType": "Hash",
"name": "l1BlockNumber_", "name": "genesisOutputRoot_",
"type": "uint256" "type": "bytes32"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{ {
...@@ -350,6 +316,19 @@ ...@@ -350,6 +316,19 @@
"stateMutability": "pure", "stateMutability": "pure",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "maxGameDepth",
"outputs": [
{
"internalType": "uint256",
"name": "maxGameDepth_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -373,58 +352,6 @@ ...@@ -373,58 +352,6 @@
"stateMutability": "payable", "stateMutability": "payable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "proposals",
"outputs": [
{
"components": [
{
"internalType": "uint128",
"name": "index",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "l2BlockNumber",
"type": "uint128"
},
{
"internalType": "Hash",
"name": "outputRoot",
"type": "bytes32"
}
],
"internalType": "struct IFaultDisputeGame.OutputProposal",
"name": "starting",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint128",
"name": "index",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "l2BlockNumber",
"type": "uint128"
},
{
"internalType": "Hash",
"name": "outputRoot",
"type": "bytes32"
}
],
"internalType": "struct IFaultDisputeGame.OutputProposal",
"name": "disputed",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "resolve", "name": "resolve",
...@@ -451,6 +378,19 @@ ...@@ -451,6 +378,19 @@
"stateMutability": "payable", "stateMutability": "payable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "resolvedAt",
"outputs": [
{
"internalType": "Timestamp",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "rootClaim", "name": "rootClaim",
...@@ -464,6 +404,19 @@ ...@@ -464,6 +404,19 @@
"stateMutability": "pure", "stateMutability": "pure",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "splitDepth",
"outputs": [
{
"internalType": "uint256",
"name": "splitDepth_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "status", "name": "status",
...@@ -518,6 +471,19 @@ ...@@ -518,6 +471,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "vm",
"outputs": [
{
"internalType": "contract IBigStepper",
"name": "vm_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
...@@ -561,6 +527,11 @@ ...@@ -561,6 +527,11 @@
"name": "CannotDefendRootClaim", "name": "CannotDefendRootClaim",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "ClaimAboveSplit",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "ClaimAlreadyExists", "name": "ClaimAlreadyExists",
...@@ -591,6 +562,11 @@ ...@@ -591,6 +562,11 @@
"name": "GameNotInProgress", "name": "GameNotInProgress",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "InvalidLocalIdent",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "InvalidParent", "name": "InvalidParent",
...@@ -603,7 +579,7 @@ ...@@ -603,7 +579,7 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "L1HeadTooOld", "name": "InvalidSplitDepth",
"type": "error" "type": "error"
}, },
{ {
......
...@@ -11,26 +11,11 @@ ...@@ -11,26 +11,11 @@
"name": "_absolutePrestate", "name": "_absolutePrestate",
"type": "bytes32" "type": "bytes32"
}, },
{
"internalType": "uint256",
"name": "_genesisBlockNumber",
"type": "uint256"
},
{
"internalType": "Hash",
"name": "_genesisOutputRoot",
"type": "bytes32"
},
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_maxGameDepth", "name": "_maxGameDepth",
"type": "uint256" "type": "uint256"
}, },
{
"internalType": "uint256",
"name": "_splitDepth",
"type": "uint256"
},
{ {
"internalType": "Duration", "internalType": "Duration",
"name": "_gameDuration", "name": "_gameDuration",
...@@ -40,6 +25,16 @@ ...@@ -40,6 +25,16 @@
"internalType": "contract IBigStepper", "internalType": "contract IBigStepper",
"name": "_vm", "name": "_vm",
"type": "address" "type": "address"
},
{
"internalType": "contract L2OutputOracle",
"name": "_l2oo",
"type": "address"
},
{
"internalType": "contract BlockOracle",
"name": "_blockOracle",
"type": "address"
} }
], ],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
...@@ -47,17 +42,82 @@ ...@@ -47,17 +42,82 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "absolutePrestate", "name": "ABSOLUTE_PRESTATE",
"outputs": [ "outputs": [
{ {
"internalType": "Claim", "internalType": "Claim",
"name": "absolutePrestate_", "name": "",
"type": "bytes32" "type": "bytes32"
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "BLOCK_ORACLE",
"outputs": [
{
"internalType": "contract BlockOracle",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "GAME_DURATION",
"outputs": [
{
"internalType": "Duration",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "L2_OUTPUT_ORACLE",
"outputs": [
{
"internalType": "contract L2OutputOracle",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_GAME_DEPTH",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VM",
"outputs": [
{
"internalType": "contract IBigStepper",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -66,9 +126,9 @@ ...@@ -66,9 +126,9 @@
"type": "uint256" "type": "uint256"
}, },
{ {
"internalType": "uint256", "internalType": "bytes32",
"name": "_execLeafIdx", "name": "_localContext",
"type": "uint256" "type": "bytes32"
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
...@@ -231,19 +291,6 @@ ...@@ -231,19 +291,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "gameDuration",
"outputs": [
{
"internalType": "Duration",
"name": "gameDuration_",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "gameType", "name": "gameType",
...@@ -259,35 +306,22 @@ ...@@ -259,35 +306,22 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "genesisBlockNumber", "name": "initialize",
"outputs": [ "outputs": [],
{ "stateMutability": "nonpayable",
"internalType": "uint256",
"name": "genesisBlockNumber_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
"inputs": [], "inputs": [],
"name": "genesisOutputRoot", "name": "l1BlockNumber",
"outputs": [ "outputs": [
{ {
"internalType": "Hash", "internalType": "uint256",
"name": "genesisOutputRoot_", "name": "l1BlockNumber_",
"type": "bytes32" "type": "uint256"
} }
], ],
"stateMutability": "view", "stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{ {
...@@ -316,19 +350,6 @@ ...@@ -316,19 +350,6 @@
"stateMutability": "pure", "stateMutability": "pure",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "maxGameDepth",
"outputs": [
{
"internalType": "uint256",
"name": "maxGameDepth_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -352,6 +373,58 @@ ...@@ -352,6 +373,58 @@
"stateMutability": "payable", "stateMutability": "payable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "proposals",
"outputs": [
{
"components": [
{
"internalType": "uint128",
"name": "index",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "l2BlockNumber",
"type": "uint128"
},
{
"internalType": "Hash",
"name": "outputRoot",
"type": "bytes32"
}
],
"internalType": "struct ILegacyFaultDisputeGame.OutputProposal",
"name": "starting",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint128",
"name": "index",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "l2BlockNumber",
"type": "uint128"
},
{
"internalType": "Hash",
"name": "outputRoot",
"type": "bytes32"
}
],
"internalType": "struct ILegacyFaultDisputeGame.OutputProposal",
"name": "disputed",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "resolve", "name": "resolve",
...@@ -378,19 +451,6 @@ ...@@ -378,19 +451,6 @@
"stateMutability": "payable", "stateMutability": "payable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "resolvedAt",
"outputs": [
{
"internalType": "Timestamp",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "rootClaim", "name": "rootClaim",
...@@ -404,19 +464,6 @@ ...@@ -404,19 +464,6 @@
"stateMutability": "pure", "stateMutability": "pure",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "splitDepth",
"outputs": [
{
"internalType": "uint256",
"name": "splitDepth_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "status", "name": "status",
...@@ -471,19 +518,6 @@ ...@@ -471,19 +518,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "vm",
"outputs": [
{
"internalType": "contract IBigStepper",
"name": "vm_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
...@@ -527,11 +561,6 @@ ...@@ -527,11 +561,6 @@
"name": "CannotDefendRootClaim", "name": "CannotDefendRootClaim",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "ClaimAboveSplit",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "ClaimAlreadyExists", "name": "ClaimAlreadyExists",
...@@ -562,11 +591,6 @@ ...@@ -562,11 +591,6 @@
"name": "GameNotInProgress", "name": "GameNotInProgress",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "InvalidLocalIdent",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "InvalidParent", "name": "InvalidParent",
...@@ -579,7 +603,7 @@ ...@@ -579,7 +603,7 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "InvalidSplitDepth", "name": "L1HeadTooOld",
"type": "error" "type": "error"
}, },
{ {
......
...@@ -6,60 +6,60 @@ ...@@ -6,60 +6,60 @@
"slot": "0", "slot": "0",
"type": "Timestamp" "type": "Timestamp"
}, },
{
"bytes": "8",
"label": "resolvedAt",
"offset": 8,
"slot": "0",
"type": "Timestamp"
},
{ {
"bytes": "1", "bytes": "1",
"label": "status", "label": "status",
"offset": 8, "offset": 16,
"slot": "0", "slot": "0",
"type": "enum GameStatus" "type": "enum GameStatus"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "bondManager", "label": "bondManager",
"offset": 9, "offset": 0,
"slot": "0", "slot": "1",
"type": "contract IBondManager" "type": "contract IBondManager"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "l1Head", "label": "l1Head",
"offset": 0, "offset": 0,
"slot": "1", "slot": "2",
"type": "Hash" "type": "Hash"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "claimData", "label": "claimData",
"offset": 0, "offset": 0,
"slot": "2",
"type": "struct IFaultDisputeGame.ClaimData[]"
},
{
"bytes": "128",
"label": "proposals",
"offset": 0,
"slot": "3", "slot": "3",
"type": "struct IFaultDisputeGame.OutputProposals" "type": "struct IFaultDisputeGame.ClaimData[]"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "claims", "label": "claims",
"offset": 0, "offset": 0,
"slot": "7", "slot": "4",
"type": "mapping(ClaimHash => bool)" "type": "mapping(ClaimHash => bool)"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "subgames", "label": "subgames",
"offset": 0, "offset": 0,
"slot": "8", "slot": "5",
"type": "mapping(uint256 => uint256[])" "type": "mapping(uint256 => uint256[])"
}, },
{ {
"bytes": "1", "bytes": "1",
"label": "subgameAtRootResolved", "label": "subgameAtRootResolved",
"offset": 0, "offset": 0,
"slot": "9", "slot": "6",
"type": "bool" "type": "bool"
} }
] ]
\ No newline at end of file
...@@ -6,60 +6,60 @@ ...@@ -6,60 +6,60 @@
"slot": "0", "slot": "0",
"type": "Timestamp" "type": "Timestamp"
}, },
{
"bytes": "8",
"label": "resolvedAt",
"offset": 8,
"slot": "0",
"type": "Timestamp"
},
{ {
"bytes": "1", "bytes": "1",
"label": "status", "label": "status",
"offset": 16, "offset": 8,
"slot": "0", "slot": "0",
"type": "enum GameStatus" "type": "enum GameStatus"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "bondManager", "label": "bondManager",
"offset": 0, "offset": 9,
"slot": "1", "slot": "0",
"type": "contract IBondManager" "type": "contract IBondManager"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "l1Head", "label": "l1Head",
"offset": 0, "offset": 0,
"slot": "2", "slot": "1",
"type": "Hash" "type": "Hash"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "claimData", "label": "claimData",
"offset": 0, "offset": 0,
"slot": "2",
"type": "struct ILegacyFaultDisputeGame.ClaimData[]"
},
{
"bytes": "128",
"label": "proposals",
"offset": 0,
"slot": "3", "slot": "3",
"type": "struct IOutputBisectionGame.ClaimData[]" "type": "struct ILegacyFaultDisputeGame.OutputProposals"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "claims", "label": "claims",
"offset": 0, "offset": 0,
"slot": "4", "slot": "7",
"type": "mapping(ClaimHash => bool)" "type": "mapping(ClaimHash => bool)"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "subgames", "label": "subgames",
"offset": 0, "offset": 0,
"slot": "5", "slot": "8",
"type": "mapping(uint256 => uint256[])" "type": "mapping(uint256 => uint256[])"
}, },
{ {
"bytes": "1", "bytes": "1",
"label": "subgameAtRootResolved", "label": "subgameAtRootResolved",
"offset": 0, "offset": 0,
"slot": "6", "slot": "9",
"type": "bool" "type": "bool"
} }
] ]
\ No newline at end of file
...@@ -6,8 +6,6 @@ import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol" ...@@ -6,8 +6,6 @@ import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"
import { IInitializable } from "src/dispute/interfaces/IInitializable.sol"; import { IInitializable } from "src/dispute/interfaces/IInitializable.sol";
import { IBondManager } from "src/dispute/interfaces/IBondManager.sol"; import { IBondManager } from "src/dispute/interfaces/IBondManager.sol";
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { BlockOracle } from "src/dispute/BlockOracle.sol";
import { Clone } from "src/libraries/Clone.sol"; import { Clone } from "src/libraries/Clone.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
...@@ -28,33 +26,39 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -28,33 +26,39 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
/// @notice The absolute prestate of the instruction trace. This is a constant that is defined /// @notice The absolute prestate of the instruction trace. This is a constant that is defined
/// by the program that is being used to execute the trace. /// by the program that is being used to execute the trace.
Claim public immutable ABSOLUTE_PRESTATE; Claim internal immutable ABSOLUTE_PRESTATE;
/// @notice The max depth of the game. /// @notice The max depth of the game.
uint256 public immutable MAX_GAME_DEPTH; uint256 internal immutable MAX_GAME_DEPTH;
/// @notice The max depth of the output bisection portion of the position tree. Immediately beneath
/// this depth, execution trace bisection begins.
uint256 internal immutable SPLIT_DEPTH;
/// @notice The duration of the game. /// @notice The duration of the game.
Duration public immutable GAME_DURATION; Duration internal immutable GAME_DURATION;
/// @notice An onchain VM that performs single instruction steps on a fault proof program trace. /// @notice An onchain VM that performs single instruction steps on a fault proof program trace.
IBigStepper public immutable VM; IBigStepper internal immutable VM;
/// @notice The trusted L2OutputOracle contract. /// @notice The genesis block number
L2OutputOracle public immutable L2_OUTPUT_ORACLE; uint256 internal immutable GENESIS_BLOCK_NUMBER;
/// @notice The block hash oracle, used for loading block hashes further back /// @notice The genesis output root
/// than the `BLOCKHASH` opcode allows as well as their child's timestamp. Hash internal immutable GENESIS_OUTPUT_ROOT;
BlockOracle public immutable BLOCK_ORACLE;
/// @notice The game type ID /// @notice The game type ID
GameType internal immutable GAME_TYPE; GameType internal immutable GAME_TYPE;
/// @notice The root claim's position is always at gindex 1. /// @notice The global root claim's position is always at gindex 1.
Position internal constant ROOT_POSITION = Position.wrap(1); Position internal constant ROOT_POSITION = Position.wrap(1);
/// @notice The starting timestamp of the game /// @notice The starting timestamp of the game
Timestamp public createdAt; Timestamp public createdAt;
/// @notice The timestamp of the game's global resolution.
Timestamp public resolvedAt;
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
GameStatus public status; GameStatus public status;
...@@ -67,11 +71,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -67,11 +71,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
/// @notice An append-only array of all claims made during the dispute game. /// @notice An append-only array of all claims made during the dispute game.
ClaimData[] public claimData; ClaimData[] public claimData;
/// @notice The starting and disputed output proposal for the game. Includes information about
/// the output indexes in the `L2OutputOracle` and the output roots at the time of
/// game creation.
OutputProposals public proposals;
/// @notice An internal mapping to allow for constant-time lookups of existing claims. /// @notice An internal mapping to allow for constant-time lookups of existing claims.
mapping(ClaimHash => bool) internal claims; mapping(ClaimHash => bool) internal claims;
...@@ -82,35 +81,39 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -82,35 +81,39 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
bool internal subgameAtRootResolved; bool internal subgameAtRootResolved;
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 0.0.13 /// @custom:semver 0.0.19
string public constant version = "0.0.13"; string public constant version = "0.0.19";
/// @param _gameType The type ID of the game. /// @param _gameType The type ID of the game.
/// @param _absolutePrestate The absolute prestate of the instruction trace. /// @param _absolutePrestate The absolute prestate of the instruction trace.
/// @param _genesisBlockNumber The block number of the genesis block.
/// @param _genesisOutputRoot The output root of the genesis block.
/// @param _maxGameDepth The maximum depth of bisection. /// @param _maxGameDepth The maximum depth of bisection.
/// @param _splitDepth The final depth of the output bisection portion of the game.
/// @param _gameDuration The duration of the game. /// @param _gameDuration The duration of the game.
/// @param _vm An onchain VM that performs single instruction steps on a fault proof program /// @param _vm An onchain VM that performs single instruction steps on a fault proof program
/// trace. /// trace.
/// @param _l2oo The trusted L2OutputOracle contract.
/// @param _blockOracle The block oracle, used for loading block hashes further back
/// than the `BLOCKHASH` opcode allows as well as their estimated
/// timestamps.
constructor( constructor(
GameType _gameType, GameType _gameType,
Claim _absolutePrestate, Claim _absolutePrestate,
uint256 _genesisBlockNumber,
Hash _genesisOutputRoot,
uint256 _maxGameDepth, uint256 _maxGameDepth,
uint256 _splitDepth,
Duration _gameDuration, Duration _gameDuration,
IBigStepper _vm, IBigStepper _vm
L2OutputOracle _l2oo,
BlockOracle _blockOracle
) { ) {
// The split depth cannot be greater than or equal to the max game depth.
if (_splitDepth >= _maxGameDepth) revert InvalidSplitDepth();
GAME_TYPE = _gameType; GAME_TYPE = _gameType;
ABSOLUTE_PRESTATE = _absolutePrestate; ABSOLUTE_PRESTATE = _absolutePrestate;
GENESIS_BLOCK_NUMBER = _genesisBlockNumber;
GENESIS_OUTPUT_ROOT = _genesisOutputRoot;
MAX_GAME_DEPTH = _maxGameDepth; MAX_GAME_DEPTH = _maxGameDepth;
SPLIT_DEPTH = _splitDepth;
GAME_DURATION = _gameDuration; GAME_DURATION = _gameDuration;
VM = _vm; VM = _vm;
L2_OUTPUT_ORACLE = _l2oo;
BLOCK_ORACLE = _blockOracle;
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
...@@ -141,26 +144,30 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -141,26 +144,30 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// prestate. // prestate.
// If the step is an attack at a trace index > 0, the prestate exists elsewhere in // If the step is an attack at a trace index > 0, the prestate exists elsewhere in
// the game state. // the game state.
preStateClaim = stepPos.indexAtDepth() == 0 // NOTE: We localize the `indexAtDepth` for the current execution trace subgame by finding
// the remainder of the index at depth divided by 2 ** (MAX_GAME_DEPTH - SPLIT_DEPTH),
// which is the number of leaves in each execution trace subgame. This is so that we can
// determine whether or not the step position is represents the `ABSOLUTE_PRESTATE`.
preStateClaim = (stepPos.indexAtDepth() % (1 << (MAX_GAME_DEPTH - SPLIT_DEPTH))) == 0
? ABSOLUTE_PRESTATE ? ABSOLUTE_PRESTATE
: findTraceAncestor(Position.wrap(Position.unwrap(parentPos) - 1), parent.parentIndex).claim; : findTraceAncestor(Position.wrap(Position.unwrap(parentPos) - 1), parent.parentIndex, false).claim;
// For all attacks, the poststate is the parent claim. // For all attacks, the poststate is the parent claim.
postState = parent; postState = parent;
} else { } else {
// If the step is a defense, the poststate exists elsewhere in the game state, // If the step is a defense, the poststate exists elsewhere in the game state,
// and the parent claim is the expected pre-state. // and the parent claim is the expected pre-state.
preStateClaim = parent.claim; preStateClaim = parent.claim;
postState = findTraceAncestor(Position.wrap(Position.unwrap(parentPos) + 1), parent.parentIndex); postState = findTraceAncestor(Position.wrap(Position.unwrap(parentPos) + 1), parent.parentIndex, false);
} }
// INVARIANT: The prestate is always invalid if the passed `_stateData` is not the // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the
// preimage of the prestate claim hash. // preimage of the prestate claim hash.
// We ignore the highest order byte of the digest because it is used to // We ignore the highest order byte of the digest because it is used to
// indicate the VM Status and is added after the digest is computed. // indicate the VM Status and is added after the digest is computed.
if (keccak256(_stateData) << 8 != Claim.unwrap(preStateClaim) << 8) { if (keccak256(_stateData) << 8 != Claim.unwrap(preStateClaim) << 8) revert InvalidPrestate();
revert InvalidPrestate();
} // Compute the local preimage context for the step.
Hash uuid = findLocalContext(_claimIndex);
// INVARIANT: If a step is an attack, the poststate is valid if the step produces // INVARIANT: If a step is an attack, the poststate is valid if the step produces
// the same poststate hash as the parent claim's value. // the same poststate hash as the parent claim's value.
...@@ -174,7 +181,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -174,7 +181,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// SAFETY: While the `attack` path does not need an extra check for the post // SAFETY: While the `attack` path does not need an extra check for the post
// state's depth in relation to the parent, we don't need another // state's depth in relation to the parent, we don't need another
// branch because (n - n) % 2 == 0. // branch because (n - n) % 2 == 0.
bool validStep = VM.step(_stateData, _proof, 0) == Claim.unwrap(postState.claim); bool validStep = VM.step(_stateData, _proof, Hash.unwrap(uuid)) == Claim.unwrap(postState.claim);
bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0; bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0;
if (parentPostAgree == validStep) revert ValidStep(); if (parentPostAgree == validStep) revert ValidStep();
...@@ -191,24 +198,34 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -191,24 +198,34 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// INVARIANT: Moves cannot be made unless the game is currently in progress. // INVARIANT: Moves cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
// INVARIANT: A defense can never be made against the root claim. This is because the root
// claim commits to the entire state. Therefore, the only valid defense is to
// do nothing if it is agreed with.
if (_challengeIndex == 0 && !_isAttack) revert CannotDefendRootClaim();
// Get the parent. If it does not exist, the call will revert with OOB. // Get the parent. If it does not exist, the call will revert with OOB.
ClaimData memory parent = claimData[_challengeIndex]; ClaimData memory parent = claimData[_challengeIndex];
// Compute the position that the claim commits to. Because the parent's position is already // Compute the position that the claim commits to. Because the parent's position is already
// known, we can compute the next position by moving left or right depending on whether // known, we can compute the next position by moving left or right depending on whether
// or not the move is an attack or defense. // or not the move is an attack or defense.
Position nextPosition = parent.position.move(_isAttack); Position parentPos = parent.position;
Position nextPosition = parentPos.move(_isAttack);
uint256 nextPositionDepth = nextPosition.depth();
// INVARIANT: A defense can never be made against the root claim of either the output root game or any
// of the execution trace bisection subgames. This is because the root claim commits to the
// entire state. Therefore, the only valid defense is to do nothing if it is agreed with.
if ((_challengeIndex == 0 || nextPositionDepth == SPLIT_DEPTH + 2) && !_isAttack) {
revert CannotDefendRootClaim();
}
// INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a // INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a
// claim at this depth is to perform a single instruction step on-chain via // claim at this depth is to perform a single instruction step on-chain via
// the `step` function to prove that the state transition produces an unexpected // the `step` function to prove that the state transition produces an unexpected
// post-state. // post-state.
if (nextPosition.depth() > MAX_GAME_DEPTH) revert GameDepthExceeded(); if (nextPositionDepth > MAX_GAME_DEPTH) revert GameDepthExceeded();
// When the next position surpasses the split depth (i.e., it is the root claim of an execution
// trace bisection sub-game), we need to perform some extra verification steps.
if (nextPositionDepth == SPLIT_DEPTH + 1) {
verifyExecBisectionRoot(_claim, _challengeIndex, parentPos, _isAttack);
}
// Fetch the grandparent clock, if it exists. // Fetch the grandparent clock, if it exists.
// The grandparent clock should always exist unless the parent is the root claim. // The grandparent clock should always exist unless the parent is the root claim.
...@@ -240,8 +257,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -240,8 +257,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp))); Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp)));
// INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple // INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple
// claims // claims at the same position may dispute the same challengeIndex. However, they must have different
// at the same position may dispute the same challengeIndex. However, the must have different values. // values.
ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex); ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex);
if (claims[claimHash]) revert ClaimAlreadyExists(); if (claims[claimHash]) revert ClaimAlreadyExists();
claims[claimHash] = true; claims[claimHash] = true;
...@@ -278,62 +295,40 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -278,62 +295,40 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
} }
/// @inheritdoc IFaultDisputeGame /// @inheritdoc IFaultDisputeGame
function addLocalData(uint256 _ident, bytes32 _localContext, uint256 _partOffset) external { function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external {
// INVARIANT: Local data can only be added if the game is currently in progress. // INVARIANT: Local data can only be added if the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
(Claim starting, Position startingPos, Claim disputed, Position disputedPos) =
findStartingAndDisputedOutputs(_execLeafIdx);
Hash uuid = computeLocalContext(starting, startingPos, disputed, disputedPos);
IPreimageOracle oracle = VM.oracle(); IPreimageOracle oracle = VM.oracle();
bytes4 loadLocalDataSelector = IPreimageOracle.loadLocalData.selector; if (_ident == LocalPreimageKey.L1_HEAD_HASH) {
assembly { // Load the L1 head hash
// Store the `loadLocalData(uint256,bytes32,uint256,uint256)` selector oracle.loadLocalData(_ident, Hash.unwrap(uuid), Hash.unwrap(l1Head), 32, _partOffset);
mstore(0x1C, loadLocalDataSelector) } else if (_ident == LocalPreimageKey.STARTING_OUTPUT_ROOT) {
// Store the `_ident` argument // Load the starting proposal's output root.
mstore(0x20, _ident) oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(starting), 32, _partOffset);
// Store the `_localContext` argument } else if (_ident == LocalPreimageKey.DISPUTED_OUTPUT_ROOT) {
mstore(0x40, _localContext) // Load the disputed proposal's output root
// Store the data to load oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(disputed), 32, _partOffset);
let data } else if (_ident == LocalPreimageKey.STARTING_L2_BLOCK_NUMBER) {
switch _ident // Load the starting proposal's L2 block number as a big-endian uint64 in the
case 1 { // high order 8 bytes of the word.
// Load the L1 head hash
data := sload(l1Head.slot) // If the starting position is 0 (invalid), the starting output root is genesis. Otherwise,
} // we add the index at depth + 1 to the genesis block number to get the L2 block number.
case 2 { uint256 l2Number = Position.unwrap(startingPos) == 0
// Load the starting proposal's output root. ? GENESIS_BLOCK_NUMBER
data := sload(add(proposals.slot, 0x01)) : GENESIS_BLOCK_NUMBER + startingPos.traceIndex(SPLIT_DEPTH) + 1;
}
case 3 { oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(l2Number << 0xC0), 8, _partOffset);
// Load the disputed proposal's output root } else if (_ident == LocalPreimageKey.CHAIN_ID) {
data := sload(add(proposals.slot, 0x03)) // Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word.
} oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(block.chainid << 0xC0), 8, _partOffset);
case 4 { } else {
// Load the starting proposal's L2 block number as a big-endian uint64 in the revert InvalidLocalIdent();
// high order 8 bytes of the word.
data := shl(0xC0, shr(0x80, sload(proposals.slot)))
}
case 5 {
// Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word.
data := shl(0xC0, chainid())
}
default {
// Store the `InvalidLocalIdent()` selector.
mstore(0x00, 0xff137e65)
// Revert with `InvalidLocalIdent()`
revert(0x1C, 0x04)
}
mstore(0x60, data)
// Store the size of the data to load
// _ident > 3 ? 8 : 32
mstore(0x80, shl(sub(0x05, shl(0x01, gt(_ident, 0x03))), 0x01))
// Store the part offset of the data
mstore(0xA0, _partOffset)
// Attempt to add the local data to the preimage oracle and bubble up the revert
// if it fails.
if iszero(call(gas(), oracle, 0x00, 0x1C, 0xA4, 0x00, 0x00)) {
returndatacopy(0x00, 0x00, returndatasize())
revert(0x00, returndatasize())
}
} }
} }
...@@ -342,11 +337,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -342,11 +337,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
l2BlockNumber_ = _getArgUint256(0x20); l2BlockNumber_ = _getArgUint256(0x20);
} }
/// @inheritdoc IFaultDisputeGame
function l1BlockNumber() public pure returns (uint256 l1BlockNumber_) {
l1BlockNumber_ = _getArgUint256(0x40);
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// `IDisputeGame` impl // // `IDisputeGame` impl //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
...@@ -364,7 +354,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -364,7 +354,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved. // INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved.
if (!subgameAtRootResolved) revert OutOfOrderResolution(); if (!subgameAtRootResolved) revert OutOfOrderResolution();
// Update the global game status; The dispute has concluded.
status_ = claimData[0].countered ? GameStatus.CHALLENGER_WINS : GameStatus.DEFENDER_WINS; status_ = claimData[0].countered ? GameStatus.CHALLENGER_WINS : GameStatus.DEFENDER_WINS;
resolvedAt = Timestamp.wrap(uint64(block.timestamp));
emit Resolved(status = status_); emit Resolved(status = status_);
} }
...@@ -415,7 +408,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -415,7 +408,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// Resolved subgames have no entries // Resolved subgames have no entries
delete subgames[_claimIndex]; delete subgames[_claimIndex];
// Indicate the game is ready to be resolved // Indicate the game is ready to be resolved globally.
if (_claimIndex == 0) { if (_claimIndex == 0) {
subgameAtRootResolved = true; subgameAtRootResolved = true;
} }
...@@ -429,8 +422,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -429,8 +422,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
function extraData() public pure returns (bytes memory extraData_) { function extraData() public pure returns (bytes memory extraData_) {
// The extra data starts at the second word within the cwia calldata and // The extra data starts at the second word within the cwia calldata and
// is 64 bytes long. // is 32 bytes long.
extraData_ = _getArgDynBytes(0x20, 0x40); extraData_ = _getArgDynBytes(0x20, 0x20);
} }
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
...@@ -451,18 +444,30 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -451,18 +444,30 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// //
// Implicit assumptions: // Implicit assumptions:
// - The `gameStatus` state variable defaults to 0, which is `GameStatus.IN_PROGRESS` // - The `gameStatus` state variable defaults to 0, which is `GameStatus.IN_PROGRESS`
//
// Explicit checks:
// - An output root cannot be proposed at or before the genesis block.
// The VMStatus must indicate (1) 'invalid', to argue that disputed thing is invalid. // Do not allow the game to be initialized if the root claim corresponds to a block at or before the
// Games that agree with the existing outcome are not allowed. // configured genesis block number.
// NOTE(clabby): This assumption will change in Alpha Chad. if (l2BlockNumber() <= GENESIS_BLOCK_NUMBER) revert UnexpectedRootClaim(rootClaim());
uint8 vmStatus = uint8(Claim.unwrap(rootClaim())[0]);
if (!(vmStatus == VMStatus.unwrap(VMStatuses.INVALID) || vmStatus == VMStatus.unwrap(VMStatuses.PANIC))) {
revert UnexpectedRootClaim(rootClaim());
}
// Set the game's starting timestamp // Set the game's starting timestamp
createdAt = Timestamp.wrap(uint64(block.timestamp)); createdAt = Timestamp.wrap(uint64(block.timestamp));
// Revert if the calldata size is too large, which signals that the `extraData` contains more than expected.
// This is to prevent adding extra bytes to the `extraData` that result in a different game UUID in the factory,
// but are not used by the game, which would allow for multiple dispute games for the same output proposal to
// be created.
// Expected length: 0x46 (0x04 selector + 0x20 root claim + 0x20 extraData + 0x02 CWIA bytes)
assembly {
if gt(calldatasize(), 0x46) {
// Store the selector for `ExtraDataTooLong()` & revert
mstore(0x00, 0xc407e025)
revert(0x1C, 0x04)
}
}
// Set the root claim // Set the root claim
claimData.push( claimData.push(
ClaimData({ ClaimData({
...@@ -474,58 +479,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -474,58 +479,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
}) })
); );
// Grab the index of the output proposal that commits to the starting L2 head. // Persist the blockhash of the parent block.
// All outputs after this one are disputed. l1Head = Hash.wrap(blockhash(block.number - 1));
// TODO(clabby): This is 2 calls too many for the information we need. Maybe
// add a function to the L2OO?
// TODO(clabby): The block hash bisection game will allow us to dispute the first output
// root by using genesis as the starting point. For now, it is critical that
// the first proposed output root of an OP stack chain is done so by an
// honest party.
uint256 proposalIdx = L2_OUTPUT_ORACLE.getL2OutputIndexAfter(l2BlockNumber());
Types.OutputProposal memory starting = L2_OUTPUT_ORACLE.getL2Output(proposalIdx - 1);
Types.OutputProposal memory disputed = L2_OUTPUT_ORACLE.getL2Output(proposalIdx);
// SAFETY: This call can revert if the block hash oracle does not have information
// about the block number provided to it.
BlockOracle.BlockInfo memory blockInfo = BLOCK_ORACLE.load(l1BlockNumber());
// INVARIANT: The L1 head must contain the disputed output root. If it does not,
// the game cannot be played.
// SAFETY: The block timestamp in the oracle records the timestamp of the
// block *after* the hash stored. This means that the timestamp
// is off by 1 block. This is known, and covered as follows:
// - The timestamp will always be less than the disputed timestamp
// if the checkpoint was made before the proposal. We must revert here.
// - The timestamp will be equal to the disputed timestamp if the
// checkpoint was made in the same block as the proposal, and the
// hash will be the parent block, which does not contain the proposal.
// We must revert here.
// - The timestamp will always be greater than the disputed timestamp
// if the checkpoint was made any block after the proposal. This is
// the only case where we can continue, since we must have the L1
// head contain the disputed output root to play the game.
if (Timestamp.unwrap(blockInfo.childTimestamp) <= disputed.timestamp) revert L1HeadTooOld();
// Persist the output proposals fetched from the oracle. These outputs will be referenced
// for loading local data into the preimage oracle as well as to authenticate the game's
// resolution. If the disputed output has changed in the oracle, the game cannot be
// resolved.
proposals = OutputProposals({
starting: OutputProposal({
index: uint128(proposalIdx - 1),
l2BlockNumber: starting.l2BlockNumber,
outputRoot: Hash.wrap(starting.outputRoot)
}),
disputed: OutputProposal({
index: uint128(proposalIdx),
l2BlockNumber: disputed.l2BlockNumber,
outputRoot: Hash.wrap(disputed.outputRoot)
})
});
// Persist the L1 head hash of the L1 block number provided.
l1Head = blockInfo.hash;
} }
/// @notice Returns the length of the `claimData` array. /// @notice Returns the length of the `claimData` array.
...@@ -533,25 +488,214 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ...@@ -533,25 +488,214 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
len_ = claimData.length; len_ = claimData.length;
} }
////////////////////////////////////////////////////////////////
// IMMUTABLE GETTERS //
////////////////////////////////////////////////////////////////
/// @notice Returns the absolute prestate of the instruction trace.
function absolutePrestate() external view returns (Claim absolutePrestate_) {
absolutePrestate_ = ABSOLUTE_PRESTATE;
}
/// @notice Returns the max game depth.
function maxGameDepth() external view returns (uint256 maxGameDepth_) {
maxGameDepth_ = MAX_GAME_DEPTH;
}
/// @notice Returns the split depth.
function splitDepth() external view returns (uint256 splitDepth_) {
splitDepth_ = SPLIT_DEPTH;
}
/// @notice Returns the game duration.
function gameDuration() external view returns (Duration gameDuration_) {
gameDuration_ = GAME_DURATION;
}
/// @notice Returns the address of the VM.
function vm() external view returns (IBigStepper vm_) {
vm_ = VM;
}
/// @notice Returns the genesis block number.
function genesisBlockNumber() external view returns (uint256 genesisBlockNumber_) {
genesisBlockNumber_ = GENESIS_BLOCK_NUMBER;
}
/// @notice Returns the genesis output root.
function genesisOutputRoot() external view returns (Hash genesisOutputRoot_) {
genesisOutputRoot_ = GENESIS_OUTPUT_ROOT;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// HELPERS // // HELPERS //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @notice Verifies the integrity of an execution bisection subgame's root claim. Reverts if the claim
/// is invalid.
/// @param _rootClaim The root claim of the execution bisection subgame.
function verifyExecBisectionRoot(
Claim _rootClaim,
uint256 _parentIdx,
Position _parentPos,
bool _isAttack
)
internal
view
{
// The root claim of an execution trace bisection sub-game must:
// 1. Signal that the VM panicked or resulted in an invalid transition if the disputed output root
// was made by the opposing party.
// 2. Signal that the VM resulted in a valid transition if the disputed output root was made by the same party.
// If the move is a defense, the disputed output could have been made by either party. In this case, we
// need to search for the parent output to determine what the expected status byte should be.
Position disputedLeafPos = Position.wrap(Position.unwrap(_parentPos) + 1);
ClaimData storage disputed = findTraceAncestor({ _pos: disputedLeafPos, _start: _parentIdx, _global: true });
uint8 vmStatus = uint8(Claim.unwrap(_rootClaim)[0]);
if (_isAttack || disputed.position.depth() % 2 == SPLIT_DEPTH % 2) {
// If the move is an attack, the parent output is always deemed to be disputed. In this case, we only need
// to check that the root claim signals that the VM panicked or resulted in an invalid transition.
// If the move is a defense, and the disputed output and creator of the execution trace subgame disagree,
// the root claim should also signal that the VM panicked or resulted in an invalid transition.
if (!(vmStatus == VMStatus.unwrap(VMStatuses.INVALID) || vmStatus == VMStatus.unwrap(VMStatuses.PANIC))) {
revert UnexpectedRootClaim(_rootClaim);
}
} else if (vmStatus != VMStatus.unwrap(VMStatuses.VALID)) {
// The disputed output and the creator of the execution trace subgame agree. The status byte should
// have signaled that the VM succeeded.
revert UnexpectedRootClaim(_rootClaim);
}
}
/// @notice Finds the trace ancestor of a given position within the DAG. /// @notice Finds the trace ancestor of a given position within the DAG.
/// @param _pos The position to find the trace ancestor claim of. /// @param _pos The position to find the trace ancestor claim of.
/// @param _start The index to start searching from. /// @param _start The index to start searching from.
/// @param _global Whether or not to search the entire dag or just within an execution trace subgame. If set to
/// `true`, and `_pos` is at or above the split depth, this function will revert.
/// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`. /// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`.
// TODO(clabby): Can we form a relationship between the trace path and the position to avoid function findTraceAncestor(
// looping? Position _pos,
function findTraceAncestor(Position _pos, uint256 _start) internal view returns (ClaimData storage ancestor_) { uint256 _start,
bool _global
)
internal
view
returns (ClaimData storage ancestor_)
{
// Grab the trace ancestor's expected position. // Grab the trace ancestor's expected position.
Position preStateTraceAncestor = _pos.traceAncestor(); Position traceAncestorPos = _global ? _pos.traceAncestor() : _pos.traceAncestorBounded(SPLIT_DEPTH);
// Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is // Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is
// guaranteed that such a claim exists. // guaranteed that such a claim exists.
ancestor_ = claimData[_start]; ancestor_ = claimData[_start];
while (Position.unwrap(ancestor_.position) != Position.unwrap(preStateTraceAncestor)) { while (Position.unwrap(ancestor_.position) != Position.unwrap(traceAncestorPos)) {
ancestor_ = claimData[ancestor_.parentIndex]; ancestor_ = claimData[ancestor_.parentIndex];
} }
} }
/// @notice Finds the starting and disputed output root for a given `ClaimData` within the DAG. This
/// `ClaimData` must be below the `SPLIT_DEPTH`.
/// @param _start The index within `claimData` of the claim to start searching from.
/// @return startingClaim_ The starting output root claim.
/// @return startingPos_ The starting output root position.
/// @return disputedClaim_ The disputed output root claim.
/// @return disputedPos_ The disputed output root position.
function findStartingAndDisputedOutputs(uint256 _start)
internal
view
returns (Claim startingClaim_, Position startingPos_, Claim disputedClaim_, Position disputedPos_)
{
// Fatch the starting claim.
uint256 claimIdx = _start;
ClaimData storage claim = claimData[claimIdx];
// If the starting claim's depth is less than or equal to the split depth, we revert as this is UB.
if (claim.position.depth() <= SPLIT_DEPTH) revert ClaimAboveSplit();
// We want to:
// 1. Find the first claim at the split depth.
// 2. Determine whether it was the starting or disputed output for the exec game.
// 3. Find the complimentary claim depending on the info from #2 (pre or post).
// Walk up the DAG until the ancestor's depth is equal to the split depth.
uint256 currentDepth;
ClaimData storage execRootClaim = claim;
while ((currentDepth = claim.position.depth()) > SPLIT_DEPTH) {
uint256 parentIndex = claim.parentIndex;
// If we're currently at the split depth + 1, we're at the root of the execution sub-game.
// We need to keep track of the root claim here to determine whether the execution sub-game was
// started with an attack or defense against the output leaf claim.
if (currentDepth == SPLIT_DEPTH + 1) execRootClaim = claim;
claim = claimData[parentIndex];
claimIdx = parentIndex;
}
// Determine whether the start of the execution sub-game was an attack or defense to the output root
// above. This is important because it determines which claim is the starting output root and which
// is the disputed output root.
(Position execRootPos, Position outputPos) = (execRootClaim.position, claim.position);
bool wasAttack = Position.unwrap(execRootPos.parent()) == Position.unwrap(outputPos);
// Determine the starting and disputed output root indices.
// 1. If it was an attack, the disputed output root is `claim`, and the starting output root is
// elsewhere in the DAG (it must commit to the block # index at depth of `outputPos - 1`).
// 2. If it was a defense, the starting output root is `claim`, and the disputed output root is
// elsewhere in the DAG (it must commit to the block # index at depth of `outputPos + 1`).
if (wasAttack) {
// If this is an attack on the first output root (the block directly after genesis), the
// starting claim nor position exists in the tree. We leave these as 0, which can be easily
// identified due to 0 being an invalid Gindex.
if (outputPos.indexAtDepth() > 0) {
ClaimData storage starting =
findTraceAncestor(Position.wrap(Position.unwrap(outputPos) - 1), claimIdx, true);
(startingClaim_, startingPos_) = (starting.claim, starting.position);
} else {
startingClaim_ = Claim.wrap(Hash.unwrap(GENESIS_OUTPUT_ROOT));
}
(disputedClaim_, disputedPos_) = (claim.claim, claim.position);
} else {
ClaimData storage disputed =
findTraceAncestor(Position.wrap(Position.unwrap(outputPos) + 1), claimIdx, true);
(startingClaim_, startingPos_) = (claim.claim, claim.position);
(disputedClaim_, disputedPos_) = (disputed.claim, disputed.position);
}
}
/// @notice Finds the local context hash for a given claim index that is present in an execution trace subgame.
/// @param _claimIndex The index of the claim to find the local context hash for.
/// @return uuid_ The local context hash.
function findLocalContext(uint256 _claimIndex) internal view returns (Hash uuid_) {
(Claim starting, Position startingPos, Claim disputed, Position disputedPos) =
findStartingAndDisputedOutputs(_claimIndex);
uuid_ = computeLocalContext(starting, startingPos, disputed, disputedPos);
}
/// @notice Computes the local context hash for a set of starting/disputed claim values and positions.
/// @param _starting The starting claim.
/// @param _startingPos The starting claim's position.
/// @param _disputed The disputed claim.
/// @param _disputedPos The disputed claim's position.
/// @return uuid_ The local context hash.
function computeLocalContext(
Claim _starting,
Position _startingPos,
Claim _disputed,
Position _disputedPos
)
internal
pure
returns (Hash uuid_)
{
// A position of 0 indicates that the starting claim is the absolute prestate. In this special case,
// we do not include the starting claim within the local context hash.
if (Position.unwrap(_startingPos) == 0) {
uuid_ = Hash.wrap(keccak256(abi.encode(_disputed, _disputedPos)));
} else {
uuid_ = Hash.wrap(keccak256(abi.encode(_starting, _startingPos, _disputed, _disputedPos)));
}
}
} }
...@@ -18,27 +18,6 @@ interface IFaultDisputeGame is IDisputeGame { ...@@ -18,27 +18,6 @@ interface IFaultDisputeGame is IDisputeGame {
Clock clock; Clock clock;
} }
/// @notice The `OutputProposal` struct contains information about an output proposal in
/// the `L2OutputOracle` at a given index.
struct OutputProposal {
uint128 index;
uint128 l2BlockNumber;
Hash outputRoot;
}
/// @notice A container for two consecutive `OutputProposal`s, used to store the starting
/// and disputed output proposals for a given dispute game. The starting output
/// proposal will be used to determine where the off chain agents should begin
/// running their fault proof program, and the disputed output proposal will be
/// fed into the program and treated as disputed state. The program's exit code
/// expresses its opinion on the validity of the state transition from the starting,
/// trusted output proposal to the disputed output proposal, and ultimately resolves
/// the dispute.
struct OutputProposals {
OutputProposal starting;
OutputProposal disputed;
}
/// @notice Emitted when a new claim is added to the DAG by `claimant` /// @notice Emitted when a new claim is added to the DAG by `claimant`
/// @param parentIndex The index within the `claimData` array of the parent claim /// @param parentIndex The index within the `claimData` array of the parent claim
/// @param claim The claim being added /// @param claim The claim being added
...@@ -70,9 +49,9 @@ interface IFaultDisputeGame is IDisputeGame { ...@@ -70,9 +49,9 @@ interface IFaultDisputeGame is IDisputeGame {
/// @notice Posts the requested local data to the VM's `PreimageOralce`. /// @notice Posts the requested local data to the VM's `PreimageOralce`.
/// @param _ident The local identifier of the data to post. /// @param _ident The local identifier of the data to post.
/// @param _localContext The local context for the `PreimageOracle` key. /// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step.
/// @param _partOffset The offset of the data to post. /// @param _partOffset The offset of the data to post.
function addLocalData(uint256 _ident, bytes32 _localContext, uint256 _partOffset) external; function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external;
/// @notice Resolves the subgame rooted at the given claim index. /// @notice Resolves the subgame rooted at the given claim index.
/// @dev This function must be called bottom-up in the DAG /// @dev This function must be called bottom-up in the DAG
...@@ -82,15 +61,9 @@ interface IFaultDisputeGame is IDisputeGame { ...@@ -82,15 +61,9 @@ interface IFaultDisputeGame is IDisputeGame {
/// @param _claimIndex The index of the subgame root claim to resolve. /// @param _claimIndex The index of the subgame root claim to resolve.
function resolveClaim(uint256 _claimIndex) external payable; function resolveClaim(uint256 _claimIndex) external payable;
/// @notice An L1 block hash that contains the disputed output root, fetched from the /// @notice A block hash on the L1 that contains the disputed output root.
/// `BlockOracle` and verified by referencing the timestamp associated with the
/// first L2 Output Proposal in the `L2OutputOracle` that contains the disputed
/// L2 block number.
function l1Head() external view returns (Hash l1Head_); function l1Head() external view returns (Hash l1Head_);
/// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`. /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`.
function l2BlockNumber() external view returns (uint256 l2BlockNumber_); function l2BlockNumber() external view returns (uint256 l2BlockNumber_);
/// @notice The l1BlockNumber that Cannon was ran from to generate the root claim.
function l1BlockNumber() external view returns (uint256 l1BlockNumber_);
} }
...@@ -2,10 +2,12 @@ ...@@ -2,10 +2,12 @@
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { IOutputBisectionGame } from "src/dispute/interfaces/IOutputBisectionGame.sol"; import { ILegacyFaultDisputeGame } from "src/legacy/interfaces/IFaultDisputeGame.sol";
import { IInitializable } from "src/dispute/interfaces/IInitializable.sol"; import { IInitializable } from "src/dispute/interfaces/IInitializable.sol";
import { IBondManager } from "src/dispute/interfaces/IBondManager.sol"; import { IBondManager } from "src/dispute/interfaces/IBondManager.sol";
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { BlockOracle } from "src/legacy/BlockOracle.sol";
import { Clone } from "src/libraries/Clone.sol"; import { Clone } from "src/libraries/Clone.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
...@@ -17,60 +19,61 @@ import { LibClock } from "src/dispute/lib/LibClock.sol"; ...@@ -17,60 +19,61 @@ import { LibClock } from "src/dispute/lib/LibClock.sol";
import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol"; import "src/libraries/DisputeErrors.sol";
/// @title OutputBisectionGame /// @title LegacyFaultDisputeGame
/// @notice An implementation of the `IOutputBisectionGame` interface. /// @notice An implementation of the `ILegacyFaultDisputeGame` interface.
contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { /// @dev This version of the fault dispute game was released in the fault proof alpha, and features no bonds nor output
/// bisection.
contract LegacyFaultDisputeGame is ILegacyFaultDisputeGame, Clone, ISemver {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// State Vars // // State Vars //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @notice The absolute prestate of the instruction trace. This is a constant that is defined /// @notice The absolute prestate of the instruction trace. This is a constant that is defined
/// by the program that is being used to execute the trace. /// by the program that is being used to execute the trace.
Claim internal immutable ABSOLUTE_PRESTATE; Claim public immutable ABSOLUTE_PRESTATE;
/// @notice The max depth of the game. /// @notice The max depth of the game.
uint256 internal immutable MAX_GAME_DEPTH; uint256 public immutable MAX_GAME_DEPTH;
/// @notice The max depth of the output bisection portion of the position tree. Immediately beneath
/// this depth, execution trace bisection begins.
uint256 internal immutable SPLIT_DEPTH;
/// @notice The duration of the game. /// @notice The duration of the game.
Duration internal immutable GAME_DURATION; Duration public immutable GAME_DURATION;
/// @notice An onchain VM that performs single instruction steps on a fault proof program trace. /// @notice An onchain VM that performs single instruction steps on a fault proof program trace.
IBigStepper internal immutable VM; IBigStepper public immutable VM;
/// @notice The genesis block number /// @notice The trusted L2OutputOracle contract.
uint256 internal immutable GENESIS_BLOCK_NUMBER; L2OutputOracle public immutable L2_OUTPUT_ORACLE;
/// @notice The genesis output root /// @notice The block hash oracle, used for loading block hashes further back
Hash internal immutable GENESIS_OUTPUT_ROOT; /// than the `BLOCKHASH` opcode allows as well as their child's timestamp.
BlockOracle public immutable BLOCK_ORACLE;
/// @notice The game type ID /// @notice The game type ID
GameType internal immutable GAME_TYPE; GameType internal immutable GAME_TYPE;
/// @notice The global root claim's position is always at gindex 1. /// @notice The root claim's position is always at gindex 1.
Position internal constant ROOT_POSITION = Position.wrap(1); Position internal constant ROOT_POSITION = Position.wrap(1);
/// @notice The starting timestamp of the game /// @notice The starting timestamp of the game
Timestamp public createdAt; Timestamp public createdAt;
/// @notice The timestamp of the game's global resolution.
Timestamp public resolvedAt;
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
GameStatus public status; GameStatus public status;
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
IBondManager public bondManager; IBondManager public bondManager;
/// @inheritdoc IOutputBisectionGame /// @inheritdoc ILegacyFaultDisputeGame
Hash public l1Head; Hash public l1Head;
/// @notice An append-only array of all claims made during the dispute game. /// @notice An append-only array of all claims made during the dispute game.
ClaimData[] public claimData; ClaimData[] public claimData;
/// @notice The starting and disputed output proposal for the game. Includes information about
/// the output indexes in the `L2OutputOracle` and the output roots at the time of
/// game creation.
OutputProposals public proposals;
/// @notice An internal mapping to allow for constant-time lookups of existing claims. /// @notice An internal mapping to allow for constant-time lookups of existing claims.
mapping(ClaimHash => bool) internal claims; mapping(ClaimHash => bool) internal claims;
...@@ -81,46 +84,42 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -81,46 +84,42 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
bool internal subgameAtRootResolved; bool internal subgameAtRootResolved;
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 0.0.18 /// @custom:semver 0.0.13
string public constant version = "0.0.18"; string public constant version = "0.0.13";
/// @param _gameType The type ID of the game. /// @param _gameType The type ID of the game.
/// @param _absolutePrestate The absolute prestate of the instruction trace. /// @param _absolutePrestate The absolute prestate of the instruction trace.
/// @param _genesisBlockNumber The block number of the genesis block.
/// @param _genesisOutputRoot The output root of the genesis block.
/// @param _maxGameDepth The maximum depth of bisection. /// @param _maxGameDepth The maximum depth of bisection.
/// @param _splitDepth The final depth of the output bisection portion of the game.
/// @param _gameDuration The duration of the game. /// @param _gameDuration The duration of the game.
/// @param _vm An onchain VM that performs single instruction steps on a fault proof program /// @param _vm An onchain VM that performs single instruction steps on a fault proof program
/// trace. /// trace.
/// @param _l2oo The trusted L2OutputOracle contract.
/// @param _blockOracle The block oracle, used for loading block hashes further back
/// than the `BLOCKHASH` opcode allows as well as their estimated
/// timestamps.
constructor( constructor(
GameType _gameType, GameType _gameType,
Claim _absolutePrestate, Claim _absolutePrestate,
uint256 _genesisBlockNumber,
Hash _genesisOutputRoot,
uint256 _maxGameDepth, uint256 _maxGameDepth,
uint256 _splitDepth,
Duration _gameDuration, Duration _gameDuration,
IBigStepper _vm IBigStepper _vm,
L2OutputOracle _l2oo,
BlockOracle _blockOracle
) { ) {
// The split depth cannot be greater than or equal to the max game depth.
if (_splitDepth >= _maxGameDepth) revert InvalidSplitDepth();
GAME_TYPE = _gameType; GAME_TYPE = _gameType;
ABSOLUTE_PRESTATE = _absolutePrestate; ABSOLUTE_PRESTATE = _absolutePrestate;
GENESIS_BLOCK_NUMBER = _genesisBlockNumber;
GENESIS_OUTPUT_ROOT = _genesisOutputRoot;
MAX_GAME_DEPTH = _maxGameDepth; MAX_GAME_DEPTH = _maxGameDepth;
SPLIT_DEPTH = _splitDepth;
GAME_DURATION = _gameDuration; GAME_DURATION = _gameDuration;
VM = _vm; VM = _vm;
L2_OUTPUT_ORACLE = _l2oo;
BLOCK_ORACLE = _blockOracle;
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// `IOutputBisectionGame` impl // // `ILegacyFaultDisputeGame` impl //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @inheritdoc IOutputBisectionGame /// @inheritdoc ILegacyFaultDisputeGame
function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external { function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external {
// INVARIANT: Steps cannot be made unless the game is currently in progress. // INVARIANT: Steps cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
...@@ -144,30 +143,26 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -144,30 +143,26 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// prestate. // prestate.
// If the step is an attack at a trace index > 0, the prestate exists elsewhere in // If the step is an attack at a trace index > 0, the prestate exists elsewhere in
// the game state. // the game state.
// NOTE: We localize the `indexAtDepth` for the current execution trace subgame by finding preStateClaim = stepPos.indexAtDepth() == 0
// the remainder of the index at depth divided by 2 ** (MAX_GAME_DEPTH - SPLIT_DEPTH),
// which is the number of leaves in each execution trace subgame. This is so that we can
// determine whether or not the step position is represents the `ABSOLUTE_PRESTATE`.
preStateClaim = (stepPos.indexAtDepth() % (1 << (MAX_GAME_DEPTH - SPLIT_DEPTH))) == 0
? ABSOLUTE_PRESTATE ? ABSOLUTE_PRESTATE
: findTraceAncestor(Position.wrap(Position.unwrap(parentPos) - 1), parent.parentIndex, false).claim; : findTraceAncestor(Position.wrap(Position.unwrap(parentPos) - 1), parent.parentIndex).claim;
// For all attacks, the poststate is the parent claim. // For all attacks, the poststate is the parent claim.
postState = parent; postState = parent;
} else { } else {
// If the step is a defense, the poststate exists elsewhere in the game state, // If the step is a defense, the poststate exists elsewhere in the game state,
// and the parent claim is the expected pre-state. // and the parent claim is the expected pre-state.
preStateClaim = parent.claim; preStateClaim = parent.claim;
postState = findTraceAncestor(Position.wrap(Position.unwrap(parentPos) + 1), parent.parentIndex, false); postState = findTraceAncestor(Position.wrap(Position.unwrap(parentPos) + 1), parent.parentIndex);
} }
// INVARIANT: The prestate is always invalid if the passed `_stateData` is not the // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the
// preimage of the prestate claim hash. // preimage of the prestate claim hash.
// We ignore the highest order byte of the digest because it is used to // We ignore the highest order byte of the digest because it is used to
// indicate the VM Status and is added after the digest is computed. // indicate the VM Status and is added after the digest is computed.
if (keccak256(_stateData) << 8 != Claim.unwrap(preStateClaim) << 8) revert InvalidPrestate(); if (keccak256(_stateData) << 8 != Claim.unwrap(preStateClaim) << 8) {
revert InvalidPrestate();
// Compute the local preimage context for the step. }
Hash uuid = findLocalContext(_claimIndex);
// INVARIANT: If a step is an attack, the poststate is valid if the step produces // INVARIANT: If a step is an attack, the poststate is valid if the step produces
// the same poststate hash as the parent claim's value. // the same poststate hash as the parent claim's value.
...@@ -181,7 +176,7 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -181,7 +176,7 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// SAFETY: While the `attack` path does not need an extra check for the post // SAFETY: While the `attack` path does not need an extra check for the post
// state's depth in relation to the parent, we don't need another // state's depth in relation to the parent, we don't need another
// branch because (n - n) % 2 == 0. // branch because (n - n) % 2 == 0.
bool validStep = VM.step(_stateData, _proof, Hash.unwrap(uuid)) == Claim.unwrap(postState.claim); bool validStep = VM.step(_stateData, _proof, 0) == Claim.unwrap(postState.claim);
bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0; bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0;
if (parentPostAgree == validStep) revert ValidStep(); if (parentPostAgree == validStep) revert ValidStep();
...@@ -198,34 +193,24 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -198,34 +193,24 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// INVARIANT: Moves cannot be made unless the game is currently in progress. // INVARIANT: Moves cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
// INVARIANT: A defense can never be made against the root claim. This is because the root
// claim commits to the entire state. Therefore, the only valid defense is to
// do nothing if it is agreed with.
if (_challengeIndex == 0 && !_isAttack) revert CannotDefendRootClaim();
// Get the parent. If it does not exist, the call will revert with OOB. // Get the parent. If it does not exist, the call will revert with OOB.
ClaimData memory parent = claimData[_challengeIndex]; ClaimData memory parent = claimData[_challengeIndex];
// Compute the position that the claim commits to. Because the parent's position is already // Compute the position that the claim commits to. Because the parent's position is already
// known, we can compute the next position by moving left or right depending on whether // known, we can compute the next position by moving left or right depending on whether
// or not the move is an attack or defense. // or not the move is an attack or defense.
Position parentPos = parent.position; Position nextPosition = parent.position.move(_isAttack);
Position nextPosition = parentPos.move(_isAttack);
uint256 nextPositionDepth = nextPosition.depth();
// INVARIANT: A defense can never be made against the root claim of either the output root game or any
// of the execution trace bisection subgames. This is because the root claim commits to the
// entire state. Therefore, the only valid defense is to do nothing if it is agreed with.
if ((_challengeIndex == 0 || nextPositionDepth == SPLIT_DEPTH + 2) && !_isAttack) {
revert CannotDefendRootClaim();
}
// INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a // INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a
// claim at this depth is to perform a single instruction step on-chain via // claim at this depth is to perform a single instruction step on-chain via
// the `step` function to prove that the state transition produces an unexpected // the `step` function to prove that the state transition produces an unexpected
// post-state. // post-state.
if (nextPositionDepth > MAX_GAME_DEPTH) revert GameDepthExceeded(); if (nextPosition.depth() > MAX_GAME_DEPTH) revert GameDepthExceeded();
// When the next position surpasses the split depth (i.e., it is the root claim of an execution
// trace bisection sub-game), we need to perform some extra verification steps.
if (nextPositionDepth == SPLIT_DEPTH + 1) {
verifyExecBisectionRoot(_claim, _challengeIndex, parentPos, _isAttack);
}
// Fetch the grandparent clock, if it exists. // Fetch the grandparent clock, if it exists.
// The grandparent clock should always exist unless the parent is the root claim. // The grandparent clock should always exist unless the parent is the root claim.
...@@ -257,7 +242,8 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -257,7 +242,8 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp))); Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp)));
// INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple // INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple
// claims at the same position may dispute the same challengeIndex. However, they must have different values. // claims
// at the same position may dispute the same challengeIndex. However, the must have different values.
ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex); ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex);
if (claims[claimHash]) revert ClaimAlreadyExists(); if (claims[claimHash]) revert ClaimAlreadyExists();
claims[claimHash] = true; claims[claimHash] = true;
...@@ -283,59 +269,86 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -283,59 +269,86 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
emit Move(_challengeIndex, _claim, msg.sender); emit Move(_challengeIndex, _claim, msg.sender);
} }
/// @inheritdoc IOutputBisectionGame /// @inheritdoc ILegacyFaultDisputeGame
function attack(uint256 _parentIndex, Claim _claim) external payable { function attack(uint256 _parentIndex, Claim _claim) external payable {
move(_parentIndex, _claim, true); move(_parentIndex, _claim, true);
} }
/// @inheritdoc IOutputBisectionGame /// @inheritdoc ILegacyFaultDisputeGame
function defend(uint256 _parentIndex, Claim _claim) external payable { function defend(uint256 _parentIndex, Claim _claim) external payable {
move(_parentIndex, _claim, false); move(_parentIndex, _claim, false);
} }
/// @inheritdoc IOutputBisectionGame /// @inheritdoc ILegacyFaultDisputeGame
function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external { function addLocalData(uint256 _ident, bytes32 _localContext, uint256 _partOffset) external {
// INVARIANT: Local data can only be added if the game is currently in progress. // INVARIANT: Local data can only be added if the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
(Claim starting, Position startingPos, Claim disputed, Position disputedPos) =
findStartingAndDisputedOutputs(_execLeafIdx);
Hash uuid = computeLocalContext(starting, startingPos, disputed, disputedPos);
IPreimageOracle oracle = VM.oracle(); IPreimageOracle oracle = VM.oracle();
if (_ident == LocalPreimageKey.L1_HEAD_HASH) { bytes4 loadLocalDataSelector = IPreimageOracle.loadLocalData.selector;
// Load the L1 head hash assembly {
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Hash.unwrap(l1Head), 32, _partOffset); // Store the `loadLocalData(uint256,bytes32,uint256,uint256)` selector
} else if (_ident == LocalPreimageKey.STARTING_OUTPUT_ROOT) { mstore(0x1C, loadLocalDataSelector)
// Load the starting proposal's output root. // Store the `_ident` argument
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(starting), 32, _partOffset); mstore(0x20, _ident)
} else if (_ident == LocalPreimageKey.DISPUTED_OUTPUT_ROOT) { // Store the `_localContext` argument
// Load the disputed proposal's output root mstore(0x40, _localContext)
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(disputed), 32, _partOffset); // Store the data to load
} else if (_ident == LocalPreimageKey.STARTING_L2_BLOCK_NUMBER) { let data
// Load the starting proposal's L2 block number as a big-endian uint64 in the switch _ident
// high order 8 bytes of the word. case 1 {
// Load the L1 head hash
// If the starting position is 0 (invalid), the starting output root is genesis. Otherwise, data := sload(l1Head.slot)
// we add the index at depth + 1 to the genesis block number to get the L2 block number. }
uint256 l2Number = Position.unwrap(startingPos) == 0 case 2 {
? GENESIS_BLOCK_NUMBER // Load the starting proposal's output root.
: GENESIS_BLOCK_NUMBER + startingPos.traceIndex(SPLIT_DEPTH) + 1; data := sload(add(proposals.slot, 0x01))
}
oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(l2Number << 0xC0), 8, _partOffset); case 3 {
} else if (_ident == LocalPreimageKey.CHAIN_ID) { // Load the disputed proposal's output root
// Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word. data := sload(add(proposals.slot, 0x03))
oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(block.chainid << 0xC0), 8, _partOffset); }
} else { case 4 {
revert InvalidLocalIdent(); // Load the starting proposal's L2 block number as a big-endian uint64 in the
// high order 8 bytes of the word.
data := shl(0xC0, shr(0x80, sload(proposals.slot)))
}
case 5 {
// Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word.
data := shl(0xC0, chainid())
}
default {
// Store the `InvalidLocalIdent()` selector.
mstore(0x00, 0xff137e65)
// Revert with `InvalidLocalIdent()`
revert(0x1C, 0x04)
}
mstore(0x60, data)
// Store the size of the data to load
// _ident > 3 ? 8 : 32
mstore(0x80, shl(sub(0x05, shl(0x01, gt(_ident, 0x03))), 0x01))
// Store the part offset of the data
mstore(0xA0, _partOffset)
// Attempt to add the local data to the preimage oracle and bubble up the revert
// if it fails.
if iszero(call(gas(), oracle, 0x00, 0x1C, 0xA4, 0x00, 0x00)) {
returndatacopy(0x00, 0x00, returndatasize())
revert(0x00, returndatasize())
}
} }
} }
/// @inheritdoc IOutputBisectionGame /// @inheritdoc ILegacyFaultDisputeGame
function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) { function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
l2BlockNumber_ = _getArgUint256(0x20); l2BlockNumber_ = _getArgUint256(0x20);
} }
/// @inheritdoc ILegacyFaultDisputeGame
function l1BlockNumber() public pure returns (uint256 l1BlockNumber_) {
l1BlockNumber_ = _getArgUint256(0x40);
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// `IDisputeGame` impl // // `IDisputeGame` impl //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
...@@ -353,14 +366,11 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -353,14 +366,11 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved. // INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved.
if (!subgameAtRootResolved) revert OutOfOrderResolution(); if (!subgameAtRootResolved) revert OutOfOrderResolution();
// Update the global game status; The dispute has concluded.
status_ = claimData[0].countered ? GameStatus.CHALLENGER_WINS : GameStatus.DEFENDER_WINS; status_ = claimData[0].countered ? GameStatus.CHALLENGER_WINS : GameStatus.DEFENDER_WINS;
resolvedAt = Timestamp.wrap(uint64(block.timestamp));
emit Resolved(status = status_); emit Resolved(status = status_);
} }
/// @inheritdoc IOutputBisectionGame /// @inheritdoc ILegacyFaultDisputeGame
function resolveClaim(uint256 _claimIndex) external payable { function resolveClaim(uint256 _claimIndex) external payable {
// INVARIANT: Resolution cannot occur unless the game is currently in progress. // INVARIANT: Resolution cannot occur unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
...@@ -407,7 +417,7 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -407,7 +417,7 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// Resolved subgames have no entries // Resolved subgames have no entries
delete subgames[_claimIndex]; delete subgames[_claimIndex];
// Indicate the game is ready to be resolved globally. // Indicate the game is ready to be resolved
if (_claimIndex == 0) { if (_claimIndex == 0) {
subgameAtRootResolved = true; subgameAtRootResolved = true;
} }
...@@ -421,8 +431,8 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -421,8 +431,8 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
function extraData() public pure returns (bytes memory extraData_) { function extraData() public pure returns (bytes memory extraData_) {
// The extra data starts at the second word within the cwia calldata and // The extra data starts at the second word within the cwia calldata and
// is 32 bytes long. // is 64 bytes long.
extraData_ = _getArgDynBytes(0x20, 0x20); extraData_ = _getArgDynBytes(0x20, 0x40);
} }
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
...@@ -443,30 +453,18 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -443,30 +453,18 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// //
// Implicit assumptions: // Implicit assumptions:
// - The `gameStatus` state variable defaults to 0, which is `GameStatus.IN_PROGRESS` // - The `gameStatus` state variable defaults to 0, which is `GameStatus.IN_PROGRESS`
//
// Explicit checks:
// - An output root cannot be proposed at or before the genesis block.
// Do not allow the game to be initialized if the root claim corresponds to a block at or before the // The VMStatus must indicate (1) 'invalid', to argue that disputed thing is invalid.
// configured genesis block number. // Games that agree with the existing outcome are not allowed.
if (l2BlockNumber() <= GENESIS_BLOCK_NUMBER) revert UnexpectedRootClaim(rootClaim()); // NOTE(clabby): This assumption will change in Alpha Chad.
uint8 vmStatus = uint8(Claim.unwrap(rootClaim())[0]);
if (!(vmStatus == VMStatus.unwrap(VMStatuses.INVALID) || vmStatus == VMStatus.unwrap(VMStatuses.PANIC))) {
revert UnexpectedRootClaim(rootClaim());
}
// Set the game's starting timestamp // Set the game's starting timestamp
createdAt = Timestamp.wrap(uint64(block.timestamp)); createdAt = Timestamp.wrap(uint64(block.timestamp));
// Revert if the calldata size is too large, which signals that the `extraData` contains more than expected.
// This is to prevent adding extra bytes to the `extraData` that result in a different game UUID in the factory,
// but are not used by the game, which would allow for multiple dispute games for the same output proposal to
// be created.
// Expected length: 0x46 (0x04 selector + 0x20 root claim + 0x20 extraData + 0x02 CWIA bytes)
assembly {
if gt(calldatasize(), 0x46) {
// Store the selector for `ExtraDataTooLong()` & revert
mstore(0x00, 0xc407e025)
revert(0x1C, 0x04)
}
}
// Set the root claim // Set the root claim
claimData.push( claimData.push(
ClaimData({ ClaimData({
...@@ -478,8 +476,58 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -478,8 +476,58 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
}) })
); );
// Persist the blockhash of the parent block. // Grab the index of the output proposal that commits to the starting L2 head.
l1Head = Hash.wrap(blockhash(block.number - 1)); // All outputs after this one are disputed.
// TODO(clabby): This is 2 calls too many for the information we need. Maybe
// add a function to the L2OO?
// TODO(clabby): The block hash bisection game will allow us to dispute the first output
// root by using genesis as the starting point. For now, it is critical that
// the first proposed output root of an OP stack chain is done so by an
// honest party.
uint256 proposalIdx = L2_OUTPUT_ORACLE.getL2OutputIndexAfter(l2BlockNumber());
Types.OutputProposal memory starting = L2_OUTPUT_ORACLE.getL2Output(proposalIdx - 1);
Types.OutputProposal memory disputed = L2_OUTPUT_ORACLE.getL2Output(proposalIdx);
// SAFETY: This call can revert if the block hash oracle does not have information
// about the block number provided to it.
BlockOracle.BlockInfo memory blockInfo = BLOCK_ORACLE.load(l1BlockNumber());
// INVARIANT: The L1 head must contain the disputed output root. If it does not,
// the game cannot be played.
// SAFETY: The block timestamp in the oracle records the timestamp of the
// block *after* the hash stored. This means that the timestamp
// is off by 1 block. This is known, and covered as follows:
// - The timestamp will always be less than the disputed timestamp
// if the checkpoint was made before the proposal. We must revert here.
// - The timestamp will be equal to the disputed timestamp if the
// checkpoint was made in the same block as the proposal, and the
// hash will be the parent block, which does not contain the proposal.
// We must revert here.
// - The timestamp will always be greater than the disputed timestamp
// if the checkpoint was made any block after the proposal. This is
// the only case where we can continue, since we must have the L1
// head contain the disputed output root to play the game.
if (Timestamp.unwrap(blockInfo.childTimestamp) <= disputed.timestamp) revert L1HeadTooOld();
// Persist the output proposals fetched from the oracle. These outputs will be referenced
// for loading local data into the preimage oracle as well as to authenticate the game's
// resolution. If the disputed output has changed in the oracle, the game cannot be
// resolved.
proposals = OutputProposals({
starting: OutputProposal({
index: uint128(proposalIdx - 1),
l2BlockNumber: starting.l2BlockNumber,
outputRoot: Hash.wrap(starting.outputRoot)
}),
disputed: OutputProposal({
index: uint128(proposalIdx),
l2BlockNumber: disputed.l2BlockNumber,
outputRoot: Hash.wrap(disputed.outputRoot)
})
});
// Persist the L1 head hash of the L1 block number provided.
l1Head = blockInfo.hash;
} }
/// @notice Returns the length of the `claimData` array. /// @notice Returns the length of the `claimData` array.
...@@ -487,214 +535,25 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -487,214 +535,25 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
len_ = claimData.length; len_ = claimData.length;
} }
////////////////////////////////////////////////////////////////
// IMMUTABLE GETTERS //
////////////////////////////////////////////////////////////////
/// @notice Returns the absolute prestate of the instruction trace.
function absolutePrestate() external view returns (Claim absolutePrestate_) {
absolutePrestate_ = ABSOLUTE_PRESTATE;
}
/// @notice Returns the max game depth.
function maxGameDepth() external view returns (uint256 maxGameDepth_) {
maxGameDepth_ = MAX_GAME_DEPTH;
}
/// @notice Returns the split depth.
function splitDepth() external view returns (uint256 splitDepth_) {
splitDepth_ = SPLIT_DEPTH;
}
/// @notice Returns the game duration.
function gameDuration() external view returns (Duration gameDuration_) {
gameDuration_ = GAME_DURATION;
}
/// @notice Returns the address of the VM.
function vm() external view returns (IBigStepper vm_) {
vm_ = VM;
}
/// @notice Returns the genesis block number.
function genesisBlockNumber() external view returns (uint256 genesisBlockNumber_) {
genesisBlockNumber_ = GENESIS_BLOCK_NUMBER;
}
/// @notice Returns the genesis output root.
function genesisOutputRoot() external view returns (Hash genesisOutputRoot_) {
genesisOutputRoot_ = GENESIS_OUTPUT_ROOT;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// HELPERS // // HELPERS //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @notice Verifies the integrity of an execution bisection subgame's root claim. Reverts if the claim
/// is invalid.
/// @param _rootClaim The root claim of the execution bisection subgame.
function verifyExecBisectionRoot(
Claim _rootClaim,
uint256 _parentIdx,
Position _parentPos,
bool _isAttack
)
internal
view
{
// The root claim of an execution trace bisection sub-game must:
// 1. Signal that the VM panicked or resulted in an invalid transition if the disputed output root
// was made by the opposing party.
// 2. Signal that the VM resulted in a valid transition if the disputed output root was made by the same party.
// If the move is a defense, the disputed output could have been made by either party. In this case, we
// need to search for the parent output to determine what the expected status byte should be.
Position disputedLeafPos = Position.wrap(Position.unwrap(_parentPos) + 1);
ClaimData storage disputed = findTraceAncestor({ _pos: disputedLeafPos, _start: _parentIdx, _global: true });
uint8 vmStatus = uint8(Claim.unwrap(_rootClaim)[0]);
if (_isAttack || disputed.position.depth() % 2 == SPLIT_DEPTH % 2) {
// If the move is an attack, the parent output is always deemed to be disputed. In this case, we only need
// to check that the root claim signals that the VM panicked or resulted in an invalid transition.
// If the move is a defense, and the disputed output and creator of the execution trace subgame disagree,
// the root claim should also signal that the VM panicked or resulted in an invalid transition.
if (!(vmStatus == VMStatus.unwrap(VMStatuses.INVALID) || vmStatus == VMStatus.unwrap(VMStatuses.PANIC))) {
revert UnexpectedRootClaim(_rootClaim);
}
} else if (vmStatus != VMStatus.unwrap(VMStatuses.VALID)) {
// The disputed output and the creator of the execution trace subgame agree. The status byte should
// have signaled that the VM succeeded.
revert UnexpectedRootClaim(_rootClaim);
}
}
/// @notice Finds the trace ancestor of a given position within the DAG. /// @notice Finds the trace ancestor of a given position within the DAG.
/// @param _pos The position to find the trace ancestor claim of. /// @param _pos The position to find the trace ancestor claim of.
/// @param _start The index to start searching from. /// @param _start The index to start searching from.
/// @param _global Whether or not to search the entire dag or just within an execution trace subgame. If set to
/// `true`, and `_pos` is at or above the split depth, this function will revert.
/// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`. /// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`.
function findTraceAncestor( // TODO(clabby): Can we form a relationship between the trace path and the position to avoid
Position _pos, // looping?
uint256 _start, function findTraceAncestor(Position _pos, uint256 _start) internal view returns (ClaimData storage ancestor_) {
bool _global
)
internal
view
returns (ClaimData storage ancestor_)
{
// Grab the trace ancestor's expected position. // Grab the trace ancestor's expected position.
Position traceAncestorPos = _global ? _pos.traceAncestor() : _pos.traceAncestorBounded(SPLIT_DEPTH); Position preStateTraceAncestor = _pos.traceAncestor();
// Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is // Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is
// guaranteed that such a claim exists. // guaranteed that such a claim exists.
ancestor_ = claimData[_start]; ancestor_ = claimData[_start];
while (Position.unwrap(ancestor_.position) != Position.unwrap(traceAncestorPos)) { while (Position.unwrap(ancestor_.position) != Position.unwrap(preStateTraceAncestor)) {
ancestor_ = claimData[ancestor_.parentIndex]; ancestor_ = claimData[ancestor_.parentIndex];
} }
} }
/// @notice Finds the starting and disputed output root for a given `ClaimData` within the DAG. This
/// `ClaimData` must be below the `SPLIT_DEPTH`.
/// @param _start The index within `claimData` of the claim to start searching from.
/// @return startingClaim_ The starting output root claim.
/// @return startingPos_ The starting output root position.
/// @return disputedClaim_ The disputed output root claim.
/// @return disputedPos_ The disputed output root position.
function findStartingAndDisputedOutputs(uint256 _start)
internal
view
returns (Claim startingClaim_, Position startingPos_, Claim disputedClaim_, Position disputedPos_)
{
// Fatch the starting claim.
uint256 claimIdx = _start;
ClaimData storage claim = claimData[claimIdx];
// If the starting claim's depth is less than or equal to the split depth, we revert as this is UB.
if (claim.position.depth() <= SPLIT_DEPTH) revert ClaimAboveSplit();
// We want to:
// 1. Find the first claim at the split depth.
// 2. Determine whether it was the starting or disputed output for the exec game.
// 3. Find the complimentary claim depending on the info from #2 (pre or post).
// Walk up the DAG until the ancestor's depth is equal to the split depth.
uint256 currentDepth;
ClaimData storage execRootClaim = claim;
while ((currentDepth = claim.position.depth()) > SPLIT_DEPTH) {
uint256 parentIndex = claim.parentIndex;
// If we're currently at the split depth + 1, we're at the root of the execution sub-game.
// We need to keep track of the root claim here to determine whether the execution sub-game was
// started with an attack or defense against the output leaf claim.
if (currentDepth == SPLIT_DEPTH + 1) execRootClaim = claim;
claim = claimData[parentIndex];
claimIdx = parentIndex;
}
// Determine whether the start of the execution sub-game was an attack or defense to the output root
// above. This is important because it determines which claim is the starting output root and which
// is the disputed output root.
(Position execRootPos, Position outputPos) = (execRootClaim.position, claim.position);
bool wasAttack = Position.unwrap(execRootPos.parent()) == Position.unwrap(outputPos);
// Determine the starting and disputed output root indices.
// 1. If it was an attack, the disputed output root is `claim`, and the starting output root is
// elsewhere in the DAG (it must commit to the block # index at depth of `outputPos - 1`).
// 2. If it was a defense, the starting output root is `claim`, and the disputed output root is
// elsewhere in the DAG (it must commit to the block # index at depth of `outputPos + 1`).
if (wasAttack) {
// If this is an attack on the first output root (the block directly after genesis), the
// starting claim nor position exists in the tree. We leave these as 0, which can be easily
// identified due to 0 being an invalid Gindex.
if (outputPos.indexAtDepth() > 0) {
ClaimData storage starting =
findTraceAncestor(Position.wrap(Position.unwrap(outputPos) - 1), claimIdx, true);
(startingClaim_, startingPos_) = (starting.claim, starting.position);
} else {
startingClaim_ = Claim.wrap(Hash.unwrap(GENESIS_OUTPUT_ROOT));
}
(disputedClaim_, disputedPos_) = (claim.claim, claim.position);
} else {
ClaimData storage disputed =
findTraceAncestor(Position.wrap(Position.unwrap(outputPos) + 1), claimIdx, true);
(startingClaim_, startingPos_) = (claim.claim, claim.position);
(disputedClaim_, disputedPos_) = (disputed.claim, disputed.position);
}
}
/// @notice Finds the local context hash for a given claim index that is present in an execution trace subgame.
/// @param _claimIndex The index of the claim to find the local context hash for.
/// @return uuid_ The local context hash.
function findLocalContext(uint256 _claimIndex) internal view returns (Hash uuid_) {
(Claim starting, Position startingPos, Claim disputed, Position disputedPos) =
findStartingAndDisputedOutputs(_claimIndex);
uuid_ = computeLocalContext(starting, startingPos, disputed, disputedPos);
}
/// @notice Computes the local context hash for a set of starting/disputed claim values and positions.
/// @param _starting The starting claim.
/// @param _startingPos The starting claim's position.
/// @param _disputed The disputed claim.
/// @param _disputedPos The disputed claim's position.
/// @return uuid_ The local context hash.
function computeLocalContext(
Claim _starting,
Position _startingPos,
Claim _disputed,
Position _disputedPos
)
internal
pure
returns (Hash uuid_)
{
// A position of 0 indicates that the starting claim is the absolute prestate. In this special case,
// we do not include the starting claim within the local context hash.
if (Position.unwrap(_startingPos) == 0) {
uuid_ = Hash.wrap(keccak256(abi.encode(_disputed, _disputedPos)));
} else {
uuid_ = Hash.wrap(keccak256(abi.encode(_starting, _startingPos, _disputed, _disputedPos)));
}
}
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { IDisputeGame } from "./IDisputeGame.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeTypes.sol";
/// @title IOutputBisectionGame /// @title ILegacyFaultDisputeGame
/// @notice The interface for a fault proof backed dispute game. /// @notice The interface for a fault proof backed dispute game.
interface IOutputBisectionGame is IDisputeGame { interface ILegacyFaultDisputeGame is IDisputeGame {
/// @notice The `ClaimData` struct represents the data associated with a Claim. /// @notice The `ClaimData` struct represents the data associated with a Claim.
/// @dev TODO(clabby): Add bond ID information. /// @dev TODO(clabby): Add bond ID information.
struct ClaimData { struct ClaimData {
...@@ -18,6 +18,27 @@ interface IOutputBisectionGame is IDisputeGame { ...@@ -18,6 +18,27 @@ interface IOutputBisectionGame is IDisputeGame {
Clock clock; Clock clock;
} }
/// @notice The `OutputProposal` struct contains information about an output proposal in
/// the `L2OutputOracle` at a given index.
struct OutputProposal {
uint128 index;
uint128 l2BlockNumber;
Hash outputRoot;
}
/// @notice A container for two consecutive `OutputProposal`s, used to store the starting
/// and disputed output proposals for a given dispute game. The starting output
/// proposal will be used to determine where the off chain agents should begin
/// running their fault proof program, and the disputed output proposal will be
/// fed into the program and treated as disputed state. The program's exit code
/// expresses its opinion on the validity of the state transition from the starting,
/// trusted output proposal to the disputed output proposal, and ultimately resolves
/// the dispute.
struct OutputProposals {
OutputProposal starting;
OutputProposal disputed;
}
/// @notice Emitted when a new claim is added to the DAG by `claimant` /// @notice Emitted when a new claim is added to the DAG by `claimant`
/// @param parentIndex The index within the `claimData` array of the parent claim /// @param parentIndex The index within the `claimData` array of the parent claim
/// @param claim The claim being added /// @param claim The claim being added
...@@ -49,9 +70,9 @@ interface IOutputBisectionGame is IDisputeGame { ...@@ -49,9 +70,9 @@ interface IOutputBisectionGame is IDisputeGame {
/// @notice Posts the requested local data to the VM's `PreimageOralce`. /// @notice Posts the requested local data to the VM's `PreimageOralce`.
/// @param _ident The local identifier of the data to post. /// @param _ident The local identifier of the data to post.
/// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step. /// @param _localContext The local context for the `PreimageOracle` key.
/// @param _partOffset The offset of the data to post. /// @param _partOffset The offset of the data to post.
function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external; function addLocalData(uint256 _ident, bytes32 _localContext, uint256 _partOffset) external;
/// @notice Resolves the subgame rooted at the given claim index. /// @notice Resolves the subgame rooted at the given claim index.
/// @dev This function must be called bottom-up in the DAG /// @dev This function must be called bottom-up in the DAG
...@@ -61,9 +82,15 @@ interface IOutputBisectionGame is IDisputeGame { ...@@ -61,9 +82,15 @@ interface IOutputBisectionGame is IDisputeGame {
/// @param _claimIndex The index of the subgame root claim to resolve. /// @param _claimIndex The index of the subgame root claim to resolve.
function resolveClaim(uint256 _claimIndex) external payable; function resolveClaim(uint256 _claimIndex) external payable;
/// @notice A block hash on the L1 that contains the disputed output root. /// @notice An L1 block hash that contains the disputed output root, fetched from the
/// `BlockOracle` and verified by referencing the timestamp associated with the
/// first L2 Output Proposal in the `L2OutputOracle` that contains the disputed
/// L2 block number.
function l1Head() external view returns (Hash l1Head_); function l1Head() external view returns (Hash l1Head_);
/// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`. /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`.
function l2BlockNumber() external view returns (uint256 l2BlockNumber_); function l2BlockNumber() external view returns (uint256 l2BlockNumber_);
/// @notice The l1BlockNumber that Cannon was ran from to generate the root claim.
function l1BlockNumber() external view returns (uint256 l1BlockNumber_);
} }
...@@ -84,26 +84,7 @@ error ClaimAboveSplit(); ...@@ -84,26 +84,7 @@ error ClaimAboveSplit();
error InvalidSplitDepth(); error InvalidSplitDepth();
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// `AttestationDisputeGame` Errors // // `BlockOracle` Errors (Legacy) //
////////////////////////////////////////////////////////////////
/// @notice Thrown when an invalid signature is submitted to `challenge`.
error InvalidSignature();
/// @notice Thrown when a signature that has already been used to support the
/// `rootClaim` is submitted to `challenge`.
error AlreadyChallenged();
////////////////////////////////////////////////////////////////
// `Ownable` Errors //
////////////////////////////////////////////////////////////////
/// @notice Thrown when a function that is protected by the `onlyOwner` modifier
/// is called from an account other than the owner.
error NotOwner();
////////////////////////////////////////////////////////////////
// `BlockOracle` Errors //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @notice Thrown when a block that is out of the range of the `BLOCKHASH` opcode /// @notice Thrown when a block that is out of the range of the `BLOCKHASH` opcode
......
...@@ -82,13 +82,6 @@ library GameTypes { ...@@ -82,13 +82,6 @@ library GameTypes {
/// @dev A dispute game type the uses the cannon vm. /// @dev A dispute game type the uses the cannon vm.
GameType internal constant CANNON = GameType.wrap(0); GameType internal constant CANNON = GameType.wrap(0);
/// @dev A dispute game type that performs output bisection and then uses the cannon vm.
GameType internal constant OUTPUT_CANNON = GameType.wrap(1);
/// @notice A dispute game type that performs output bisection and then uses an alphabet vm.
/// Not intended for production use.
GameType internal constant OUTPUT_ALPHABET = GameType.wrap(254);
/// @notice A dispute game type that uses an alphabet vm. /// @notice A dispute game type that uses an alphabet vm.
/// Not intended for production use. /// Not intended for production use.
GameType internal constant ALPHABET = GameType.wrap(255); GameType internal constant ALPHABET = GameType.wrap(255);
......
...@@ -3,19 +3,19 @@ pragma solidity ^0.8.15; ...@@ -3,19 +3,19 @@ pragma solidity ^0.8.15;
import { CommonBase } from "forge-std/Base.sol"; import { CommonBase } from "forge-std/Base.sol";
import { OutputBisectionGame } from "src/dispute/OutputBisectionGame.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol";
import { IOutputBisectionGame } from "src/dispute/interfaces/IOutputBisectionGame.sol"; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol";
import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeTypes.sol";
/// @title GameSolver /// @title GameSolver
/// @notice The `GameSolver` contract is a contract that can produce an array of available /// @notice The `GameSolver` contract is a contract that can produce an array of available
/// moves for a given `OutputBisectionGame` contract, from the eyes of an honest /// moves for a given `FaultDisputeGame` contract, from the eyes of an honest
/// actor. The `GameSolver` does not implement functionality for acting on the `Move`s /// actor. The `GameSolver` does not implement functionality for acting on the `Move`s
/// it suggests. /// it suggests.
abstract contract GameSolver is CommonBase { abstract contract GameSolver is CommonBase {
/// @notice The `OutputBisectionGame` proxy that the `GameSolver` will be solving. /// @notice The `FaultDisputeGame` proxy that the `GameSolver` will be solving.
OutputBisectionGame public immutable GAME; FaultDisputeGame public immutable GAME;
/// @notice The split depth of the game /// @notice The split depth of the game
uint256 internal immutable SPLIT_DEPTH; uint256 internal immutable SPLIT_DEPTH;
/// @notice The max depth of the game /// @notice The max depth of the game
...@@ -37,7 +37,7 @@ abstract contract GameSolver is CommonBase { ...@@ -37,7 +37,7 @@ abstract contract GameSolver is CommonBase {
/// `GAME` contract. /// `GAME` contract.
bool public agreeWithRoot; bool public agreeWithRoot;
/// @notice The `MoveKind` enum represents a kind of interaction with the `OutputBisectionGame` contract. /// @notice The `MoveKind` enum represents a kind of interaction with the `FaultDisputeGame` contract.
enum MoveKind { enum MoveKind {
Attack, Attack,
Defend, Defend,
...@@ -47,14 +47,14 @@ abstract contract GameSolver is CommonBase { ...@@ -47,14 +47,14 @@ abstract contract GameSolver is CommonBase {
/// @notice The `Move` struct represents a move in the game, and contains information /// @notice The `Move` struct represents a move in the game, and contains information
/// about the kind of move, the sender of the move, and the calldata to be sent /// about the kind of move, the sender of the move, and the calldata to be sent
/// to the `OutputBisectionGame` contract by a consumer of this contract. /// to the `FaultDisputeGame` contract by a consumer of this contract.
struct Move { struct Move {
MoveKind kind; MoveKind kind;
bytes data; bytes data;
} }
constructor( constructor(
OutputBisectionGame _gameProxy, FaultDisputeGame _gameProxy,
uint256[] memory _l2Outputs, uint256[] memory _l2Outputs,
bytes memory _trace, bytes memory _trace,
bytes memory _preStateData bytes memory _preStateData
...@@ -70,13 +70,13 @@ abstract contract GameSolver is CommonBase { ...@@ -70,13 +70,13 @@ abstract contract GameSolver is CommonBase {
} }
/// @notice Returns an array of `Move`s that can be taken from the perspective of an honest /// @notice Returns an array of `Move`s that can be taken from the perspective of an honest
/// actor in the `OutputBisectionGame` contract. /// actor in the `FaultDisputeGame` contract.
function solveGame() external virtual returns (Move[] memory moves_); function solveGame() external virtual returns (Move[] memory moves_);
} }
/// @title HonestGameSolver /// @title HonestGameSolver
/// @notice The `HonestGameSolver` is an implementation of `GameSolver` which responds accordingly depending /// @notice The `HonestGameSolver` is an implementation of `GameSolver` which responds accordingly depending
/// on the state of the `OutputBisectionGame` contract in relation to their local opinion of the correct /// on the state of the `FaultDisputeGame` contract in relation to their local opinion of the correct
/// order of output roots and the execution trace between each block `n` -> `n + 1` state transition. /// order of output roots and the execution trace between each block `n` -> `n + 1` state transition.
contract HonestGameSolver is GameSolver { contract HonestGameSolver is GameSolver {
/// @notice The `Direction` enum represents the direction of a proposed move in the game, /// @notice The `Direction` enum represents the direction of a proposed move in the game,
...@@ -88,7 +88,7 @@ contract HonestGameSolver is GameSolver { ...@@ -88,7 +88,7 @@ contract HonestGameSolver is GameSolver {
} }
constructor( constructor(
OutputBisectionGame _gameProxy, FaultDisputeGame _gameProxy,
uint256[] memory _l2Outputs, uint256[] memory _l2Outputs,
bytes memory _trace, bytes memory _trace,
bytes memory _preStateData bytes memory _preStateData
...@@ -105,7 +105,7 @@ contract HonestGameSolver is GameSolver { ...@@ -105,7 +105,7 @@ contract HonestGameSolver is GameSolver {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @notice Returns an array of `Move`s that can be taken from the perspective of an honest /// @notice Returns an array of `Move`s that can be taken from the perspective of an honest
/// actor in the `OutputBisectionGame` contract. /// actor in the `FaultDisputeGame` contract.
function solveGame() external override returns (Move[] memory moves_) { function solveGame() external override returns (Move[] memory moves_) {
uint256 numClaims = GAME.claimDataLen(); uint256 numClaims = GAME.claimDataLen();
...@@ -116,7 +116,7 @@ contract HonestGameSolver is GameSolver { ...@@ -116,7 +116,7 @@ contract HonestGameSolver is GameSolver {
uint256 numMoves = 0; uint256 numMoves = 0;
for (uint256 i = processedBuf; i < numClaims; i++) { for (uint256 i = processedBuf; i < numClaims; i++) {
// Grab the observed claim. // Grab the observed claim.
IOutputBisectionGame.ClaimData memory observed = getClaimData(i); IFaultDisputeGame.ClaimData memory observed = getClaimData(i);
// Determine the direction of the next move to be taken. // Determine the direction of the next move to be taken.
(Direction moveDirection, Position movePos) = determineDirection(observed); (Direction moveDirection, Position movePos) = determineDirection(observed);
...@@ -149,7 +149,7 @@ contract HonestGameSolver is GameSolver { ...@@ -149,7 +149,7 @@ contract HonestGameSolver is GameSolver {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @dev Helper function to determine the direction of the next move to be taken. /// @dev Helper function to determine the direction of the next move to be taken.
function determineDirection(IOutputBisectionGame.ClaimData memory _claimData) function determineDirection(IFaultDisputeGame.ClaimData memory _claimData)
internal internal
view view
returns (Direction direction_, Position movePos_) returns (Direction direction_, Position movePos_)
...@@ -217,7 +217,7 @@ contract HonestGameSolver is GameSolver { ...@@ -217,7 +217,7 @@ contract HonestGameSolver is GameSolver {
bool isAttack = _direction == Direction.Attack; bool isAttack = _direction == Direction.Attack;
move_ = Move({ move_ = Move({
kind: isAttack ? MoveKind.Attack : MoveKind.Defend, kind: isAttack ? MoveKind.Attack : MoveKind.Defend,
data: abi.encodeCall(OutputBisectionGame.move, (_challengeIndex, claimAt(_movePos), isAttack)) data: abi.encodeCall(FaultDisputeGame.move, (_challengeIndex, claimAt(_movePos), isAttack))
}); });
} }
...@@ -256,7 +256,7 @@ contract HonestGameSolver is GameSolver { ...@@ -256,7 +256,7 @@ contract HonestGameSolver is GameSolver {
move_ = Move({ move_ = Move({
kind: MoveKind.Step, kind: MoveKind.Step,
data: abi.encodeCall(OutputBisectionGame.step, (_challengeIndex, isAttack, preStateTrace, hex"")) data: abi.encodeCall(FaultDisputeGame.step, (_challengeIndex, isAttack, preStateTrace, hex""))
}); });
} }
...@@ -266,14 +266,10 @@ contract HonestGameSolver is GameSolver { ...@@ -266,14 +266,10 @@ contract HonestGameSolver is GameSolver {
/// @dev Helper function to get the `ClaimData` struct at a given index in the `GAME` contract's /// @dev Helper function to get the `ClaimData` struct at a given index in the `GAME` contract's
/// `claimData` array. /// `claimData` array.
function getClaimData(uint256 _claimIndex) function getClaimData(uint256 _claimIndex) internal view returns (IFaultDisputeGame.ClaimData memory claimData_) {
internal
view
returns (IOutputBisectionGame.ClaimData memory claimData_)
{
// thanks, solc // thanks, solc
(uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = GAME.claimData(_claimIndex); (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = GAME.claimData(_claimIndex);
claimData_ = IOutputBisectionGame.ClaimData({ claimData_ = IFaultDisputeGame.ClaimData({
parentIndex: parentIndex, parentIndex: parentIndex,
countered: countered, countered: countered,
claim: claim, claim: claim,
...@@ -353,10 +349,10 @@ abstract contract DisputeActor { ...@@ -353,10 +349,10 @@ abstract contract DisputeActor {
/// that this actor *can* be dishonest if the trace is faulty, but it will always follow /// that this actor *can* be dishonest if the trace is faulty, but it will always follow
/// the rules of the honest actor. /// the rules of the honest actor.
contract HonestDisputeActor is DisputeActor { contract HonestDisputeActor is DisputeActor {
OutputBisectionGame public immutable GAME; FaultDisputeGame public immutable GAME;
constructor( constructor(
OutputBisectionGame _gameProxy, FaultDisputeGame _gameProxy,
uint256[] memory _l2Outputs, uint256[] memory _l2Outputs,
bytes memory _trace, bytes memory _trace,
bytes memory _preStateData bytes memory _preStateData
...@@ -378,7 +374,7 @@ contract HonestDisputeActor is DisputeActor { ...@@ -378,7 +374,7 @@ contract HonestDisputeActor is DisputeActor {
GameSolver.Move memory localMove = moves[i]; GameSolver.Move memory localMove = moves[i];
// If the move is a step, we first need to add the starting L2 block number to the `PreimageOracle` // If the move is a step, we first need to add the starting L2 block number to the `PreimageOracle`
// via the `OutputBisectionGame` contract. // via the `FaultDisputeGame` contract.
// TODO: This is leaky. Could be another move kind. // TODO: This is leaky. Could be another move kind.
if (localMove.kind == GameSolver.MoveKind.Step) { if (localMove.kind == GameSolver.MoveKind.Step) {
bytes memory moveData = localMove.data; bytes memory moveData = localMove.data;
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { BlockOracle } from "src/dispute/BlockOracle.sol";
import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol";
contract BlockOracle_Test is Test {
BlockOracle oracle;
/// @notice Emitted when a block is checkpointed.
event Checkpoint(uint256 indexed blockNumber, Hash indexed blockHash, Timestamp indexed childTimestamp);
function setUp() public {
oracle = new BlockOracle();
// Roll the chain forward 1 block.
vm.roll(block.number + 1);
vm.warp(block.timestamp + 13);
}
/// @notice Tests that checkpointing a block and loading its information succeeds.
function test_checkpointAndLoad_succeeds() public {
vm.expectEmit(true, true, true, false);
emit Checkpoint(
block.number - 1, Hash.wrap(blockhash(block.number - 1)), Timestamp.wrap(uint64(block.timestamp))
);
oracle.checkpoint();
uint256 blockNumber = block.number - 1;
BlockOracle.BlockInfo memory res = oracle.load(blockNumber);
assertEq(Hash.unwrap(res.hash), blockhash(blockNumber));
assertEq(Timestamp.unwrap(res.childTimestamp), block.timestamp);
}
/// @notice Tests that the `load` function reverts if the block hash for the given block
/// number has not been stored.
function test_load_noBlockHash_reverts() public {
vm.expectRevert(BlockHashNotPresent.selector);
oracle.load(0);
}
}
...@@ -7,7 +7,6 @@ import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; ...@@ -7,7 +7,6 @@ import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { BlockOracle } from "src/dispute/BlockOracle.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol";
...@@ -19,6 +18,8 @@ import { LibPosition } from "src/dispute/lib/LibPosition.sol"; ...@@ -19,6 +18,8 @@ import { LibPosition } from "src/dispute/lib/LibPosition.sol";
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; import { AlphabetVM } from "test/mocks/AlphabetVM.sol";
import { DisputeActor, HonestDisputeActor } from "test/actors/FaultDisputeActors.sol";
contract FaultDisputeGame_Init is DisputeGameFactory_Init { contract FaultDisputeGame_Init is DisputeGameFactory_Init {
/// @dev The type of the game being tested. /// @dev The type of the game being tested.
GameType internal constant GAME_TYPE = GameType.wrap(0); GameType internal constant GAME_TYPE = GameType.wrap(0);
...@@ -27,48 +28,55 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { ...@@ -27,48 +28,55 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
FaultDisputeGame internal gameImpl; FaultDisputeGame internal gameImpl;
/// @dev The `Clone` proxy of the game. /// @dev The `Clone` proxy of the game.
FaultDisputeGame internal gameProxy; FaultDisputeGame internal gameProxy;
/// @dev The extra data passed to the game for initialization. /// @dev The extra data passed to the game for initialization.
bytes internal extraData; bytes internal extraData;
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant); event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
function init(Claim rootClaim, Claim absolutePrestate) public { function init(
Claim rootClaim,
Claim absolutePrestate,
uint256 l2BlockNumber,
uint256 genesisBlockNumber,
Hash genesisOutputRoot
)
public
{
// Set the time to a realistic date. // Set the time to a realistic date.
vm.warp(1690906994); vm.warp(1690906994);
// Propose 2 mock outputs
vm.startPrank(l2OutputOracle.PROPOSER());
for (uint256 i; i < 2; i++) {
l2OutputOracle.proposeL2Output(bytes32(i + 1), l2OutputOracle.nextBlockNumber(), blockhash(i), i);
// Advance 1 block
vm.roll(block.number + 1);
vm.warp(block.timestamp + 13);
}
vm.stopPrank();
// Deploy a new block hash oracle and store the block hash for the genesis block.
BlockOracle blockOracle = new BlockOracle();
blockOracle.checkpoint();
// Set the extra data for the game creation // Set the extra data for the game creation
extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, block.number - 1); extraData = abi.encode(l2BlockNumber);
AlphabetVM _vm = new AlphabetVM(absolutePrestate);
// Deploy an implementation of the fault game // Deploy an implementation of the fault game
gameImpl = new FaultDisputeGame( gameImpl = new FaultDisputeGame({
GAME_TYPE, _gameType: GAME_TYPE,
absolutePrestate, _absolutePrestate: absolutePrestate,
4, _genesisBlockNumber: genesisBlockNumber,
Duration.wrap(7 days), _genesisOutputRoot: genesisOutputRoot,
new AlphabetVM(absolutePrestate), _maxGameDepth: 2 ** 3,
l2OutputOracle, _splitDepth: 2 ** 2,
blockOracle _gameDuration: Duration.wrap(7 days),
); _vm: _vm
});
// Register the game implementation with the factory. // Register the game implementation with the factory.
factory.setImplementation(GAME_TYPE, gameImpl); factory.setImplementation(GAME_TYPE, gameImpl);
// Create a new game. // Create a new game.
gameProxy = FaultDisputeGame(address(factory.create(GAME_TYPE, rootClaim, extraData))); gameProxy = FaultDisputeGame(address(factory.create(GAME_TYPE, rootClaim, extraData)));
// Check immutables
assertEq(GameType.unwrap(gameProxy.gameType()), GameType.unwrap(GAME_TYPE));
assertEq(Claim.unwrap(gameProxy.absolutePrestate()), Claim.unwrap(absolutePrestate));
assertEq(gameProxy.genesisBlockNumber(), genesisBlockNumber);
assertEq(Hash.unwrap(gameProxy.genesisOutputRoot()), Hash.unwrap(genesisOutputRoot));
assertEq(gameProxy.maxGameDepth(), 2 ** 3);
assertEq(gameProxy.splitDepth(), 2 ** 2);
assertEq(Duration.unwrap(gameProxy.gameDuration()), 7 days);
assertEq(address(gameProxy.vm()), address(_vm));
// Label the proxy // Label the proxy
vm.label(address(gameProxy), "FaultDisputeGame_Clone"); vm.label(address(gameProxy), "FaultDisputeGame_Clone");
} }
...@@ -82,13 +90,40 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -82,13 +90,40 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
super.init(ROOT_CLAIM, ABSOLUTE_PRESTATE); super.init({
rootClaim: ROOT_CLAIM,
absolutePrestate: ABSOLUTE_PRESTATE,
l2BlockNumber: 0x10,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// `IDisputeGame` Implementation Tests // // `IDisputeGame` Implementation Tests //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @dev Tests that the constructor of the `FaultDisputeGame` reverts when the `_splitDepth`
/// parameter is greater than or equal to the `MAX_GAME_DEPTH`
function test_constructor_wrongArgs_reverts(uint256 _splitDepth) public {
AlphabetVM alphabetVM = new AlphabetVM(ABSOLUTE_PRESTATE);
// Test that the constructor reverts when the `_splitDepth` parameter is greater than or equal
// to the `MAX_GAME_DEPTH` parameter.
_splitDepth = bound(_splitDepth, 2 ** 3, type(uint256).max);
vm.expectRevert(InvalidSplitDepth.selector);
new FaultDisputeGame({
_gameType: GAME_TYPE,
_absolutePrestate: ABSOLUTE_PRESTATE,
_genesisBlockNumber: 0,
_genesisOutputRoot: Hash.wrap(bytes32(0)),
_maxGameDepth: 2 ** 3,
_splitDepth: _splitDepth,
_gameDuration: Duration.wrap(7 days),
_vm: alphabetVM
});
}
/// @dev Tests that the game's root claim is set correctly. /// @dev Tests that the game's root claim is set correctly.
function test_rootClaim_succeeds() public { function test_rootClaim_succeeds() public {
assertEq(Claim.unwrap(gameProxy.rootClaim()), Claim.unwrap(ROOT_CLAIM)); assertEq(Claim.unwrap(gameProxy.rootClaim()), Claim.unwrap(ROOT_CLAIM));
...@@ -119,63 +154,45 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -119,63 +154,45 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// `IFaultDisputeGame` Implementation Tests // // `IFaultDisputeGame` Implementation Tests //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @dev Tests that a game cannot be created by the factory if the L1 head hash does not /// @dev Tests that the game cannot be initialized with an output root that commits to <= the configured genesis
/// contain the disputed L2 output root. /// block number
function test_initialize_l1HeadTooOld_reverts() public { function testFuzz_initialize_cannotProposeGenesis_reverts(uint256 _blockNumber) public {
// Store a mock block hash for the genesis block. The timestamp will default to 0. _blockNumber = bound(_blockNumber, 0, gameProxy.genesisBlockNumber());
vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1)));
bytes memory _extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, 0); Claim claim = _dummyClaim();
vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, claim));
vm.expectRevert(L1HeadTooOld.selector); gameProxy = FaultDisputeGame(address(factory.create(GAME_TYPE, claim, abi.encode(_blockNumber))));
factory.create(GAME_TYPE, ROOT_CLAIM, _extraData); }
}
/// @dev Tests that the game cannot be initialized with extra data > 64 bytes long (root claim + l2 block number
/// @dev Tests that a game cannot be created that disputes the first output root proposed. /// concatenated)
/// TODO(clabby): This will be solved by the block hash bisection game, where we'll be able function testFuzz_initialize_extraDataTooLong_reverts(uint256 _extraDataLen) public {
/// to dispute the first output root by using genesis as the starting point. // The `DisputeGameFactory` will pack the root claim and the extra data into a single array, which is enforced
/// For now, it is critical that the first proposed output root of an OP stack // to be at least 64 bytes long.
/// chain is done so by an honest party. // We bound the upper end to 23.5KB to ensure that the minimal proxy never surpasses the contract size limit
function test_initialize_firstOutput_reverts() public { // in this test, as CWIA proxies store the immutable args in their bytecode.
uint256 submissionInterval = l2OutputOracle.SUBMISSION_INTERVAL(); // [33 bytes, 23.5 KB]
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11)); _extraDataLen = bound(_extraDataLen, 33, 23_500);
factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(submissionInterval, block.number - 1)); bytes memory _extraData = new bytes(_extraDataLen);
}
// Assign the first 32 bytes in `extraData` to a valid L2 block number passed genesis.
/// @dev Tests that the `create` function reverts when the rootClaim does not disagree with the outcome. uint256 genesisBlockNumber = gameProxy.genesisBlockNumber();
function testFuzz_initialize_badRootStatus_reverts(Claim rootClaim, bytes calldata extraData) public { assembly {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. mstore(add(_extraData, 0x20), add(genesisBlockNumber, 1))
// Ensure the root claim does not have the correct VM status }
uint8 vmStatus = uint8(Claim.unwrap(rootClaim)[0]);
if (vmStatus == 1 || vmStatus == 2) rootClaim = changeClaimStatus(rootClaim, VMStatuses.VALID);
vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, rootClaim)); Claim claim = _dummyClaim();
factory.create(GameTypes.CANNON, rootClaim, extraData); vm.expectRevert(abi.encodeWithSelector(ExtraDataTooLong.selector));
gameProxy = FaultDisputeGame(address(factory.create(GAME_TYPE, claim, _extraData)));
} }
/// @dev Tests that the game is initialized with the correct data. /// @dev Tests that the game is initialized with the correct data.
function test_initialize_correctData_succeeds() public { function test_initialize_correctData_succeeds() public {
// Starting // Assert that the root claim is initialized correctly.
(FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) =
gameProxy.proposals();
Types.OutputProposal memory starting = l2OutputOracle.getL2Output(startingProp.index);
assertEq(startingProp.index, 0);
assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber);
assertEq(Hash.unwrap(startingProp.outputRoot), starting.outputRoot);
// Disputed
Types.OutputProposal memory disputed = l2OutputOracle.getL2Output(disputedProp.index);
assertEq(disputedProp.index, 1);
assertEq(disputedProp.l2BlockNumber, disputed.l2BlockNumber);
assertEq(Hash.unwrap(disputedProp.outputRoot), disputed.outputRoot);
// L1 head
(, uint256 l1HeadNumber) = abi.decode(gameProxy.extraData(), (uint256, uint256));
assertEq(blockhash(l1HeadNumber), Hash.unwrap(gameProxy.l1Head()));
(uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(0); (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(0);
assertEq(parentIndex, type(uint32).max); assertEq(parentIndex, type(uint32).max);
assertEq(countered, false); assertEq(countered, false);
assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM)); assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM));
...@@ -183,6 +200,12 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -183,6 +200,12 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp)))) Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
); );
// Assert that the `createdAt` timestamp is correct.
assertEq(Timestamp.unwrap(gameProxy.createdAt()), block.timestamp);
// Assert that the blockhash provided is correct.
assertEq(Hash.unwrap(gameProxy.l1Head()), blockhash(block.number - 1));
} }
/// @dev Tests that a move while the game status is not `IN_PROGRESS` causes the call to revert /// @dev Tests that a move while the game status is not `IN_PROGRESS` causes the call to revert
...@@ -190,13 +213,13 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -190,13 +213,13 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
function test_move_gameNotInProgress_reverts() public { function test_move_gameNotInProgress_reverts() public {
uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS); uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS);
// Replace the game status in storage. It exists in slot 0 at offset 8. // Replace the game status in storage. It exists in slot 0 at offset 16.
uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0))); uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0)));
uint256 offset = (8 << 3); uint256 offset = 16 << 3;
uint256 mask = 0xFF << offset; uint256 mask = 0xFF << offset;
// Replace the byte in the slot value with the challenger wins status. // Replace the byte in the slot value with the challenger wins status.
slot = (slot & ~mask) | (chalWins << offset); slot = (slot & ~mask) | (chalWins << offset);
vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot)); vm.store(address(gameProxy), bytes32(0), bytes32(slot));
// Ensure that the game status was properly updated. // Ensure that the game status was properly updated.
GameStatus status = gameProxy.status(); GameStatus status = gameProxy.status();
...@@ -210,19 +233,19 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -210,19 +233,19 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error. /// @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error.
function test_move_defendRoot_reverts() public { function test_move_defendRoot_reverts() public {
vm.expectRevert(CannotDefendRootClaim.selector); vm.expectRevert(CannotDefendRootClaim.selector);
gameProxy.defend(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.defend(0, _dummyClaim());
} }
/// @dev Tests that an attempt to move against a claim that does not exist reverts with the /// @dev Tests that an attempt to move against a claim that does not exist reverts with the
/// `ParentDoesNotExist` error. /// `ParentDoesNotExist` error.
function test_move_nonExistentParent_reverts() public { function test_move_nonExistentParent_reverts() public {
Claim claim = Claim.wrap(bytes32(uint256(5))); Claim claim = _dummyClaim();
// Expect an out of bounds revert for an attack // Expect an out of bounds revert for an attack
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32)); vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32));
gameProxy.attack(1, claim); gameProxy.attack(1, claim);
// Expect an out of bounds revert for an attack // Expect an out of bounds revert for a defense
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32)); vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32));
gameProxy.defend(1, claim); gameProxy.defend(1, claim);
} }
...@@ -230,9 +253,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -230,9 +253,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that an attempt to move at the maximum game depth reverts with the /// @dev Tests that an attempt to move at the maximum game depth reverts with the
/// `GameDepthExceeded` error. /// `GameDepthExceeded` error.
function test_move_gameDepthExceeded_reverts() public { function test_move_gameDepthExceeded_reverts() public {
Claim claim = Claim.wrap(bytes32(uint256(5))); Claim claim = _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC);
uint256 maxDepth = gameProxy.MAX_GAME_DEPTH(); uint256 maxDepth = gameProxy.maxGameDepth();
for (uint256 i = 0; i <= maxDepth; i++) { for (uint256 i = 0; i <= maxDepth; i++) {
// At the max game depth, the `_move` function should revert with // At the max game depth, the `_move` function should revert with
...@@ -250,7 +273,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -250,7 +273,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// Warp ahead past the clock time for the first move (3 1/2 days) // Warp ahead past the clock time for the first move (3 1/2 days)
vm.warp(block.timestamp + 3 days + 12 hours + 1); vm.warp(block.timestamp + 3 days + 12 hours + 1);
vm.expectRevert(ClockTimeExceeded.selector); vm.expectRevert(ClockTimeExceeded.selector);
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, _dummyClaim());
} }
/// @notice Static unit test for the correctness of the chess clock incrementation. /// @notice Static unit test for the correctness of the chess clock incrementation.
...@@ -260,7 +283,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -260,7 +283,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp)))) Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
); );
Claim claim = Claim.wrap(bytes32(uint256(5))); Claim claim = _dummyClaim();
vm.warp(block.timestamp + 15); vm.warp(block.timestamp + 15);
gameProxy.attack(0, claim); gameProxy.attack(0, claim);
...@@ -276,6 +299,10 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -276,6 +299,10 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp)))) Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))))
); );
// We are at the split depth, so we need to set the status byte of the claim
// for the next move.
claim = _changeClaimStatus(claim, VMStatuses.PANIC);
vm.warp(block.timestamp + 10); vm.warp(block.timestamp + 10);
gameProxy.attack(2, claim); gameProxy.attack(2, claim);
(,,,, clock) = gameProxy.claimData(3); (,,,, clock) = gameProxy.claimData(3);
...@@ -294,7 +321,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -294,7 +321,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should /// @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should
/// revert with the `ClaimAlreadyExists` error. /// revert with the `ClaimAlreadyExists` error.
function test_move_duplicateClaim_reverts() public { function test_move_duplicateClaim_reverts() public {
Claim claim = Claim.wrap(bytes32(uint256(5))); Claim claim = _dummyClaim();
// Make the first move. This should succeed. // Make the first move. This should succeed.
gameProxy.attack(0, claim); gameProxy.attack(0, claim);
...@@ -306,14 +333,16 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -306,14 +333,16 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test asserting that identical claims at the same position can be made in different subgames. /// @dev Static unit test asserting that identical claims at the same position can be made in different subgames.
function test_move_duplicateClaimsDifferentSubgames_succeeds() public { function test_move_duplicateClaimsDifferentSubgames_succeeds() public {
Claim claimA = Claim.wrap(bytes32(uint256(5))); Claim claimA = _dummyClaim();
Claim claimB = Claim.wrap(bytes32(uint256(6))); Claim claimB = _dummyClaim();
// Make the first move. This should succeed. // Make the first moves. This should succeed.
gameProxy.attack(0, claimA); gameProxy.attack(0, claimA);
gameProxy.attack(0, claimB); gameProxy.attack(0, claimB);
gameProxy.attack(1, claimB); // Perform an attack at the same position with the same claim value in both subgames.
// These both should succeed.
gameProxy.attack(1, claimA);
gameProxy.attack(2, claimA); gameProxy.attack(2, claimA);
} }
...@@ -322,7 +351,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -322,7 +351,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// Warp ahead 5 seconds. // Warp ahead 5 seconds.
vm.warp(block.timestamp + 5); vm.warp(block.timestamp + 5);
Claim counter = Claim.wrap(bytes32(uint256(5))); Claim counter = _dummyClaim();
// Perform the attack. // Perform the attack.
vm.expectEmit(true, true, true, false); vm.expectEmit(true, true, true, false);
...@@ -355,6 +384,26 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -355,6 +384,26 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
); );
} }
/// @dev Tests that making a claim at the execution trace bisection root level with an invalid status
/// byte reverts with the `UnexpectedRootClaim` error.
function test_move_incorrectStatusExecRoot_reverts() public {
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, _dummyClaim());
}
vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, bytes32(0)));
gameProxy.attack(4, Claim.wrap(bytes32(0)));
}
/// @dev Tests that making a claim at the execution trace bisection root level with a valid status
/// byte succeeds.
function test_move_correctStatusExecRoot_succeeds() public {
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, _dummyClaim());
}
gameProxy.attack(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC));
}
/// @dev Static unit test for the correctness an uncontested root resolution. /// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontested_succeeds() public { function test_resolve_rootUncontested_succeeds() public {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
...@@ -382,9 +431,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -382,9 +431,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
function test_resolve_notInProgress_reverts() public { function test_resolve_notInProgress_reverts() public {
uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS); uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS);
// Replace the game status in storage. It exists in slot 0 at offset 8. // Replace the game status in storage. It exists in slot 0 at offset 16.
uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0))); uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0)));
uint256 offset = (8 << 3); uint256 offset = 16 << 3;
uint256 mask = 0xFF << offset; uint256 mask = 0xFF << offset;
// Replace the byte in the slot value with the challenger wins status. // Replace the byte in the slot value with the challenger wins status.
slot = (slot & ~mask) | (chalWins << offset); slot = (slot & ~mask) | (chalWins << offset);
...@@ -396,7 +445,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -396,7 +445,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test for the correctness of resolving a single attack game state. /// @dev Static unit test for the correctness of resolving a single attack game state.
function test_resolve_rootContested_succeeds() public { function test_resolve_rootContested_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
...@@ -406,8 +455,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -406,8 +455,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test for the correctness of resolving a game with a contested challenge claim. /// @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
function test_resolve_challengeContested_succeeds() public { function test_resolve_challengeContested_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, _dummyClaim());
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6)))); gameProxy.defend(1, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
...@@ -418,10 +467,10 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -418,10 +467,10 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test for the correctness of resolving a game with multiplayer moves. /// @dev Static unit test for the correctness of resolving a game with multiplayer moves.
function test_resolve_teamDeathmatch_succeeds() public { function test_resolve_teamDeathmatch_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, _dummyClaim());
gameProxy.attack(0, Claim.wrap(bytes32(uint256(4)))); gameProxy.attack(0, _dummyClaim());
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6)))); gameProxy.defend(1, _dummyClaim());
gameProxy.defend(1, Claim.wrap(bytes32(uint256(7)))); gameProxy.defend(1, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
...@@ -432,25 +481,30 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -432,25 +481,30 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test for the correctness of resolving a game that reaches max game depth. /// @dev Static unit test for the correctness of resolving a game that reaches max game depth.
function test_resolve_stepReached_succeeds() public { function test_resolve_stepReached_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); Claim claim = _dummyClaim();
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); for (uint256 i; i < gameProxy.splitDepth(); i++) {
gameProxy.attack(2, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(i, claim);
gameProxy.attack(3, Claim.wrap(bytes32(uint256(5)))); }
claim = _changeClaimStatus(claim, VMStatuses.PANIC);
for (uint256 i = gameProxy.claimDataLen() - 1; i < gameProxy.maxGameDepth(); i++) {
gameProxy.attack(i, claim);
}
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// resolving claim at 4 isn't necessary // resolving claim at 8 isn't necessary
gameProxy.resolveClaim(3); for (uint256 i = 8; i > 0; i--) {
gameProxy.resolveClaim(2); gameProxy.resolveClaim(i - 1);
gameProxy.resolveClaim(1); }
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
} }
/// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame multiple times /// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame multiple times
function test_resolve_claimAlreadyResolved_reverts() public { function test_resolve_claimAlreadyResolved_reverts() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); Claim claim = _dummyClaim();
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, claim);
gameProxy.attack(1, claim);
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
...@@ -461,21 +515,26 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -461,21 +515,26 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame at max depth /// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame at max depth
function test_resolve_claimAtMaxDepthAlreadyResolved_reverts() public { function test_resolve_claimAtMaxDepthAlreadyResolved_reverts() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); Claim claim = _dummyClaim();
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); for (uint256 i; i < gameProxy.splitDepth(); i++) {
gameProxy.attack(2, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(i, claim);
gameProxy.attack(3, Claim.wrap(bytes32(uint256(5)))); }
claim = _changeClaimStatus(claim, VMStatuses.PANIC);
for (uint256 i = gameProxy.claimDataLen() - 1; i < gameProxy.maxGameDepth(); i++) {
gameProxy.attack(i, claim);
}
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.expectRevert(ClaimAlreadyResolved.selector); vm.expectRevert(ClaimAlreadyResolved.selector);
gameProxy.resolveClaim(4); gameProxy.resolveClaim(8);
} }
/// @dev Static unit test asserting that resolve reverts when attempting to resolve subgames out of order /// @dev Static unit test asserting that resolve reverts when attempting to resolve subgames out of order
function test_resolve_outOfOrderResolution_reverts() public { function test_resolve_outOfOrderResolution_reverts() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, _dummyClaim());
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(1, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
...@@ -484,33 +543,45 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -484,33 +543,45 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
} }
/// @dev Tests that adding local data with an out of bounds identifier reverts. /// @dev Tests that adding local data with an out of bounds identifier reverts.
function testFuzz_addLocalData_oob_reverts(uint256 _ident, bytes32 _localContext) public { function testFuzz_addLocalData_oob_reverts(uint256 _ident) public {
// Get a claim below the split depth so that we can add local data for an execution trace subgame.
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, _dummyClaim());
}
gameProxy.attack(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC));
// [1, 5] are valid local data identifiers. // [1, 5] are valid local data identifiers.
if (_ident <= 5) _ident = 0; if (_ident <= 5) _ident = 0;
vm.expectRevert(InvalidLocalIdent.selector); vm.expectRevert(InvalidLocalIdent.selector);
gameProxy.addLocalData(_ident, _localContext, 0); gameProxy.addLocalData(_ident, 5, 0);
} }
/// @dev Tests that local data is loaded into the preimage oracle correctly. /// @dev Tests that local data is loaded into the preimage oracle correctly in the subgame
function test_addLocalData_static_succeeds() public { /// that is disputing the transition from `GENESIS -> GENESIS + 1`
IPreimageOracle oracle = IPreimageOracle(address(gameProxy.VM().oracle())); function test_addLocalDataGenesisTransition_static_succeeds() public {
(FaultDisputeGame.OutputProposal memory starting, FaultDisputeGame.OutputProposal memory disputed) = IPreimageOracle oracle = IPreimageOracle(address(gameProxy.vm().oracle()));
gameProxy.proposals();
bytes32[5] memory data = [ // Get a claim below the split depth so that we can add local data for an execution trace subgame.
Hash.unwrap(gameProxy.l1Head()), for (uint256 i; i < 4; i++) {
Hash.unwrap(starting.outputRoot), gameProxy.attack(i, Claim.wrap(bytes32(i)));
Hash.unwrap(disputed.outputRoot), }
bytes32(uint256(starting.l2BlockNumber) << 0xC0), gameProxy.attack(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC));
bytes32(block.chainid << 0xC0)
]; // Expected start/disputed claims
bytes32 startingClaim = Hash.unwrap(gameProxy.genesisOutputRoot());
bytes32 disputedClaim = bytes32(uint256(3));
Position disputedPos = LibPosition.wrap(4, 0);
// Expected local data
bytes32[5] memory data =
[Hash.unwrap(gameProxy.l1Head()), startingClaim, disputedClaim, bytes32(0), bytes32(block.chainid << 0xC0)];
for (uint256 i = 1; i <= 5; i++) { for (uint256 i = 1; i <= 5; i++) {
uint256 expectedLen = i > 3 ? 8 : 32; uint256 expectedLen = i > 3 ? 8 : 32;
bytes32 key = _getKey(i, keccak256(abi.encode(disputedClaim, disputedPos)));
gameProxy.addLocalData(i, 0, 0); gameProxy.addLocalData(i, 5, 0);
bytes32 key = _getKey(i, 0);
(bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0); (bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0);
assertEq(dat >> 0xC0, bytes32(expectedLen)); assertEq(dat >> 0xC0, bytes32(expectedLen));
// Account for the length prefix if i > 3 (the data stored // Account for the length prefix if i > 3 (the data stored
...@@ -520,570 +591,614 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -520,570 +591,614 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// total.) // total.)
assertEq(datLen, expectedLen + (i > 3 ? 8 : 0)); assertEq(datLen, expectedLen + (i > 3 ? 8 : 0));
gameProxy.addLocalData(i, 0, 8); gameProxy.addLocalData(i, 5, 8);
key = _getKey(i, 0);
(dat, datLen) = oracle.readPreimage(key, 8); (dat, datLen) = oracle.readPreimage(key, 8);
assertEq(dat, data[i - 1]); assertEq(dat, data[i - 1]);
assertEq(datLen, expectedLen); assertEq(datLen, expectedLen);
} }
} }
/// @dev Helper to get the localized key for an identifier in the context of the game proxy. /// @dev Tests that local data is loaded into the preimage oracle correctly.
function _getKey(uint256 _ident, bytes32 _localContext) internal view returns (bytes32) { function test_addLocalDataMiddle_static_succeeds() public {
bytes32 h = keccak256(abi.encode(_ident | (1 << 248), address(gameProxy), _localContext)); IPreimageOracle oracle = IPreimageOracle(address(gameProxy.vm().oracle()));
return bytes32((uint256(h) & ~uint256(0xFF << 248)) | (1 << 248));
}
function changeClaimStatus(Claim _claim, VMStatus _status) public pure returns (Claim out_) {
assembly {
out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status))
}
}
}
/// @notice A generic game player actor with a configurable trace.
/// @dev This actor always responds rationally with respect to their trace. The
/// `play` function can be overridden to change this behavior.
contract GamePlayer {
bool public failedToStep;
FaultDisputeGame public gameProxy;
bytes public trace;
GamePlayer internal counterParty;
Vm internal vm;
uint256 internal maxDepth;
/// @notice Initializes the player
function init(FaultDisputeGame _gameProxy, GamePlayer _counterParty, Vm _vm) public {
gameProxy = _gameProxy;
counterParty = _counterParty;
vm = _vm;
maxDepth = _gameProxy.MAX_GAME_DEPTH();
}
/// @notice Perform the next move in the game.
function play(uint256 _parentIndex) public virtual {
// Grab the claim data at the parent index.
(uint32 grandparentIndex,, Claim parentClaim, Position parentPos,) = gameProxy.claimData(_parentIndex);
// The position to move to.
Position movePos;
// May or may not be used.
Position movePos2;
// Signifies whether the move is an attack or not.
bool isAttack;
if (grandparentIndex == type(uint32).max) {
// If the parent claim is the root claim, begin by attacking.
movePos = parentPos.move(true);
// Flag the move as an attack.
isAttack = true;
} else {
// If the parent claim is not the root claim, check if we disagree with it and/or its grandparent
// to determine our next move(s).
// Fetch our claim at the parent's position.
Claim ourParentClaim = claimAt(parentPos);
// Fetch our claim at the grandparent's position.
(,, Claim grandparentClaim, Position grandparentPos,) = gameProxy.claimData(grandparentIndex);
Claim ourGrandparentClaim = claimAt(grandparentPos);
if (Claim.unwrap(ourParentClaim) != Claim.unwrap(parentClaim)) {
// Attack parent.
movePos = parentPos.move(true);
// If we also disagree with the grandparent, attack it as well.
if (Claim.unwrap(ourGrandparentClaim) != Claim.unwrap(grandparentClaim)) {
movePos2 = grandparentPos.move(true);
}
// Flag the move as an attack.
isAttack = true;
} else if (
Claim.unwrap(ourParentClaim) == Claim.unwrap(parentClaim)
&& Claim.unwrap(ourGrandparentClaim) == Claim.unwrap(grandparentClaim)
) {
movePos = parentPos.move(false);
}
}
// If we are past the maximum depth, break the recursion and step.
if (movePos.depth() > maxDepth) {
bytes memory preStateTrace;
// First, we need to find the pre/post state index depending on whether we
// are making an attack step or a defense step. If the index at depth of the
// move position is 0, the prestate is the absolute prestate and we need to
// do nothing.
if (movePos.indexAtDepth() > 0) {
Position leafPos = isAttack
? Position.wrap(Position.unwrap(parentPos) - 1)
: Position.wrap(Position.unwrap(parentPos) + 1);
Position statePos = leafPos.traceAncestor();
// Grab the trace up to the prestate's trace index.
if (isAttack) {
preStateTrace = abi.encode(statePos.traceIndex(maxDepth), traceAt(statePos));
} else {
preStateTrace = abi.encode(parentPos.traceIndex(maxDepth), traceAt(parentPos));
}
} else {
preStateTrace = abi.encode(15);
}
// Perform the step and halt recursion.
try gameProxy.step(_parentIndex, isAttack, preStateTrace, hex"") {
// Do nothing, step succeeded.
} catch {
failedToStep = true;
}
} else {
// Find the trace index that our next claim must commit to.
uint256 traceIndex = movePos.traceIndex(maxDepth);
// Grab the claim that we need to make from the helper.
Claim ourClaim = claimAt(traceIndex);
if (isAttack) {
// Attack the parent claim.
gameProxy.attack(_parentIndex, ourClaim);
// Call out to our counter party to respond.
counterParty.play(gameProxy.claimDataLen() - 1);
// If we have a second move position, attack the grandparent.
if (Position.unwrap(movePos2) != 0) {
(,,, Position grandparentPos,) = gameProxy.claimData(grandparentIndex);
Claim ourGrandparentClaim = claimAt(grandparentPos.move(true));
gameProxy.attack(grandparentIndex, ourGrandparentClaim);
counterParty.play(gameProxy.claimDataLen() - 1);
}
} else {
// Don't defend a claim we would've made ourselves.
if (parentPos.depth() % 2 == 0 && Claim.unwrap(claimAt(15)) == Claim.unwrap(gameProxy.rootClaim())) {
return;
}
// Defend the parent claim.
gameProxy.defend(_parentIndex, ourClaim);
// Call out to our counter party to respond.
counterParty.play(gameProxy.claimDataLen() - 1);
}
}
}
/// @notice Returns the state at the trace index within the player's trace.
function traceAt(Position _position) public view returns (uint256 state_) {
return traceAt(_position.traceIndex(maxDepth));
}
/// @notice Returns the state at the trace index within the player's trace.
function traceAt(uint256 _traceIndex) public view returns (uint256 state_) {
return uint256(uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex]));
}
/// @notice Returns the player's claim that commits to a given trace index. // Get a claim below the split depth so that we can add local data for an execution trace subgame.
function claimAt(uint256 _traceIndex) public view returns (Claim claim_) { for (uint256 i; i < 4; i++) {
bytes32 hash = gameProxy.attack(i, Claim.wrap(bytes32(i)));
keccak256(abi.encode(_traceIndex >= trace.length ? trace.length - 1 : _traceIndex, traceAt(_traceIndex)));
assembly {
claim_ := or(and(hash, not(shl(248, 0xFF))), shl(248, 1))
} }
} gameProxy.defend(4, _changeClaimStatus(ROOT_CLAIM, VMStatuses.VALID));
/// @notice Returns the player's claim that commits to a given trace index.
function claimAt(Position _position) public view returns (Claim claim_) {
return claimAt(_position.traceIndex(maxDepth));
}
}
contract Resolver {
FaultDisputeGame public gameProxy;
mapping(uint256 => bool) subgames; // Expected start/disputed claims
bytes32 startingClaim = bytes32(uint256(3));
Position startingPos = LibPosition.wrap(4, 0);
bytes32 disputedClaim = bytes32(uint256(2));
Position disputedPos = LibPosition.wrap(3, 0);
constructor(FaultDisputeGame gameProxy_) { // Expected local data
gameProxy = gameProxy_; bytes32[5] memory data = [
} Hash.unwrap(gameProxy.l1Head()),
startingClaim,
disputedClaim,
bytes32(uint256(1) << 0xC0),
bytes32(block.chainid << 0xC0)
];
/// @notice Auto-resolves all subgames in the game for (uint256 i = 1; i <= 5; i++) {
function run() public { uint256 expectedLen = i > 3 ? 8 : 32;
for (uint256 i = gameProxy.claimDataLen() - 1; i > 0; i--) { bytes32 key = _getKey(i, keccak256(abi.encode(startingClaim, startingPos, disputedClaim, disputedPos)));
(uint32 parentIndex,,,,) = gameProxy.claimData(i);
subgames[parentIndex] = true;
// Subgames containing only one node are implicitly resolved gameProxy.addLocalData(i, 5, 0);
// i.e. uncountered claims and claims at MAX_DEPTH (bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0);
if (!subgames[i]) { assertEq(dat >> 0xC0, bytes32(expectedLen));
continue; // Account for the length prefix if i > 3 (the data stored
} // at identifiers i <= 3 are 32 bytes long, so the expected
// length is already correct. If i > 3, the data is only 8
// bytes long, so the length prefix + the data is 16 bytes
// total.)
assertEq(datLen, expectedLen + (i > 3 ? 8 : 0));
gameProxy.resolveClaim(i); gameProxy.addLocalData(i, 5, 8);
(dat, datLen) = oracle.readPreimage(key, 8);
assertEq(dat, data[i - 1]);
assertEq(datLen, expectedLen);
} }
gameProxy.resolveClaim(0);
} }
}
contract OneVsOne_Arena is FaultDisputeGame_Init { /// @dev Helper to return a pseudo-random claim
/// @dev The absolute prestate of the trace. function _dummyClaim() internal view returns (Claim) {
bytes ABSOLUTE_PRESTATE = abi.encode(15); return Claim.wrap(keccak256(abi.encode(gasleft())));
/// @dev The absolute prestate claim.
Claim internal constant ABSOLUTE_PRESTATE_CLAIM =
Claim.wrap(bytes32((uint256(3) << 248) | (~uint256(0xFF << 248) & uint256(keccak256(abi.encode(15))))));
/// @dev The defender.
GamePlayer internal defender;
/// @dev The challenger.
GamePlayer internal challenger;
/// @dev The resolver.
Resolver internal resolver;
function init(GamePlayer _defender, GamePlayer _challenger, uint256 _finalTraceIndex) public {
Claim rootClaim = _defender.claimAt(_finalTraceIndex);
super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM);
defender = _defender;
challenger = _challenger;
resolver = new Resolver(gameProxy);
// Set the counterparties.
defender.init(gameProxy, challenger, vm);
challenger.init(gameProxy, defender, vm);
// Label actors for trace.
vm.label(address(challenger), "Challenger");
vm.label(address(defender), "Defender");
vm.label(address(resolver), "Resolver");
} }
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1 is OneVsOne_Arena {
function setUp() public override {
super.setUp();
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 0);
super.init(dishonest, honest, 15);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(defender.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot1 is OneVsOne_Arena {
function setUp() public override {
super.setUp();
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 0);
super.init(honest, dishonest, 15);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root /// @dev Helper to get the localized key for an identifier in the context of the game proxy.
// claim unsuccessfully. function _getKey(uint256 _ident, bytes32 _localContext) internal view returns (bytes32) {
resolver.run(); bytes32 h = keccak256(abi.encode(_ident | (1 << 248), address(gameProxy), _localContext));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); return bytes32((uint256(h) & ~uint256(0xFF << 248)) | (1 << 248));
assertTrue(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena {
function setUp() public override {
super.setUp();
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 7);
super.init(dishonest, honest, 15);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(defender.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena {
function setUp() public override {
super.setUp();
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 7);
super.init(honest, dishonest, 15);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena {
function setUp() public override {
super.setUp();
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 2);
super.init(dishonest, honest, 15);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(defender.failedToStep());
} }
} }
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena { contract FaultDispute_1v1_Actors_Test is FaultDisputeGame_Init {
function setUp() public override { /// @dev The honest actor
super.setUp(); DisputeActor internal honest;
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); /// @dev The dishonest actor
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 2); DisputeActor internal dishonest;
super.init(honest, dishonest, 15);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
// Setup the `FaultDisputeGame`
super.setUp(); super.setUp();
GamePlayer honest = new HonestPlayer_HalfTrace(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 8, 5);
super.init(dishonest, honest, 7);
} }
function test_resolvesCorrectly_succeeds() public { /// @notice Fuzz test for a 1v1 output bisection dispute.
// Play the game until a step is forced. /// @dev The alphabet game has a constant status byte, and is not safe from someone being dishonest in
challenger.play(0); /// output bisection and then posting a correct execution trace bisection root claim. This test
/// does not cover this case (i.e. root claim of output bisection is dishonest, root claim of
// Warp ahead to expire the other player's clock. /// execution trace bisection is made by the dishonest actor but is honest, honest actor cannot
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); /// attack it without risk of losing).
function testFuzz_outputBisection1v1honestRoot_succeeds(uint8 _divergeOutput, uint8 _divergeStep) public {
// Resolve the game and assert that the honest player challenged the root uint256[] memory honestL2Outputs = new uint256[](16);
// claim successfully. for (uint256 i; i < honestL2Outputs.length; i++) {
resolver.run(); honestL2Outputs[i] = i + 1;
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); }
assertFalse(challenger.failedToStep()); bytes memory honestTrace = new bytes(256);
} for (uint256 i; i < honestTrace.length; i++) {
} honestTrace[i] = bytes1(uint8(i));
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot4 is OneVsOne_Arena {
function setUp() public override {
super.setUp();
GamePlayer honest = new HonestPlayer_HalfTrace(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 8, 5);
super.init(honest, dishonest, 7);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5 is OneVsOne_Arena {
function setUp() public override {
super.setUp();
GamePlayer honest = new HonestPlayer_QuarterTrace(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 4, 3);
super.init(dishonest, honest, 3);
}
function test_resolvesCorrectly_succeeds() public { uint256 divergeAtOutput = bound(_divergeOutput, 0, 15);
// Play the game until a step is forced. uint256 divergeAtStep = bound(_divergeStep, 0, 7);
challenger.play(0); uint256 divergeStepOffset = (divergeAtOutput << 4) + divergeAtStep;
// Warp ahead to expire the other player's clock. uint256[] memory dishonestL2Outputs = new uint256[](16);
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i >= divergeAtOutput ? 0xFF : i + 1;
}
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i >= divergeStepOffset ? bytes1(uint8(0xFF)) : bytes1(uint8(i));
}
// Resolve the game and assert that the honest player challenged the root // Run the actor test
// claim successfully. _actorTest({
resolver.run(); _rootClaim: 16,
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); _absolutePrestateData: 0,
assertFalse(challenger.failedToStep()); _honestTrace: honestTrace,
} _honestL2Outputs: honestL2Outputs,
} _dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1honestRootGenesisAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot5 is OneVsOne_Arena { // The dishonest l2 outputs are from [2, 17] in this game.
function setUp() public override { uint256[] memory dishonestL2Outputs = new uint256[](16);
super.setUp(); for (uint256 i; i < dishonestL2Outputs.length; i++) {
GamePlayer honest = new HonestPlayer_QuarterTrace(ABSOLUTE_PRESTATE); dishonestL2Outputs[i] = i + 2;
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 4, 3); }
super.init(honest, dishonest, 3); // The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
} // of all set bits.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = bytes1(0xFF);
}
function test_resolvesCorrectly_succeeds() public { // Run the actor test
// Play the game until a step is forced. _actorTest({
challenger.play(0); _rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRootGenesisAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// Warp ahead to expire the other player's clock. // The dishonest l2 outputs are from [2, 17] in this game.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i + 2;
}
// The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of all set bits.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = bytes1(0xFF);
}
// Resolve the game and assert that the dishonest player challenged the root // Run the actor test
// claim unsuccessfully. _actorTest({
resolver.run(); _rootClaim: 17,
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); _absolutePrestateData: 0,
assertTrue(challenger.failedToStep()); _honestTrace: honestTrace,
} _honestL2Outputs: honestL2Outputs,
} _dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1honestRoot_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRootFuzz is OneVsOne_Arena { // The dishonest l2 outputs are from [2, 17] in this game.
function testFuzz_resolvesCorrectly_succeeds(uint256 _dishonestTraceLength) public { uint256[] memory dishonestL2Outputs = new uint256[](16);
_dishonestTraceLength = bound(_dishonestTraceLength, 1, 16); for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i + 2;
}
// The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of all zeros.
bytes memory dishonestTrace = new bytes(256);
// Run the actor test
_actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRoot_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
for (uint256 i = 0; i < _dishonestTraceLength; i++) { // The dishonest l2 outputs are from [2, 17] in this game.
uint256 snapshot = vm.snapshot(); uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i + 2;
}
// The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of all zeros.
bytes memory dishonestTrace = new bytes(256);
// Run the actor test
_actorTest({
_rootClaim: 17,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1correctRootHalfWay_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); // The dishonest l2 outputs are half correct, half incorrect.
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, _dishonestTraceLength, i); uint256[] memory dishonestL2Outputs = new uint256[](16);
super.init(dishonest, honest, _dishonestTraceLength - 1); for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 4) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Play the game until a step is forced. // Run the actor test
challenger.play(0); _actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRootHalfWay_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// Warp ahead to expire the other player's clock. // The dishonest l2 outputs are half correct, half incorrect.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 4) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Resolve the game and assert that the honest player challenged the root // Run the actor test
// claim successfully. _actorTest({
resolver.run(); _rootClaim: 0xFF,
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); _absolutePrestateData: 0,
assertFalse(defender.failedToStep()); _honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1correctAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
vm.revertTo(snapshot); // The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace correct is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i));
} }
}
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRootFuzz is OneVsOne_Arena { // Run the actor test
function testFuzz_resolvesCorrectly_succeeds(uint256 _dishonestTraceLength) public { _actorTest({
_dishonestTraceLength = bound(_dishonestTraceLength, 1, 16); _rootClaim: 16,
for (uint256 i = 0; i < _dishonestTraceLength; i++) { _absolutePrestateData: 0,
uint256 snapshot = vm.snapshot(); _honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); // The dishonest l2 outputs are half correct, half incorrect.
GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, _dishonestTraceLength, i); uint256[] memory dishonestL2Outputs = new uint256[](16);
super.init(honest, dishonest, 15); for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace correct is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i));
}
// Play the game until a step is forced. // Run the actor test
challenger.play(0); _actorTest({
_rootClaim: 0xFF,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1honestRootFinalInstruction_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// Warp ahead to expire the other player's clock. // The dishonest l2 outputs are half correct, half incorrect.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, and correct all the way up to the final instruction of the exec
// subgame.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 7) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Resolve the game and assert that the honest player challenged the root // Run the actor test
// claim successfully. _actorTest({
resolver.run(); _rootClaim: 16,
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); _absolutePrestateData: 0,
assertTrue(challenger.failedToStep()); _honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRootFinalInstruction_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
vm.revertTo(snapshot); // The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
} }
// The dishonest trace is half correct, and correct all the way up to the final instruction of the exec
// subgame.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 7) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 0xFF,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
} }
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// ACTORS // // HELPERS //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
contract HonestPlayer is GamePlayer { /// @dev Helper to run a 1v1 actor test
constructor(bytes memory _absolutePrestate) { function _actorTest(
uint8 absolutePrestate = uint8(_absolutePrestate[31]); uint256 _rootClaim,
bytes memory honestTrace = new bytes(16); uint256 _absolutePrestateData,
for (uint8 i = 0; i < honestTrace.length; i++) { bytes memory _honestTrace,
honestTrace[i] = bytes1(absolutePrestate + i + 1); uint256[] memory _honestL2Outputs,
bytes memory _dishonestTrace,
uint256[] memory _dishonestL2Outputs,
GameStatus _expectedStatus
)
internal
{
// Setup the environment
bytes memory absolutePrestateData =
_setup({ _absolutePrestateData: _absolutePrestateData, _rootClaim: _rootClaim });
// Create actors
_createActors({
_honestTrace: _honestTrace,
_honestPreStateData: absolutePrestateData,
_honestL2Outputs: _honestL2Outputs,
_dishonestTrace: _dishonestTrace,
_dishonestPreStateData: absolutePrestateData,
_dishonestL2Outputs: _dishonestL2Outputs
});
// Exhaust all moves from both actors
_exhaustMoves();
// Resolve the game and assert that the defender won
_warpAndResolve();
assertEq(uint8(gameProxy.status()), uint8(_expectedStatus));
}
/// @dev Helper to setup the 1v1 test
function _setup(
uint256 _absolutePrestateData,
uint256 _rootClaim
)
internal
returns (bytes memory absolutePrestateData_)
{
absolutePrestateData_ = abi.encode(_absolutePrestateData);
Claim absolutePrestateExec =
_changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData_)), VMStatuses.UNFINISHED);
Claim rootClaim = Claim.wrap(bytes32(uint256(_rootClaim)));
super.init({
rootClaim: rootClaim,
absolutePrestate: absolutePrestateExec,
l2BlockNumber: _rootClaim,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
}
/// @dev Helper to create actors for the 1v1 dispute.
function _createActors(
bytes memory _honestTrace,
bytes memory _honestPreStateData,
uint256[] memory _honestL2Outputs,
bytes memory _dishonestTrace,
bytes memory _dishonestPreStateData,
uint256[] memory _dishonestL2Outputs
)
internal
{
honest = new HonestDisputeActor({
_gameProxy: gameProxy,
_l2Outputs: _honestL2Outputs,
_trace: _honestTrace,
_preStateData: _honestPreStateData
});
dishonest = new HonestDisputeActor({
_gameProxy: gameProxy,
_l2Outputs: _dishonestL2Outputs,
_trace: _dishonestTrace,
_preStateData: _dishonestPreStateData
});
vm.label(address(honest), "HonestActor");
vm.label(address(dishonest), "DishonestActor");
}
/// @dev Helper to exhaust all moves from both actors.
function _exhaustMoves() internal {
while (true) {
// Allow the dishonest actor to make their moves, and then the honest actor.
(uint256 numMovesA,) = dishonest.move();
(uint256 numMovesB, bool success) = honest.move();
require(success, "Honest actor's moves should always be successful");
// If both actors have run out of moves, we're done.
if (numMovesA == 0 && numMovesB == 0) break;
} }
trace = honestTrace;
} }
}
contract HonestPlayer_HalfTrace is GamePlayer { /// @dev Helper to warp past the chess clock and resolve all claims within the dispute game.
constructor(bytes memory _absolutePrestate) { function _warpAndResolve() internal {
uint8 absolutePrestate = uint8(_absolutePrestate[31]); // Warp past the chess clock
bytes memory halfTrace = new bytes(8); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
for (uint8 i = 0; i < halfTrace.length; i++) {
halfTrace[i] = bytes1(absolutePrestate + i + 1);
}
trace = halfTrace;
}
}
contract HonestPlayer_QuarterTrace is GamePlayer { // Resolve all claims in reverse order. We allow `resolveClaim` calls to fail due to
constructor(bytes memory _absolutePrestate) { // the check that prevents claims with no subgames attached from being passed to
uint8 absolutePrestate = uint8(_absolutePrestate[31]); // `resolveClaim`. There's also a check in `resolve` to ensure all children have been
bytes memory halfTrace = new bytes(4); // resolved before global resolution, which catches any unresolved subgames here.
for (uint8 i = 0; i < halfTrace.length; i++) { for (uint256 i = gameProxy.claimDataLen(); i > 0; i--) {
halfTrace[i] = bytes1(absolutePrestate + i + 1); (bool success,) = address(gameProxy).call(abi.encodeCall(gameProxy.resolveClaim, (i - 1)));
success;
} }
trace = halfTrace; gameProxy.resolve();
} }
} }
contract VariableDivergentPlayer is GamePlayer { /// @dev Helper to change the VM status byte of a claim.
constructor(bytes memory _absolutePrestate, uint256 _traceLength, uint256 _divergeAt) { function _changeClaimStatus(Claim _claim, VMStatus _status) pure returns (Claim out_) {
uint8 absolutePrestate = uint8(_absolutePrestate[31]); assembly {
bytes memory _trace = new bytes(_traceLength); out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status))
for (uint8 i = 0; i < _trace.length; i++) {
// Diverge at trace instruction `_divergeAt`.
_trace[i] = i >= _divergeAt ? bytes1(i) : bytes1(absolutePrestate + i + 1);
}
trace = _trace;
} }
} }
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import { Test } from "forge-std/Test.sol";
import { Vm } from "forge-std/Vm.sol";
import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { OutputBisectionGame } from "src/dispute/OutputBisectionGame.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { BlockOracle } from "src/dispute/BlockOracle.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol";
import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol";
import { Types } from "src/libraries/Types.sol";
import { LibClock } from "src/dispute/lib/LibClock.sol";
import { LibPosition } from "src/dispute/lib/LibPosition.sol";
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { AlphabetVM2 } from "test/mocks/AlphabetVM2.sol";
import { DisputeActor, HonestDisputeActor } from "test/actors/OutputBisectionActors.sol";
contract OutputBisectionGame_Init is DisputeGameFactory_Init {
/// @dev The type of the game being tested.
GameType internal constant GAME_TYPE = GameType.wrap(0);
/// @dev The implementation of the game.
OutputBisectionGame internal gameImpl;
/// @dev The `Clone` proxy of the game.
OutputBisectionGame internal gameProxy;
/// @dev The extra data passed to the game for initialization.
bytes internal extraData;
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
function init(
Claim rootClaim,
Claim absolutePrestate,
uint256 l2BlockNumber,
uint256 genesisBlockNumber,
Hash genesisOutputRoot
)
public
{
// Set the time to a realistic date.
vm.warp(1690906994);
// Set the extra data for the game creation
extraData = abi.encode(l2BlockNumber);
AlphabetVM2 _vm = new AlphabetVM2(absolutePrestate);
// Deploy an implementation of the fault game
gameImpl = new OutputBisectionGame({
_gameType: GAME_TYPE,
_absolutePrestate: absolutePrestate,
_genesisBlockNumber: genesisBlockNumber,
_genesisOutputRoot: genesisOutputRoot,
_maxGameDepth: 2 ** 3,
_splitDepth: 2 ** 2,
_gameDuration: Duration.wrap(7 days),
_vm: _vm
});
// Register the game implementation with the factory.
factory.setImplementation(GAME_TYPE, gameImpl);
// Create a new game.
gameProxy = OutputBisectionGame(address(factory.create(GAME_TYPE, rootClaim, extraData)));
// Check immutables
assertEq(GameType.unwrap(gameProxy.gameType()), GameType.unwrap(GAME_TYPE));
assertEq(Claim.unwrap(gameProxy.absolutePrestate()), Claim.unwrap(absolutePrestate));
assertEq(gameProxy.genesisBlockNumber(), genesisBlockNumber);
assertEq(Hash.unwrap(gameProxy.genesisOutputRoot()), Hash.unwrap(genesisOutputRoot));
assertEq(gameProxy.maxGameDepth(), 2 ** 3);
assertEq(gameProxy.splitDepth(), 2 ** 2);
assertEq(Duration.unwrap(gameProxy.gameDuration()), 7 days);
assertEq(address(gameProxy.vm()), address(_vm));
// Label the proxy
vm.label(address(gameProxy), "OutputBisectionGame_Clone");
}
}
contract OutputBisectionGame_Test is OutputBisectionGame_Init {
/// @dev The root claim of the game.
Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10)));
/// @dev The absolute prestate of the trace.
Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32((uint256(3) << 248) | uint256(0)));
function setUp() public override {
super.setUp();
super.init({
rootClaim: ROOT_CLAIM,
absolutePrestate: ABSOLUTE_PRESTATE,
l2BlockNumber: 0x10,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
}
////////////////////////////////////////////////////////////////
// `IDisputeGame` Implementation Tests //
////////////////////////////////////////////////////////////////
/// @dev Tests that the constructor of the `OutputBisectionGame` reverts when the `_splitDepth`
/// parameter is greater than or equal to the `MAX_GAME_DEPTH`
function test_constructor_wrongArgs_reverts(uint256 _splitDepth) public {
AlphabetVM2 alphabetVM = new AlphabetVM2(ABSOLUTE_PRESTATE);
// Test that the constructor reverts when the `_splitDepth` parameter is greater than or equal
// to the `MAX_GAME_DEPTH` parameter.
_splitDepth = bound(_splitDepth, 2 ** 3, type(uint256).max);
vm.expectRevert(InvalidSplitDepth.selector);
new OutputBisectionGame({
_gameType: GAME_TYPE,
_absolutePrestate: ABSOLUTE_PRESTATE,
_genesisBlockNumber: 0,
_genesisOutputRoot: Hash.wrap(bytes32(0)),
_maxGameDepth: 2 ** 3,
_splitDepth: _splitDepth,
_gameDuration: Duration.wrap(7 days),
_vm: alphabetVM
});
}
/// @dev Tests that the game's root claim is set correctly.
function test_rootClaim_succeeds() public {
assertEq(Claim.unwrap(gameProxy.rootClaim()), Claim.unwrap(ROOT_CLAIM));
}
/// @dev Tests that the game's extra data is set correctly.
function test_extraData_succeeds() public {
assertEq(gameProxy.extraData(), extraData);
}
/// @dev Tests that the game's starting timestamp is set correctly.
function test_createdAt_succeeds() public {
assertEq(Timestamp.unwrap(gameProxy.createdAt()), block.timestamp);
}
/// @dev Tests that the game's type is set correctly.
function test_gameType_succeeds() public {
assertEq(GameType.unwrap(gameProxy.gameType()), GameType.unwrap(GAME_TYPE));
}
/// @dev Tests that the game's data is set correctly.
function test_gameData_succeeds() public {
(GameType gameType, Claim rootClaim, bytes memory _extraData) = gameProxy.gameData();
assertEq(GameType.unwrap(gameType), GameType.unwrap(GAME_TYPE));
assertEq(Claim.unwrap(rootClaim), Claim.unwrap(ROOT_CLAIM));
assertEq(_extraData, extraData);
}
////////////////////////////////////////////////////////////////
// `IOutputBisectionGame` Implementation Tests //
////////////////////////////////////////////////////////////////
/// @dev Tests that the game cannot be initialized with an output root that commits to <= the configured genesis
/// block number
function testFuzz_initialize_cannotProposeGenesis_reverts(uint256 _blockNumber) public {
_blockNumber = bound(_blockNumber, 0, gameProxy.genesisBlockNumber());
Claim claim = _dummyClaim();
vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, claim));
gameProxy = OutputBisectionGame(address(factory.create(GAME_TYPE, claim, abi.encode(_blockNumber))));
}
/// @dev Tests that the game cannot be initialized with extra data > 64 bytes long (root claim + l2 block number
/// concatenated)
function testFuzz_initialize_extraDataTooLong_reverts(uint256 _extraDataLen) public {
// The `DisputeGameFactory` will pack the root claim and the extra data into a single array, which is enforced
// to be at least 64 bytes long.
// We bound the upper end to 23.5KB to ensure that the minimal proxy never surpasses the contract size limit
// in this test, as CWIA proxies store the immutable args in their bytecode.
// [33 bytes, 23.5 KB]
_extraDataLen = bound(_extraDataLen, 33, 23_500);
bytes memory _extraData = new bytes(_extraDataLen);
// Assign the first 32 bytes in `extraData` to a valid L2 block number passed genesis.
uint256 genesisBlockNumber = gameProxy.genesisBlockNumber();
assembly {
mstore(add(_extraData, 0x20), add(genesisBlockNumber, 1))
}
Claim claim = _dummyClaim();
vm.expectRevert(abi.encodeWithSelector(ExtraDataTooLong.selector));
gameProxy = OutputBisectionGame(address(factory.create(GAME_TYPE, claim, _extraData)));
}
/// @dev Tests that the game is initialized with the correct data.
function test_initialize_correctData_succeeds() public {
// Assert that the root claim is initialized correctly.
(uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(0);
assertEq(parentIndex, type(uint32).max);
assertEq(countered, false);
assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM));
assertEq(Position.unwrap(position), 1);
assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
);
// Assert that the `createdAt` timestamp is correct.
assertEq(Timestamp.unwrap(gameProxy.createdAt()), block.timestamp);
// Assert that the blockhash provided is correct.
assertEq(Hash.unwrap(gameProxy.l1Head()), blockhash(block.number - 1));
}
/// @dev Tests that a move while the game status is not `IN_PROGRESS` causes the call to revert
/// with the `GameNotInProgress` error
function test_move_gameNotInProgress_reverts() public {
uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS);
// Replace the game status in storage. It exists in slot 0 at offset 16.
uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0)));
uint256 offset = 16 << 3;
uint256 mask = 0xFF << offset;
// Replace the byte in the slot value with the challenger wins status.
slot = (slot & ~mask) | (chalWins << offset);
vm.store(address(gameProxy), bytes32(0), bytes32(slot));
// Ensure that the game status was properly updated.
GameStatus status = gameProxy.status();
assertEq(uint256(status), chalWins);
// Attempt to make a move. Should revert.
vm.expectRevert(GameNotInProgress.selector);
gameProxy.attack(0, Claim.wrap(0));
}
/// @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error.
function test_move_defendRoot_reverts() public {
vm.expectRevert(CannotDefendRootClaim.selector);
gameProxy.defend(0, _dummyClaim());
}
/// @dev Tests that an attempt to move against a claim that does not exist reverts with the
/// `ParentDoesNotExist` error.
function test_move_nonExistentParent_reverts() public {
Claim claim = _dummyClaim();
// Expect an out of bounds revert for an attack
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32));
gameProxy.attack(1, claim);
// Expect an out of bounds revert for a defense
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32));
gameProxy.defend(1, claim);
}
/// @dev Tests that an attempt to move at the maximum game depth reverts with the
/// `GameDepthExceeded` error.
function test_move_gameDepthExceeded_reverts() public {
Claim claim = _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC);
uint256 maxDepth = gameProxy.maxGameDepth();
for (uint256 i = 0; i <= maxDepth; i++) {
// At the max game depth, the `_move` function should revert with
// the `GameDepthExceeded` error.
if (i == maxDepth) {
vm.expectRevert(GameDepthExceeded.selector);
}
gameProxy.attack(i, claim);
}
}
/// @dev Tests that a move made after the clock time has exceeded reverts with the
/// `ClockTimeExceeded` error.
function test_move_clockTimeExceeded_reverts() public {
// Warp ahead past the clock time for the first move (3 1/2 days)
vm.warp(block.timestamp + 3 days + 12 hours + 1);
vm.expectRevert(ClockTimeExceeded.selector);
gameProxy.attack(0, _dummyClaim());
}
/// @notice Static unit test for the correctness of the chess clock incrementation.
function test_move_clockCorrectness_succeeds() public {
(,,,, Clock clock) = gameProxy.claimData(0);
assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
);
Claim claim = _dummyClaim();
vm.warp(block.timestamp + 15);
gameProxy.attack(0, claim);
(,,,, clock) = gameProxy.claimData(1);
assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(1, claim);
(,,,, clock) = gameProxy.claimData(2);
assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))))
);
// We are at the split depth, so we need to set the status byte of the claim
// for the next move.
claim = _changeClaimStatus(claim, VMStatuses.PANIC);
vm.warp(block.timestamp + 10);
gameProxy.attack(2, claim);
(,,,, clock) = gameProxy.claimData(3);
assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(3, claim);
(,,,, clock) = gameProxy.claimData(4);
assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp))))
);
}
/// @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should
/// revert with the `ClaimAlreadyExists` error.
function test_move_duplicateClaim_reverts() public {
Claim claim = _dummyClaim();
// Make the first move. This should succeed.
gameProxy.attack(0, claim);
// Attempt to make the same move again.
vm.expectRevert(ClaimAlreadyExists.selector);
gameProxy.attack(0, claim);
}
/// @dev Static unit test asserting that identical claims at the same position can be made in different subgames.
function test_move_duplicateClaimsDifferentSubgames_succeeds() public {
Claim claimA = _dummyClaim();
Claim claimB = _dummyClaim();
// Make the first moves. This should succeed.
gameProxy.attack(0, claimA);
gameProxy.attack(0, claimB);
// Perform an attack at the same position with the same claim value in both subgames.
// These both should succeed.
gameProxy.attack(1, claimA);
gameProxy.attack(2, claimA);
}
/// @dev Static unit test for the correctness of an opening attack.
function test_move_simpleAttack_succeeds() public {
// Warp ahead 5 seconds.
vm.warp(block.timestamp + 5);
Claim counter = _dummyClaim();
// Perform the attack.
vm.expectEmit(true, true, true, false);
emit Move(0, counter, address(this));
gameProxy.attack(0, counter);
// Grab the claim data of the attack.
(uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(1);
// Assert correctness of the attack claim's data.
assertEq(parentIndex, 0);
assertEq(countered, false);
assertEq(Claim.unwrap(claim), Claim.unwrap(counter));
assertEq(Position.unwrap(position), Position.unwrap(Position.wrap(1).move(true)));
assertEq(
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(5), Timestamp.wrap(uint64(block.timestamp))))
);
// Grab the claim data of the parent.
(parentIndex, countered, claim, position, clock) = gameProxy.claimData(0);
// Assert correctness of the parent claim's data.
assertEq(parentIndex, type(uint32).max);
assertEq(countered, true);
assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM));
assertEq(Position.unwrap(position), 1);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp - 5))))
);
}
/// @dev Tests that making a claim at the execution trace bisection root level with an invalid status
/// byte reverts with the `UnexpectedRootClaim` error.
function test_move_incorrectStatusExecRoot_reverts() public {
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, _dummyClaim());
}
vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, bytes32(0)));
gameProxy.attack(4, Claim.wrap(bytes32(0)));
}
/// @dev Tests that making a claim at the execution trace bisection root level with a valid status
/// byte succeeds.
function test_move_correctStatusExecRoot_succeeds() public {
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, _dummyClaim());
}
gameProxy.attack(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC));
}
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontested_succeeds() public {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
}
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontestedClockNotExpired_succeeds() public {
vm.warp(block.timestamp + 3 days + 12 hours);
vm.expectRevert(ClockNotExpired.selector);
gameProxy.resolveClaim(0);
}
/// @dev Static unit test asserting that resolve reverts when the absolute root
/// subgame has not been resolved.
function test_resolve_rootUncontestedButUnresolved_reverts() public {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.expectRevert(OutOfOrderResolution.selector);
gameProxy.resolve();
}
/// @dev Static unit test asserting that resolve reverts when the game state is
/// not in progress.
function test_resolve_notInProgress_reverts() public {
uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS);
// Replace the game status in storage. It exists in slot 0 at offset 16.
uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0)));
uint256 offset = 16 << 3;
uint256 mask = 0xFF << offset;
// Replace the byte in the slot value with the challenger wins status.
slot = (slot & ~mask) | (chalWins << offset);
vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot));
vm.expectRevert(GameNotInProgress.selector);
gameProxy.resolveClaim(0);
}
/// @dev Static unit test for the correctness of resolving a single attack game state.
function test_resolve_rootContested_succeeds() public {
gameProxy.attack(0, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
}
/// @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
function test_resolve_challengeContested_succeeds() public {
gameProxy.attack(0, _dummyClaim());
gameProxy.defend(1, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(1);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
}
/// @dev Static unit test for the correctness of resolving a game with multiplayer moves.
function test_resolve_teamDeathmatch_succeeds() public {
gameProxy.attack(0, _dummyClaim());
gameProxy.attack(0, _dummyClaim());
gameProxy.defend(1, _dummyClaim());
gameProxy.defend(1, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(1);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
}
/// @dev Static unit test for the correctness of resolving a game that reaches max game depth.
function test_resolve_stepReached_succeeds() public {
Claim claim = _dummyClaim();
for (uint256 i; i < gameProxy.splitDepth(); i++) {
gameProxy.attack(i, claim);
}
claim = _changeClaimStatus(claim, VMStatuses.PANIC);
for (uint256 i = gameProxy.claimDataLen() - 1; i < gameProxy.maxGameDepth(); i++) {
gameProxy.attack(i, claim);
}
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// resolving claim at 8 isn't necessary
for (uint256 i = 8; i > 0; i--) {
gameProxy.resolveClaim(i - 1);
}
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
}
/// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame multiple times
function test_resolve_claimAlreadyResolved_reverts() public {
Claim claim = _dummyClaim();
gameProxy.attack(0, claim);
gameProxy.attack(1, claim);
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(1);
vm.expectRevert(ClaimAlreadyResolved.selector);
gameProxy.resolveClaim(1);
}
/// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame at max depth
function test_resolve_claimAtMaxDepthAlreadyResolved_reverts() public {
Claim claim = _dummyClaim();
for (uint256 i; i < gameProxy.splitDepth(); i++) {
gameProxy.attack(i, claim);
}
claim = _changeClaimStatus(claim, VMStatuses.PANIC);
for (uint256 i = gameProxy.claimDataLen() - 1; i < gameProxy.maxGameDepth(); i++) {
gameProxy.attack(i, claim);
}
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.expectRevert(ClaimAlreadyResolved.selector);
gameProxy.resolveClaim(8);
}
/// @dev Static unit test asserting that resolve reverts when attempting to resolve subgames out of order
function test_resolve_outOfOrderResolution_reverts() public {
gameProxy.attack(0, _dummyClaim());
gameProxy.attack(1, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.expectRevert(OutOfOrderResolution.selector);
gameProxy.resolveClaim(0);
}
/// @dev Tests that adding local data with an out of bounds identifier reverts.
function testFuzz_addLocalData_oob_reverts(uint256 _ident) public {
// Get a claim below the split depth so that we can add local data for an execution trace subgame.
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, _dummyClaim());
}
gameProxy.attack(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC));
// [1, 5] are valid local data identifiers.
if (_ident <= 5) _ident = 0;
vm.expectRevert(InvalidLocalIdent.selector);
gameProxy.addLocalData(_ident, 5, 0);
}
/// @dev Tests that local data is loaded into the preimage oracle correctly in the subgame
/// that is disputing the transition from `GENESIS -> GENESIS + 1`
function test_addLocalDataGenesisTransition_static_succeeds() public {
IPreimageOracle oracle = IPreimageOracle(address(gameProxy.vm().oracle()));
// Get a claim below the split depth so that we can add local data for an execution trace subgame.
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, Claim.wrap(bytes32(i)));
}
gameProxy.attack(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC));
// Expected start/disputed claims
bytes32 startingClaim = Hash.unwrap(gameProxy.genesisOutputRoot());
bytes32 disputedClaim = bytes32(uint256(3));
Position disputedPos = LibPosition.wrap(4, 0);
// Expected local data
bytes32[5] memory data =
[Hash.unwrap(gameProxy.l1Head()), startingClaim, disputedClaim, bytes32(0), bytes32(block.chainid << 0xC0)];
for (uint256 i = 1; i <= 5; i++) {
uint256 expectedLen = i > 3 ? 8 : 32;
bytes32 key = _getKey(i, keccak256(abi.encode(disputedClaim, disputedPos)));
gameProxy.addLocalData(i, 5, 0);
(bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0);
assertEq(dat >> 0xC0, bytes32(expectedLen));
// Account for the length prefix if i > 3 (the data stored
// at identifiers i <= 3 are 32 bytes long, so the expected
// length is already correct. If i > 3, the data is only 8
// bytes long, so the length prefix + the data is 16 bytes
// total.)
assertEq(datLen, expectedLen + (i > 3 ? 8 : 0));
gameProxy.addLocalData(i, 5, 8);
(dat, datLen) = oracle.readPreimage(key, 8);
assertEq(dat, data[i - 1]);
assertEq(datLen, expectedLen);
}
}
/// @dev Tests that local data is loaded into the preimage oracle correctly.
function test_addLocalDataMiddle_static_succeeds() public {
IPreimageOracle oracle = IPreimageOracle(address(gameProxy.vm().oracle()));
// Get a claim below the split depth so that we can add local data for an execution trace subgame.
for (uint256 i; i < 4; i++) {
gameProxy.attack(i, Claim.wrap(bytes32(i)));
}
gameProxy.defend(4, _changeClaimStatus(ROOT_CLAIM, VMStatuses.VALID));
// Expected start/disputed claims
bytes32 startingClaim = bytes32(uint256(3));
Position startingPos = LibPosition.wrap(4, 0);
bytes32 disputedClaim = bytes32(uint256(2));
Position disputedPos = LibPosition.wrap(3, 0);
// Expected local data
bytes32[5] memory data = [
Hash.unwrap(gameProxy.l1Head()),
startingClaim,
disputedClaim,
bytes32(uint256(1) << 0xC0),
bytes32(block.chainid << 0xC0)
];
for (uint256 i = 1; i <= 5; i++) {
uint256 expectedLen = i > 3 ? 8 : 32;
bytes32 key = _getKey(i, keccak256(abi.encode(startingClaim, startingPos, disputedClaim, disputedPos)));
gameProxy.addLocalData(i, 5, 0);
(bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0);
assertEq(dat >> 0xC0, bytes32(expectedLen));
// Account for the length prefix if i > 3 (the data stored
// at identifiers i <= 3 are 32 bytes long, so the expected
// length is already correct. If i > 3, the data is only 8
// bytes long, so the length prefix + the data is 16 bytes
// total.)
assertEq(datLen, expectedLen + (i > 3 ? 8 : 0));
gameProxy.addLocalData(i, 5, 8);
(dat, datLen) = oracle.readPreimage(key, 8);
assertEq(dat, data[i - 1]);
assertEq(datLen, expectedLen);
}
}
/// @dev Helper to return a pseudo-random claim
function _dummyClaim() internal view returns (Claim) {
return Claim.wrap(keccak256(abi.encode(gasleft())));
}
/// @dev Helper to get the localized key for an identifier in the context of the game proxy.
function _getKey(uint256 _ident, bytes32 _localContext) internal view returns (bytes32) {
bytes32 h = keccak256(abi.encode(_ident | (1 << 248), address(gameProxy), _localContext));
return bytes32((uint256(h) & ~uint256(0xFF << 248)) | (1 << 248));
}
}
contract OutputBisection_1v1_Actors_Test is OutputBisectionGame_Init {
/// @dev The honest actor
DisputeActor internal honest;
/// @dev The dishonest actor
DisputeActor internal dishonest;
function setUp() public override {
// Setup the `OutputBisectionGame`
super.setUp();
}
/// @notice Fuzz test for a 1v1 output bisection dispute.
/// @dev The alphabet game has a constant status byte, and is not safe from someone being dishonest in
/// output bisection and then posting a correct execution trace bisection root claim. This test
/// does not cover this case (i.e. root claim of output bisection is dishonest, root claim of
/// execution trace bisection is made by the dishonest actor but is honest, honest actor cannot
/// attack it without risk of losing).
function testFuzz_outputBisection1v1honestRoot_succeeds(uint8 _divergeOutput, uint8 _divergeStep) public {
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
uint256 divergeAtOutput = bound(_divergeOutput, 0, 15);
uint256 divergeAtStep = bound(_divergeStep, 0, 7);
uint256 divergeStepOffset = (divergeAtOutput << 4) + divergeAtStep;
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i >= divergeAtOutput ? 0xFF : i + 1;
}
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i >= divergeStepOffset ? bytes1(uint8(0xFF)) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1honestRootGenesisAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are from [2, 17] in this game.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i + 2;
}
// The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of all set bits.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = bytes1(0xFF);
}
// Run the actor test
_actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRootGenesisAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are from [2, 17] in this game.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i + 2;
}
// The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of all set bits.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = bytes1(0xFF);
}
// Run the actor test
_actorTest({
_rootClaim: 17,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1honestRoot_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are from [2, 17] in this game.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i + 2;
}
// The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of all zeros.
bytes memory dishonestTrace = new bytes(256);
// Run the actor test
_actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRoot_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are from [2, 17] in this game.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i + 2;
}
// The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of all zeros.
bytes memory dishonestTrace = new bytes(256);
// Run the actor test
_actorTest({
_rootClaim: 17,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1correctRootHalfWay_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 4) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRootHalfWay_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 4) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 0xFF,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1correctAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace correct is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestAbsolutePrestate_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace correct is half correct, half incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 0xFF,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1honestRootFinalInstruction_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, and correct all the way up to the final instruction of the exec
// subgame.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 7) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 16,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.DEFENDER_WINS
});
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestRootFinalInstruction_succeeds() public {
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, and correct all the way up to the final instruction of the exec
// subgame.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > (127 + 7) ? bytes1(0xFF) : bytes1(uint8(i));
}
// Run the actor test
_actorTest({
_rootClaim: 0xFF,
_absolutePrestateData: 0,
_honestTrace: honestTrace,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestL2Outputs: dishonestL2Outputs,
_expectedStatus: GameStatus.CHALLENGER_WINS
});
}
////////////////////////////////////////////////////////////////
// HELPERS //
////////////////////////////////////////////////////////////////
/// @dev Helper to run a 1v1 actor test
function _actorTest(
uint256 _rootClaim,
uint256 _absolutePrestateData,
bytes memory _honestTrace,
uint256[] memory _honestL2Outputs,
bytes memory _dishonestTrace,
uint256[] memory _dishonestL2Outputs,
GameStatus _expectedStatus
)
internal
{
// Setup the environment
bytes memory absolutePrestateData =
_setup({ _absolutePrestateData: _absolutePrestateData, _rootClaim: _rootClaim });
// Create actors
_createActors({
_honestTrace: _honestTrace,
_honestPreStateData: absolutePrestateData,
_honestL2Outputs: _honestL2Outputs,
_dishonestTrace: _dishonestTrace,
_dishonestPreStateData: absolutePrestateData,
_dishonestL2Outputs: _dishonestL2Outputs
});
// Exhaust all moves from both actors
_exhaustMoves();
// Resolve the game and assert that the defender won
_warpAndResolve();
assertEq(uint8(gameProxy.status()), uint8(_expectedStatus));
}
/// @dev Helper to setup the 1v1 test
function _setup(
uint256 _absolutePrestateData,
uint256 _rootClaim
)
internal
returns (bytes memory absolutePrestateData_)
{
absolutePrestateData_ = abi.encode(_absolutePrestateData);
Claim absolutePrestateExec =
_changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData_)), VMStatuses.UNFINISHED);
Claim rootClaim = Claim.wrap(bytes32(uint256(_rootClaim)));
super.init({
rootClaim: rootClaim,
absolutePrestate: absolutePrestateExec,
l2BlockNumber: _rootClaim,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
}
/// @dev Helper to create actors for the 1v1 dispute.
function _createActors(
bytes memory _honestTrace,
bytes memory _honestPreStateData,
uint256[] memory _honestL2Outputs,
bytes memory _dishonestTrace,
bytes memory _dishonestPreStateData,
uint256[] memory _dishonestL2Outputs
)
internal
{
honest = new HonestDisputeActor({
_gameProxy: gameProxy,
_l2Outputs: _honestL2Outputs,
_trace: _honestTrace,
_preStateData: _honestPreStateData
});
dishonest = new HonestDisputeActor({
_gameProxy: gameProxy,
_l2Outputs: _dishonestL2Outputs,
_trace: _dishonestTrace,
_preStateData: _dishonestPreStateData
});
vm.label(address(honest), "HonestActor");
vm.label(address(dishonest), "DishonestActor");
}
/// @dev Helper to exhaust all moves from both actors.
function _exhaustMoves() internal {
while (true) {
// Allow the dishonest actor to make their moves, and then the honest actor.
(uint256 numMovesA,) = dishonest.move();
(uint256 numMovesB, bool success) = honest.move();
require(success, "Honest actor's moves should always be successful");
// If both actors have run out of moves, we're done.
if (numMovesA == 0 && numMovesB == 0) break;
}
}
/// @dev Helper to warp past the chess clock and resolve all claims within the dispute game.
function _warpAndResolve() internal {
// Warp past the chess clock
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve all claims in reverse order. We allow `resolveClaim` calls to fail due to
// the check that prevents claims with no subgames attached from being passed to
// `resolveClaim`. There's also a check in `resolve` to ensure all children have been
// resolved before global resolution, which catches any unresolved subgames here.
for (uint256 i = gameProxy.claimDataLen(); i > 0; i--) {
(bool success,) = address(gameProxy).call(abi.encodeCall(gameProxy.resolveClaim, (i - 1)));
success;
}
gameProxy.resolve();
}
}
/// @dev Helper to change the VM status byte of a claim.
function _changeClaimStatus(Claim _claim, VMStatus _status) pure returns (Claim out_) {
assembly {
out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status))
}
}
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { PreimageOracle, PreimageKeyLib } from "src/cannon/PreimageOracle.sol";
import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeTypes.sol";
/// @title AlphabetVM /// @title AlphabetVM
/// @dev A mock VM for the purpose of testing the dispute game infrastructure. /// @dev A mock VM for the purpose of testing the dispute game infrastructure. Note that this only works
/// for games with an execution trace subgame max depth of 3 (8 instructions per subgame).
contract AlphabetVM is IBigStepper { contract AlphabetVM is IBigStepper {
Claim internal immutable ABSOLUTE_PRESTATE; Claim internal immutable ABSOLUTE_PRESTATE;
IPreimageOracle public oracle; IPreimageOracle public oracle;
...@@ -17,21 +18,35 @@ contract AlphabetVM is IBigStepper { ...@@ -17,21 +18,35 @@ contract AlphabetVM is IBigStepper {
} }
/// @inheritdoc IBigStepper /// @inheritdoc IBigStepper
function step(bytes calldata _stateData, bytes calldata, bytes32) external view returns (bytes32 postState_) { function step(
bytes calldata _stateData,
bytes calldata,
bytes32 _localContext
)
external
view
returns (bytes32 postState_)
{
uint256 traceIndex; uint256 traceIndex;
uint256 claim; uint256 claim;
if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) { if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) {
// If the state data is empty, then the absolute prestate is the claim. // If the state data is empty, then the absolute prestate is the claim.
traceIndex = 0; (bytes32 dat,) = oracle.readPreimage(
(claim) = abi.decode(_stateData, (uint256)); PreimageKeyLib.localizeIdent(LocalPreimageKey.STARTING_L2_BLOCK_NUMBER, _localContext), 0
);
uint256 startingL2BlockNumber = (uint256(dat) >> 128) & 0xFFFFFFFF;
traceIndex = startingL2BlockNumber << 4;
(uint256 absolutePrestateClaim) = abi.decode(_stateData, (uint256));
claim = absolutePrestateClaim + traceIndex;
} else { } else {
// Otherwise, decode the state data. // Otherwise, decode the state data.
(traceIndex, claim) = abi.decode(_stateData, (uint256, uint256)); (traceIndex, claim) = abi.decode(_stateData, (uint256, uint256));
traceIndex++; traceIndex++;
claim++;
} }
// STF: n -> n + 1 // STF: n -> n + 1
postState_ = keccak256(abi.encode(traceIndex, claim + 1)); postState_ = keccak256(abi.encode(traceIndex, claim));
assembly { assembly {
postState_ := or(and(postState_, not(shl(248, 0xFF))), shl(248, 1)) postState_ := or(and(postState_, not(shl(248, 0xFF))), shl(248, 1))
} }
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { PreimageOracle, PreimageKeyLib } from "src/cannon/PreimageOracle.sol";
import "src/libraries/DisputeTypes.sol";
/// @title AlphabetVM2
/// @dev A mock VM for the purpose of testing the dispute game infrastructure. Note that this only works
/// for games with an execution trace subgame max depth of 3 (8 instructions per subgame).
contract AlphabetVM2 is IBigStepper {
Claim internal immutable ABSOLUTE_PRESTATE;
IPreimageOracle public oracle;
constructor(Claim _absolutePrestate) {
ABSOLUTE_PRESTATE = _absolutePrestate;
oracle = new PreimageOracle();
}
/// @inheritdoc IBigStepper
function step(
bytes calldata _stateData,
bytes calldata,
bytes32 _localContext
)
external
view
returns (bytes32 postState_)
{
uint256 traceIndex;
uint256 claim;
if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) {
// If the state data is empty, then the absolute prestate is the claim.
(bytes32 dat,) = oracle.readPreimage(
PreimageKeyLib.localizeIdent(LocalPreimageKey.STARTING_L2_BLOCK_NUMBER, _localContext), 0
);
uint256 startingL2BlockNumber = (uint256(dat) >> 128) & 0xFFFFFFFF;
traceIndex = startingL2BlockNumber << 4;
(uint256 absolutePrestateClaim) = abi.decode(_stateData, (uint256));
claim = absolutePrestateClaim + traceIndex;
} else {
// Otherwise, decode the state data.
(traceIndex, claim) = abi.decode(_stateData, (uint256, uint256));
traceIndex++;
claim++;
}
// STF: n -> n + 1
postState_ = keccak256(abi.encode(traceIndex, claim));
assembly {
postState_ := or(and(postState_, not(shl(248, 0xFF))), shl(248, 1))
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment