Commit 380d8cf5 authored by smartcontracts's avatar smartcontracts Committed by GitHub

feat: introduce AnchorStateRegistry (#9835)

* feat: introduce AnchorStateRegistry

Introduces the AnchorStateRegistry used to hold anchor states for
different game types. Anchor states are updated automatically when
a game resolves.

* kontrol snapshot

---------
Co-authored-by: default avatarclabby <ben@clab.by>
parent dc2b7141
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -9,11 +9,11 @@ import (
"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)1015\"},{\"astId\":1001,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"resolvedAt\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1015\"},{\"astId\":1002,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"status\",\"offset\":16,\"slot\":\"0\",\"type\":\"t_enum(GameStatus)1009\"},{\"astId\":1003,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claimData\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_struct(ClaimData)1010_storage)dyn_storage\"},{\"astId\":1004,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"credit\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1005,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claims\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_mapping(t_userDefinedValueType(ClaimHash)1012,t_bool)\"},{\"astId\":1006,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgames\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\"},{\"astId\":1007,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgameAtRootResolved\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_bool\"},{\"astId\":1008,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"initialized\",\"offset\":1,\"slot\":\"5\",\"type\":\"t_bool\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(ClaimData)1010_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct IFaultDisputeGame.ClaimData[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(ClaimData)1010_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_enum(GameStatus)1009\":{\"encoding\":\"inplace\",\"label\":\"enum GameStatus\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"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)1012,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(ClaimHash =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(ClaimHash)1012\",\"value\":\"t_bool\"},\"t_struct(ClaimData)1010_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.ClaimData\",\"numberOfBytes\":\"160\"},\"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)1011\":{\"encoding\":\"inplace\",\"label\":\"Claim\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(ClaimHash)1012\":{\"encoding\":\"inplace\",\"label\":\"ClaimHash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Clock)1013\":{\"encoding\":\"inplace\",\"label\":\"Clock\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Position)1014\":{\"encoding\":\"inplace\",\"label\":\"Position\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Timestamp)1015\":{\"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)1018\"},{\"astId\":1001,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"resolvedAt\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1018\"},{\"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\":\"claimData\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\"},{\"astId\":1004,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"credit\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1005,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claims\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_mapping(t_userDefinedValueType(ClaimHash)1014,t_bool)\"},{\"astId\":1006,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgames\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\"},{\"astId\":1007,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgameAtRootResolved\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_bool\"},{\"astId\":1008,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"initialized\",\"offset\":1,\"slot\":\"5\",\"type\":\"t_bool\"},{\"astId\":1009,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"startingOutputRoot\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_struct(OutputRoot)1012_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"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_enum(GameStatus)1010\":{\"encoding\":\"inplace\",\"label\":\"enum GameStatus\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"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)1014,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(ClaimHash =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(ClaimHash)1014\",\"value\":\"t_bool\"},\"t_struct(ClaimData)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.ClaimData\",\"numberOfBytes\":\"160\"},\"t_struct(OutputRoot)1012_storage\":{\"encoding\":\"inplace\",\"label\":\"struct OutputRoot\",\"numberOfBytes\":\"64\"},\"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)1013\":{\"encoding\":\"inplace\",\"label\":\"Claim\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(ClaimHash)1014\":{\"encoding\":\"inplace\",\"label\":\"ClaimHash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Clock)1015\":{\"encoding\":\"inplace\",\"label\":\"Clock\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Hash)1016\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Position)1017\":{\"encoding\":\"inplace\",\"label\":\"Position\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Timestamp)1018\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}"
var FaultDisputeGameStorageLayout = new(solc.StorageLayout)
var FaultDisputeGameDeployedBin = "0x6080604052600436106101e75760003560e01c80638d450a951161010e578063d6ae3cd5116100a7578063f3f7214e11610079578063fa24f74311610061578063fa24f74314610790578063fa315aa9146107b4578063fdffbb28146107e757005b8063f3f7214e14610745578063f8f43ff61461077057005b8063d6ae3cd51461068c578063d8cc1a3c146106bf578063e1f0c376146106df578063ec5e63081461071257005b8063c55cd0c7116100e0578063c55cd0c7146105a1578063c6f0308c146105b4578063cf09e0d01461063e578063d5d44d801461065f57005b80638d450a95146104d0578063bbdc02db14610503578063bcef3b5514610544578063c395e1ca1461058157005b8063609d33341161018057806368800abf1161015257806368800abf146104405780638129fc1c146104735780638980e0cc1461047b5780638b85902b1461049057005b8063609d3334146103b857806360e27464146103cd578063632247ea146103ed5780636361506d1461040057005b806335fef567116101b957806335fef567146102c85780633a768463146102db5780633fc8cef31461032f57806354fd4d501461036257005b80630356fe3a146101f057806319effeb414610232578063200d2ed2146102785780632810e1d6146102b357005b366101ee57005b005b3480156101fc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561023e57600080fd5b5060005461025f9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610229565b34801561028457600080fd5b506000546102a690700100000000000000000000000000000000900460ff1681565b6040516102299190613e16565b3480156102bf57600080fd5b506102a66107fa565b6101ee6102d6366004613e57565b6109f7565b3480156102e757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610229565b34801561033b57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030a565b34801561036e57600080fd5b506103ab6040518060400160405280600581526020017f302e372e3100000000000000000000000000000000000000000000000000000081525081565b6040516102299190613ee4565b3480156103c457600080fd5b506103ab610a07565b3480156103d957600080fd5b506101ee6103e8366004613f19565b610a1a565b6101ee6103fb366004613f52565b610bc6565b34801561040c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561021f565b34801561044c57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b6101ee61143e565b34801561048757600080fd5b5060015461021f565b34801561049c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561021f565b3480156104dc57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b34801561050f57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610229565b34801561055057600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561021f565b34801561058d57600080fd5b5061021f61059c366004613f87565b611859565b6101ee6105af366004613e57565b611a43565b3480156105c057600080fd5b506105d46105cf366004613fb9565b611a4f565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610229565b34801561064a57600080fd5b5060005461025f9067ffffffffffffffff1681565b34801561066b57600080fd5b5061021f61067a366004613f19565b60026020526000908152604090205481565b34801561069857600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b3480156106cb57600080fd5b506101ee6106da36600461401b565b611ae6565b3480156106eb57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061025f565b34801561071e57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b34801561075157600080fd5b506040516fffffffffffffffffffffffffffffffff8152602001610229565b34801561077c57600080fd5b506101ee61078b3660046140a5565b61211b565b34801561079c57600080fd5b506107a5612595565b604051610229939291906140d1565b3480156107c057600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b6101ee6107f5366004613fb9565b6125f2565b600080600054700100000000000000000000000000000000900460ff16600281111561082857610828613de7565b1461085f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460ff1661089b576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660016000815481106108c7576108c76140ff565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614610902576001610905565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156109b6576109b6613de7565b0217905560028111156109cb576109cb613de7565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610a0382826000610bc6565b5050565b6060610a1560406020612a53565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812080549082905590819003610a7f576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b158015610b0f57600080fd5b505af1158015610b23573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610b81576040519150601f19603f3d011682016040523d82523d6000602084013e610b86565b606091505b5050905080610bc1576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60008054700100000000000000000000000000000000900460ff166002811115610bf257610bf2613de7565b14610c29576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610c3e57610c3e6140ff565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c0840152919350909190610d039083908690612aea16565b90506000610da3826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610de55750610de27f0000000000000000000000000000000000000000000000000000000000000000600261415d565b81145b8015610def575084155b15610e26576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610e80576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610eab7f0000000000000000000000000000000000000000000000000000000000000000600161415d565b8103610ebd57610ebd86888588612af2565b34610ec783611859565b1115610eff576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835160009063ffffffff90811614610f5f576001856000015163ffffffff1681548110610f2e57610f2e6140ff565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c0850151600090610f839067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642610fad610f76856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610fc1919061415d565b610fcb9190614175565b90507f000000000000000000000000000000000000000000000000000000000000000060011c677fffffffffffffff1667ffffffffffffffff8216111561103e576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526003602052604090205490915060ff16156110bc576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016003600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060016040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600460008c8152602001908152602001600020600180805490506113519190614175565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b1580156113e957600080fd5b505af11580156113fd573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a45050505050505050505050565b600554610100900460ff1615611480576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013511611537576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b606636111561154e5763c407e0256000526004601cfd5b6040805160e08101825263ffffffff808252600060208301818152328486019081526fffffffffffffffffffffffffffffffff34818116606088019081527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033560808901908152600160a08a0181815242861660c08c0190815282548084018455928a529a5160059092027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915594517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf787018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8860180549185167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216919091179055517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9850155915195518116700100000000000000000000000000000000029516949094177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa9091015583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b1580156117dc57600080fd5b505af11580156117f0573d6000803e3d6000fd5b50506000805467ffffffffffffffff42167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790555050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010017905550565b6000806118f8836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690507f000000000000000000000000000000000000000000000000000000000000000081111561195e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a80630bebc200600061197983836141bb565b9050670de0b6b3a764000060006119b0827f00000000000000000000000000000000000000000000000000000000000000006141cf565b905060006119ce6119c9670de0b6b3a7640000866141cf565b612cb3565b905060006119dc8484612f0e565b905060006119ea8383612f5d565b905060006119f782612f8b565b90506000611a1682611a11670de0b6b3a76400008f6141cf565b613173565b90506000611a248b83612f5d565b9050611a30818d6141cf565b9f9e505050505050505050505050505050565b610a0382826001610bc6565b60018181548110611a5f57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115611b1257611b12613de7565b14611b49576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018781548110611b5e57611b5e6140ff565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050611bbd7f0000000000000000000000000000000000000000000000000000000000000000600161415d565b611c59826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611c9a576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611d8957611ced7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000614175565b6001901b611d0c846fffffffffffffffffffffffffffffffff166131ad565b67ffffffffffffffff16611d20919061420c565b15611d5d57611d54611d4560016fffffffffffffffffffffffffffffffff8716614220565b865463ffffffff166000613253565b60030154611d7f565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611db3565b60038501549150611db0611d456fffffffffffffffffffffffffffffffff86166001614251565b90505b600882901b60088a8a604051611dca929190614285565b6040518091039020901b14611e0b576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e168c613337565b90506000611e25836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced3290611e9f908f908f908f908f908a906004016142de565b6020604051808303816000875af1158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee29190614318565b600485015491149150600090600290611f8d906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b612029896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6120339190614331565b61203d9190614352565b67ffffffffffffffff161590508115158103612085576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156120dc576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214757612147613de7565b1461217e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061218d86613366565b935093509350935060006121a385858585613793565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612212573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122369190614379565b90506001890361232e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84612292367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af1158015612304573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123289190614318565b5061258a565b6002890361235a5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489612292565b600389036123865773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487612292565b600489036124bf5760006123cc6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000000613852565b6123f6907f000000000000000000000000000000000000000000000000000000000000000061415d565b61240190600161415d565b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015612494573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b89190614318565b505061258a565b60058903612558576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122e5565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560606125eb610a07565b9050909192565b60008054700100000000000000000000000000000000900460ff16600281111561261e5761261e613de7565b14612655576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006001828154811061266a5761266a6140ff565b6000918252602082206005919091020160048101549092506126ac90700100000000000000000000000000000000900460401c67ffffffffffffffff16610f76565b60048301549091506000906126de90700100000000000000000000000000000000900467ffffffffffffffff16610f76565b6126e89042614331565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c166127228284614396565b67ffffffffffffffff1611612763576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600460205260409020805485158015612783575060055460ff165b156127ba576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801580156127c757508515155b1561282c578454640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156127fa5781612816565b600187015473ffffffffffffffffffffffffffffffffffffffff165b90506128228188613907565b5050505050505050565b60006fffffffffffffffffffffffffffffffff815b8381101561297257600085828154811061285d5761285d6140ff565b60009182526020808320909101548083526004909152604090912054909150156128b3576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600182815481106128c8576128c86140ff565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff16158015612921575060048101546fffffffffffffffffffffffffffffffff908116908516115b1561295f576001810154600482015473ffffffffffffffffffffffffffffffffffffffff90911695506fffffffffffffffffffffffffffffffff1693505b50508061296b906143b9565b9050612841565b506129ba73ffffffffffffffffffffffffffffffffffffffff83161561299857826129b4565b600188015473ffffffffffffffffffffffffffffffffffffffff165b88613907565b86547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416021787556000888152600460205260408120612a1691613dad565b8760000361282257600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050505050505050565b60606000612a8a84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900361415d565b90508267ffffffffffffffff1667ffffffffffffffff811115612aaf57612aaf6143f1565b6040519080825280601f01601f191660200182016040528015612ad9576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000612b116fffffffffffffffffffffffffffffffff84166001614251565b90506000612b2182866001613253565b9050600086901a8380612c145750612b5a60027f000000000000000000000000000000000000000000000000000000000000000061420c565b6004830154600290612bfe906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b612c089190614352565b67ffffffffffffffff16145b15612c6c5760ff811660011480612c2e575060ff81166002145b612c67576040517ff40239db0000000000000000000000000000000000000000000000000000000081526004810188905260240161152e565b612caa565b60ff811615612caa576040517ff40239db0000000000000000000000000000000000000000000000000000000081526004810188905260240161152e565b50505050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213612d1257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202612f4b57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215612f7b5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213612fb957919050565b680755bf798b4a1bf1e58212612fd75763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60006131a4670de0b6b3a76400008361318b86612cb3565b6131959190614420565b61319f91906144dc565b612f8b565b90505b92915050565b60008061323a837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261329c576132976fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000613a93565b6132b7565b6132b7856fffffffffffffffffffffffffffffffff16613c51565b9050600184815481106132cc576132cc6140ff565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461332f57815460018054909163ffffffff1690811061331a5761331a6140ff565b906000526020600020906005020191506132dd565b509392505050565b600080600080600061334886613366565b935093509350935061335c84848484613793565b9695505050505050565b6000806000806000859050600060018281548110613386576133866140ff565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000009061345d906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161349e576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000090613565906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1692508211156135e157825463ffffffff166135ab7f0000000000000000000000000000000000000000000000000000000000000000600161415d565b83036135b5578391505b600181815481106135c8576135c86140ff565b90600052602060002090600502019350809450506134a2565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff1661364a613635856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff16149050801561372f576000613682836fffffffffffffffffffffffffffffffff166131ad565b67ffffffffffffffff1611156136e55760006136bc6136b460016fffffffffffffffffffffffffffffffff8616614220565b896001613253565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506137099050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750613785565b60006137516136b46fffffffffffffffffffffffffffffffff85166001614251565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841681036137f95782826040516020016137dc9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b60405160208183030381529060405280519060200120905061384a565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b6000806138df847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101613977576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff841660009081526020919091526040812080548392906139ea90849061415d565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b158015613a7f57600080fd5b505af1158015612caa573d6000803e3d6000fd5b600081613b32846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611613b73576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613b7c83613c51565b905081613c1b826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16116131a7576131a4613c3883600161415d565b6fffffffffffffffffffffffffffffffff831690613cfd565b60008119600183011681613ce5827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080613d8a847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190613dcb9190613dce565b50565b5b80821115613de35760008155600101613dcf565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613e51577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215613e6a57600080fd5b50508035926020909101359150565b6000815180845260005b81811015613e9f57602081850181015186830182015201613e83565b81811115613eb1576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006131a46020830184613e79565b73ffffffffffffffffffffffffffffffffffffffff81168114613dcb57600080fd5b600060208284031215613f2b57600080fd5b8135613f3681613ef7565b9392505050565b80358015158114613f4d57600080fd5b919050565b600080600060608486031215613f6757600080fd5b8335925060208401359150613f7e60408501613f3d565b90509250925092565b600060208284031215613f9957600080fd5b81356fffffffffffffffffffffffffffffffff81168114613f3657600080fd5b600060208284031215613fcb57600080fd5b5035919050565b60008083601f840112613fe457600080fd5b50813567ffffffffffffffff811115613ffc57600080fd5b60208301915083602082850101111561401457600080fd5b9250929050565b6000806000806000806080878903121561403457600080fd5b8635955061404460208801613f3d565b9450604087013567ffffffffffffffff8082111561406157600080fd5b61406d8a838b01613fd2565b9096509450606089013591508082111561408657600080fd5b5061409389828a01613fd2565b979a9699509497509295939492505050565b6000806000606084860312156140ba57600080fd5b505081359360208301359350604090920135919050565b63ffffffff841681528260208201526060604082015260006140f66060830184613e79565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156141705761417061412e565b500190565b6000828210156141875761418761412e565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826141ca576141ca61418c565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156142075761420761412e565b500290565b60008261421b5761421b61418c565b500690565b60006fffffffffffffffffffffffffffffffff838116908316818110156142495761424961412e565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561427c5761427c61412e565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006142f2606083018789614295565b8281036020840152614305818688614295565b9150508260408301529695505050505050565b60006020828403121561432a57600080fd5b5051919050565b600067ffffffffffffffff838116908316818110156142495761424961412e565b600067ffffffffffffffff8084168061436d5761436d61418c565b92169190910692915050565b60006020828403121561438b57600080fd5b8151613f3681613ef7565b600067ffffffffffffffff80831681851680830382111561427c5761427c61412e565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036143ea576143ea61412e565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156144615761446161412e565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561449c5761449c61412e565b600087129250878205871284841616156144b8576144b861412e565b878505871281841616156144ce576144ce61412e565b505050929093029392505050565b6000826144eb576144eb61418c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561453f5761453f61412e565b50059056fea164736f6c634300080f000a"
var FaultDisputeGameDeployedBin = "0x6080604052600436106101ff5760003560e01c80638d450a951161010e578063d6ae3cd5116100a7578063f3f7214e11610079578063fa24f74311610061578063fa24f7431461079c578063fa315aa9146107c0578063fdffbb28146107f357005b8063f3f7214e14610751578063f8f43ff61461077c57005b8063d6ae3cd514610698578063d8cc1a3c146106cb578063e1f0c376146106eb578063ec5e63081461071e57005b8063c55cd0c7116100e0578063c55cd0c7146105ad578063c6f0308c146105c0578063cf09e0d01461064a578063d5d44d801461066b57005b80638d450a95146104dc578063bbdc02db1461050f578063bcef3b5514610550578063c395e1ca1461058d57005b806357da950e116101985780636361506d1161016a5780638129fc1c116101525780638129fc1c1461047f5780638980e0cc146104875780638b85902b1461049c57005b80636361506d1461042a57806370872aa51461046a57005b806357da950e146103b2578063609d3334146103e257806360e27464146103f7578063632247ea1461041757005b806335fef567116101d157806335fef567146102c25780633a768463146102d55780633fc8cef31461032957806354fd4d501461035c57005b806319effeb414610208578063200d2ed21461025357806325fc2ace1461028e5780632810e1d6146102ad57005b3661020657005b005b34801561021457600080fd5b506000546102359068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561025f57600080fd5b5060005461028190700100000000000000000000000000000000900460ff1681565b60405161024a9190613f78565b34801561029a57600080fd5b506006545b60405190815260200161024a565b3480156102b957600080fd5b50610281610806565b6102066102d0366004613fb9565b610a83565b3480156102e157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161024a565b34801561033557600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610304565b34801561036857600080fd5b506103a56040518060400160405280600581526020017f302e382e3100000000000000000000000000000000000000000000000000000081525081565b60405161024a9190614046565b3480156103be57600080fd5b506006546007546103cd919082565b6040805192835260208301919091520161024a565b3480156103ee57600080fd5b506103a5610a93565b34801561040357600080fd5b5061020661041236600461407b565b610aa6565b6102066104253660046140b4565b610c52565b34801561043657600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561029f565b34801561047657600080fd5b5060075461029f565b6102066114ca565b34801561049357600080fd5b5060015461029f565b3480156104a857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561029f565b3480156104e857600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b34801561051b57600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161024a565b34801561055c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561029f565b34801561059957600080fd5b5061029f6105a83660046140e9565b6119f6565b6102066105bb366004613fb9565b611be0565b3480156105cc57600080fd5b506105e06105db36600461411b565b611bec565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161024a565b34801561065657600080fd5b506000546102359067ffffffffffffffff1681565b34801561067757600080fd5b5061029f61068636600461407b565b60026020526000908152604090205481565b3480156106a457600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b3480156106d757600080fd5b506102066106e636600461417d565b611c83565b3480156106f757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610235565b34801561072a57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b34801561075d57600080fd5b506040516fffffffffffffffffffffffffffffffff815260200161024a565b34801561078857600080fd5b50610206610797366004614207565b6122b8565b3480156107a857600080fd5b506107b1612715565b60405161024a93929190614233565b3480156107cc57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b61020661080136600461411b565b612772565b600080600054700100000000000000000000000000000000900460ff16600281111561083457610834613f49565b1461086b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460ff166108a7576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660016000815481106108d3576108d3614261565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff161461090e576001610911565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156109c2576109c2613f49565b0217905560028111156109d7576109d7613f49565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a6857600080fd5b505af1158015610a7c573d6000803e3d6000fd5b5050505090565b610a8f82826000610c52565b5050565b6060610aa160406020612bd3565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812080549082905590819003610b0b576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b158015610b9b57600080fd5b505af1158015610baf573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610c0d576040519150601f19603f3d011682016040523d82523d6000602084013e610c12565b606091505b5050905080610c4d576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60008054700100000000000000000000000000000000900460ff166002811115610c7e57610c7e613f49565b14610cb5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610cca57610cca614261565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c0840152919350909190610d8f9083908690612c6a16565b90506000610e2f826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610e715750610e6e7f000000000000000000000000000000000000000000000000000000000000000060026142bf565b81145b8015610e7b575084155b15610eb2576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610f0c576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f377f000000000000000000000000000000000000000000000000000000000000000060016142bf565b8103610f4957610f4986888588612c72565b34610f53836119f6565b1115610f8b576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835160009063ffffffff90811614610feb576001856000015163ffffffff1681548110610fba57610fba614261565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c085015160009061100f9067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642611039611002856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff1661104d91906142bf565b61105791906142d7565b90507f000000000000000000000000000000000000000000000000000000000000000060011c677fffffffffffffff1667ffffffffffffffff821611156110ca576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526003602052604090205490915060ff1615611148576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016003600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060016040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600460008c8152602001908152602001600020600180805490506113dd91906142d7565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b15801561147557600080fd5b505af1158015611489573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a45050505050505050505050565b600554610100900460ff161561150c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690637258a807906024016040805180830381865afa1580156115c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e491906142ee565b909250905081611620576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082018252838152602001829052600683905560078290558190367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90030135116116d2576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b60663611156116e95763c407e0256000526004601cfd5b6040805160e08101825263ffffffff808252600060208301818152328486019081526fffffffffffffffffffffffffffffffff34818116606088019081527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033560808901908152600160a08a0181815242861660c08c0190815282548084018455928a529a5160059092027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915594517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf787018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8860180549185167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216919091179055517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9850155915195518116700100000000000000000000000000000000029516949094177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa9091015583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b15801561197757600080fd5b505af115801561198b573d6000803e3d6000fd5b50506000805467ffffffffffffffff42167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790555050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055505050565b600080611a95836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690507f0000000000000000000000000000000000000000000000000000000000000000811115611afb576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a80630bebc2006000611b168383614341565b9050670de0b6b3a76400006000611b4d827f0000000000000000000000000000000000000000000000000000000000000000614355565b90506000611b6b611b66670de0b6b3a764000086614355565b612e33565b90506000611b79848461308e565b90506000611b8783836130dd565b90506000611b948261310b565b90506000611bb382611bae670de0b6b3a76400008f614355565b6132f3565b90506000611bc18b836130dd565b9050611bcd818d614355565b9f9e505050505050505050505050505050565b610a8f82826001610c52565b60018181548110611bfc57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115611caf57611caf613f49565b14611ce6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018781548110611cfb57611cfb614261565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050611d5a7f000000000000000000000000000000000000000000000000000000000000000060016142bf565b611df6826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611e37576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611f2657611e8a7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006142d7565b6001901b611ea9846fffffffffffffffffffffffffffffffff1661332d565b67ffffffffffffffff16611ebd9190614392565b15611efa57611ef1611ee260016fffffffffffffffffffffffffffffffff87166143a6565b865463ffffffff1660006133d3565b60030154611f1c565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611f50565b60038501549150611f4d611ee26fffffffffffffffffffffffffffffffff861660016143d7565b90505b600882901b60088a8a604051611f6792919061440b565b6040518091039020901b14611fa8576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611fb38c6134b7565b90506000611fc2836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced329061203c908f908f908f908f908a90600401614464565b6020604051808303816000875af115801561205b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207f919061449e565b60048501549114915060009060029061212a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121c6896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121d091906144b7565b6121da91906144d8565b67ffffffffffffffff161590508115158103612222576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff1615612279576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156122e4576122e4613f49565b1461231b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061232a866134e6565b93509350935093506000612340858585856138f5565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d391906144ff565b9050600189036124cb5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461242f367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156124a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c5919061449e565b5061270a565b600289036124f75773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961242f565b600389036125235773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761242f565b6004890361263f5760006125696fffffffffffffffffffffffffffffffff85167f00000000000000000000000000000000000000000000000000000000000000006139b4565b60075461257691906142bf565b6125819060016142bf565b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015612614573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612638919061449e565b505061270a565b600589036126d8576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a401612482565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335606061276b610a93565b9050909192565b60008054700100000000000000000000000000000000900460ff16600281111561279e5761279e613f49565b146127d5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600182815481106127ea576127ea614261565b60009182526020822060059190910201600481015490925061282c90700100000000000000000000000000000000900460401c67ffffffffffffffff16611002565b600483015490915060009061285e90700100000000000000000000000000000000900467ffffffffffffffff16611002565b61286890426144b7565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c166128a2828461451c565b67ffffffffffffffff16116128e3576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600460205260409020805485158015612903575060055460ff165b1561293a576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015801561294757508515155b156129ac578454640100000000900473ffffffffffffffffffffffffffffffffffffffff166000811561297a5781612996565b600187015473ffffffffffffffffffffffffffffffffffffffff165b90506129a28188613a69565b5050505050505050565b60006fffffffffffffffffffffffffffffffff815b83811015612af25760008582815481106129dd576129dd614261565b6000918252602080832090910154808352600490915260409091205490915015612a33576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018281548110612a4857612a48614261565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff16158015612aa1575060048101546fffffffffffffffffffffffffffffffff908116908516115b15612adf576001810154600482015473ffffffffffffffffffffffffffffffffffffffff90911695506fffffffffffffffffffffffffffffffff1693505b505080612aeb9061453f565b90506129c1565b50612b3a73ffffffffffffffffffffffffffffffffffffffff831615612b185782612b34565b600188015473ffffffffffffffffffffffffffffffffffffffff165b88613a69565b86547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416021787556000888152600460205260408120612b9691613f0f565b876000036129a257600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050505050505050565b60606000612c0a84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036142bf565b90508267ffffffffffffffff1667ffffffffffffffff811115612c2f57612c2f614577565b6040519080825280601f01601f191660200182016040528015612c59576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000612c916fffffffffffffffffffffffffffffffff841660016143d7565b90506000612ca1828660016133d3565b9050600086901a8380612d945750612cda60027f0000000000000000000000000000000000000000000000000000000000000000614392565b6004830154600290612d7e906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b612d8891906144d8565b67ffffffffffffffff16145b15612dec5760ff811660011480612dae575060ff81166002145b612de7576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016116c9565b612e2a565b60ff811615612e2a576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016116c9565b50505050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213612e9257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a7640000021582026130cb57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156130fb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361313957919050565b680755bf798b4a1bf1e582126131575763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613324670de0b6b3a76400008361330b86612e33565b61331591906145a6565b61331f9190614662565b61310b565b90505b92915050565b6000806133ba837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261341c576134176fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000613bf5565b613437565b613437856fffffffffffffffffffffffffffffffff16613db3565b90506001848154811061344c5761344c614261565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146134af57815460018054909163ffffffff1690811061349a5761349a614261565b9060005260206000209060050201915061345d565b509392505050565b60008060008060006134c8866134e6565b93509350935093506134dc848484846138f5565b9695505050505050565b600080600080600085905060006001828154811061350657613506614261565b600091825260209091206004600590920201908101549091507f0000000000000000000000000000000000000000000000000000000000000000906135dd906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161361e576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f0000000000000000000000000000000000000000000000000000000000000000906136e5906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16925082111561376157825463ffffffff1661372b7f000000000000000000000000000000000000000000000000000000000000000060016142bf565b8303613735578391505b6001818154811061374857613748614261565b9060005260206000209060050201935080945050613622565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166137ca6137b5856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015613891576000613802836fffffffffffffffffffffffffffffffff1661332d565b67ffffffffffffffff16111561386557600061383c61383460016fffffffffffffffffffffffffffffffff86166143a6565b8960016133d3565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a5061386b9050565b6006549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff1697506138e7565b60006138b36138346fffffffffffffffffffffffffffffffff851660016143d7565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff8416810361395b57828260405160200161393e9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012090506139ac565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080613a41847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101613ad9576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff84166000908152602091909152604081208054839290613b4c9084906142bf565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b158015613be157600080fd5b505af1158015612e2a573d6000803e3d6000fd5b600081613c94846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611613cd5576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613cde83613db3565b905081613d7d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161332757613324613d9a8360016142bf565b6fffffffffffffffffffffffffffffffff831690613e5f565b60008119600183011681613e47827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080613eec847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190613f2d9190613f30565b50565b5b80821115613f455760008155600101613f31565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613fb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215613fcc57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561400157602081850181015186830182015201613fe5565b81811115614013576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006133246020830184613fdb565b73ffffffffffffffffffffffffffffffffffffffff81168114613f2d57600080fd5b60006020828403121561408d57600080fd5b813561409881614059565b9392505050565b803580151581146140af57600080fd5b919050565b6000806000606084860312156140c957600080fd5b83359250602084013591506140e06040850161409f565b90509250925092565b6000602082840312156140fb57600080fd5b81356fffffffffffffffffffffffffffffffff8116811461409857600080fd5b60006020828403121561412d57600080fd5b5035919050565b60008083601f84011261414657600080fd5b50813567ffffffffffffffff81111561415e57600080fd5b60208301915083602082850101111561417657600080fd5b9250929050565b6000806000806000806080878903121561419657600080fd5b863595506141a66020880161409f565b9450604087013567ffffffffffffffff808211156141c357600080fd5b6141cf8a838b01614134565b909650945060608901359150808211156141e857600080fd5b506141f589828a01614134565b979a9699509497509295939492505050565b60008060006060848603121561421c57600080fd5b505081359360208301359350604090920135919050565b63ffffffff841681528260208201526060604082015260006142586060830184613fdb565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156142d2576142d2614290565b500190565b6000828210156142e9576142e9614290565b500390565b6000806040838503121561430157600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261435057614350614312565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561438d5761438d614290565b500290565b6000826143a1576143a1614312565b500690565b60006fffffffffffffffffffffffffffffffff838116908316818110156143cf576143cf614290565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561440257614402614290565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60608152600061447860608301878961441b565b828103602084015261448b81868861441b565b9150508260408301529695505050505050565b6000602082840312156144b057600080fd5b5051919050565b600067ffffffffffffffff838116908316818110156143cf576143cf614290565b600067ffffffffffffffff808416806144f3576144f3614312565b92169190910692915050565b60006020828403121561451157600080fd5b815161409881614059565b600067ffffffffffffffff80831681851680830382111561440257614402614290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457057614570614290565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156145e7576145e7614290565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561462257614622614290565b6000871292508782058712848416161561463e5761463e614290565b8785058712818416161561465457614654614290565b505050929093029392505050565b60008261467157614671614312565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156146c5576146c5614290565b50059056fea164736f6c634300080f000a"
func init() {
......
......@@ -31,8 +31,8 @@ var (
methodStep = "step"
methodAddLocalData = "addLocalData"
methodVM = "vm"
methodGenesisBlockNumber = "genesisBlockNumber"
methodGenesisOutputRoot = "genesisOutputRoot"
methodStartingBlockNumber = "startingBlockNumber"
methodStartingRootHash = "startingRootHash"
methodSplitDepth = "splitDepth"
methodL2BlockNumber = "l2BlockNumber"
methodRequiredBond = "getRequiredBond"
......@@ -83,7 +83,7 @@ func (f *FaultDisputeGameContract) GetBalance(ctx context.Context, block rpcbloc
// and the post-state block (that the proposed output root is for).
func (f *FaultDisputeGameContract) GetBlockRange(ctx context.Context) (prestateBlock uint64, poststateBlock uint64, retErr error) {
results, err := f.multiCaller.Call(ctx, rpcblock.Latest,
f.contract.Call(methodGenesisBlockNumber),
f.contract.Call(methodStartingBlockNumber),
f.contract.Call(methodL2BlockNumber))
if err != nil {
retErr = fmt.Errorf("failed to retrieve game block range: %w", err)
......@@ -123,12 +123,12 @@ func (f *FaultDisputeGameContract) GetGameMetadata(ctx context.Context, block rp
return l1Head, l2BlockNumber, rootClaim, status, duration, nil
}
func (f *FaultDisputeGameContract) GetGenesisOutputRoot(ctx context.Context) (common.Hash, error) {
genesisOutputRoot, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGenesisOutputRoot))
func (f *FaultDisputeGameContract) GetStartingRootHash(ctx context.Context) (common.Hash, error) {
startingRootHash, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodStartingRootHash))
if err != nil {
return common.Hash{}, fmt.Errorf("failed to retrieve genesis output root: %w", err)
}
return genesisOutputRoot.GetHash(0), nil
return startingRootHash.GetHash(0), nil
}
func (f *FaultDisputeGameContract) GetSplitDepth(ctx context.Context) (types.Depth, error) {
......
......@@ -315,7 +315,7 @@ func TestGetBlockRange(t *testing.T) {
stubRpc, contract := setupFaultDisputeGameTest(t)
expectedStart := uint64(65)
expectedEnd := uint64(102)
stubRpc.SetResponse(fdgAddr, methodGenesisBlockNumber, rpcblock.Latest, nil, []interface{}{new(big.Int).SetUint64(expectedStart)})
stubRpc.SetResponse(fdgAddr, methodStartingBlockNumber, rpcblock.Latest, nil, []interface{}{new(big.Int).SetUint64(expectedStart)})
stubRpc.SetResponse(fdgAddr, methodL2BlockNumber, rpcblock.Latest, nil, []interface{}{new(big.Int).SetUint64(expectedEnd)})
start, end, err := contract.GetBlockRange(context.Background())
require.NoError(t, err)
......@@ -354,13 +354,13 @@ func TestGetGameMetadata(t *testing.T) {
require.Equal(t, expectedGameDuration, duration)
}
func TestGetGenesisOutputRoot(t *testing.T) {
func TestGetStartingRootHash(t *testing.T) {
stubRpc, contract := setupFaultDisputeGameTest(t)
expectedOutputRoot := common.HexToHash("0x1234")
stubRpc.SetResponse(fdgAddr, methodGenesisOutputRoot, rpcblock.Latest, nil, []interface{}{expectedOutputRoot})
genesisOutputRoot, err := contract.GetGenesisOutputRoot(context.Background())
stubRpc.SetResponse(fdgAddr, methodStartingRootHash, rpcblock.Latest, nil, []interface{}{expectedOutputRoot})
startingOutputRoot, err := contract.GetStartingRootHash(context.Background())
require.NoError(t, err)
require.Equal(t, expectedOutputRoot, genesisOutputRoot)
require.Equal(t, expectedOutputRoot, startingOutputRoot)
}
func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) {
......
......@@ -131,8 +131,8 @@ func registerAlphabet(
return accessor, nil
}
prestateValidator := NewPrestateValidator("alphabet", contract.GetAbsolutePrestateHash, alphabet.PrestateProvider)
genesisValidator := NewPrestateValidator("output root", contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, genesisValidator}, creator, l1HeaderSource, selective, claimants)
startingValidator := NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider)
return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, startingValidator}, creator, l1HeaderSource, selective, claimants)
}
err := registerOracle(ctx, oracles, gameFactory, caller, faultTypes.AlphabetGameType)
if err != nil {
......@@ -215,8 +215,8 @@ func registerCannon(
return accessor, nil
}
prestateValidator := NewPrestateValidator("cannon", contract.GetAbsolutePrestateHash, cannonPrestateProvider)
genesisValidator := NewPrestateValidator("output root", contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, genesisValidator}, creator, l1HeaderSource, selective, claimants)
startingValidator := NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider)
return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, startingValidator}, creator, l1HeaderSource, selective, claimants)
}
err := registerOracle(ctx, oracles, gameFactory, caller, gameType)
if err != nil {
......
......@@ -185,8 +185,8 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string
h.require.NoError(err)
callOpts := &bind.CallOpts{Context: ctx}
prestateBlock, err := game.GenesisBlockNumber(callOpts)
h.require.NoError(err, "Failed to load genesis block number")
prestateBlock, err := game.StartingBlockNumber(callOpts)
h.require.NoError(err, "Failed to load starting block number")
poststateBlock, err := game.L2BlockNumber(callOpts)
h.require.NoError(err, "Failed to load l2 block number")
splitDepth, err := game.SplitDepth(callOpts)
......@@ -251,8 +251,8 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri
h.require.NoError(err)
callOpts := &bind.CallOpts{Context: ctx}
prestateBlock, err := game.GenesisBlockNumber(callOpts)
h.require.NoError(err, "Failed to load genesis block number")
prestateBlock, err := game.StartingBlockNumber(callOpts)
h.require.NoError(err, "Failed to load starting block number")
poststateBlock, err := game.L2BlockNumber(callOpts)
h.require.NoError(err, "Failed to load l2 block number")
splitDepth, err := game.SplitDepth(callOpts)
......
......@@ -87,9 +87,9 @@ func (g *OutputGameHelper) L2BlockNum(ctx context.Context) uint64 {
return blockNum.Uint64()
}
func (g *OutputGameHelper) GenesisBlockNum(ctx context.Context) uint64 {
blockNum, err := g.game.GenesisBlockNumber(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "failed to load genesis block number")
func (g *OutputGameHelper) StartingBlockNum(ctx context.Context) uint64 {
blockNum, err := g.game.StartingBlockNumber(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "failed to load starting block number")
return blockNum.Uint64()
}
......
......@@ -8,4 +8,4 @@ GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (g
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92930)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68360)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 69013)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155556)
\ No newline at end of file
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155551)
\ No newline at end of file
......@@ -53,7 +53,7 @@
"faultGameMaxDepth": 50,
"faultGameMaxDuration": 2400,
"faultGameGenesisBlock": 0,
"faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameGenesisOutputRoot": "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
"faultGameSplitDepth": 14,
"faultGameWithdrawalDelay": 604800,
"preimageOracleMinProposalSize": 10000,
......
......@@ -47,7 +47,7 @@
"faultGameMaxDepth": 8,
"faultGameMaxDuration": 2400,
"faultGameGenesisBlock": 0,
"faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameGenesisOutputRoot": "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
"faultGameSplitDepth": 4,
"faultGameWithdrawalDelay": 604800,
"preimageOracleMinProposalSize": 10000,
......
# `FaultDisputeGame` Invariants
## FaultDisputeGame always returns all ETH on total resolution
**Test:** [`FaultDisputeGame.t.sol#L39`](../test/invariants/FaultDisputeGame.t.sol#L39)
**Test:** [`FaultDisputeGame.t.sol#L33`](../test/invariants/FaultDisputeGame.t.sol#L33)
The FaultDisputeGame contract should always return all ETH in the contract to the correct recipients upon resolution of all outstanding claims. There may never be any ETH left in the contract after a full resolution.
\ No newline at end of file
......@@ -34,6 +34,7 @@ import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol";
import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol";
import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol";
import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { MIPS } from "src/cannon/MIPS.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
......@@ -69,6 +70,7 @@ contract Deploy is Deployer {
/// to finally adopt PUSHN and get rid of stack too deep once and for all.
/// Someday we will look back and laugh about stack too deep, today is not that day.
struct FaultDisputeGameParams {
AnchorStateRegistry anchorStateRegistry;
DelayedWETH weth;
GameType gameType;
Claim absolutePrestate;
......@@ -144,6 +146,7 @@ contract Deploy is Deployer {
L2OutputOracle: mustGetAddress("L2OutputOracleProxy"),
DisputeGameFactory: mustGetAddress("DisputeGameFactoryProxy"),
DelayedWETH: mustGetAddress("DelayedWETHProxy"),
AnchorStateRegistry: mustGetAddress("AnchorStateRegistryProxy"),
OptimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: mustGetAddress("OptimismPortalProxy"),
OptimismPortal2: mustGetAddress("OptimismPortalProxy"),
......@@ -162,6 +165,7 @@ contract Deploy is Deployer {
L2OutputOracle: getAddress("L2OutputOracleProxy"),
DisputeGameFactory: getAddress("DisputeGameFactoryProxy"),
DelayedWETH: getAddress("DelayedWETHProxy"),
AnchorStateRegistry: getAddress("AnchorStateRegistryProxy"),
OptimismMintableERC20Factory: getAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: getAddress("OptimismPortalProxy"),
OptimismPortal2: getAddress("OptimismPortalProxy"),
......@@ -345,6 +349,7 @@ contract Deploy is Deployer {
deployERC1967Proxy("DisputeGameFactoryProxy");
deployERC1967Proxy("L2OutputOracleProxy");
deployERC1967Proxy("DelayedWETHProxy");
deployERC1967Proxy("AnchorStateRegistryProxy");
transferAddressManagerOwnership(); // to the ProxyAdmin
}
......@@ -366,6 +371,7 @@ contract Deploy is Deployer {
deployDelayedWETH();
deployPreimageOracle();
deployMips();
deployAnchorStateRegistry();
}
/// @notice Initialize all of the implementations
......@@ -379,6 +385,7 @@ contract Deploy is Deployer {
initializeL2OutputOracle();
initializeDisputeGameFactory();
initializeDelayedWETH();
initializeAnchorStateRegistry();
// Selectively initialize either the original OptimismPortal or the new OptimismPortal2. Since this will upgrade
// the proxy, we cannot initialize both. FPAC warning can be removed once we're done with the old OptimismPortal
......@@ -731,6 +738,17 @@ contract Deploy is Deployer {
addr_ = address(mips);
}
/// @notice Deploy the AnchorStateRegistry
function deployAnchorStateRegistry() public broadcast returns (address addr_) {
console.log("Deploying AnchorStateRegistry implementation");
AnchorStateRegistry anchorStateRegistry =
new AnchorStateRegistry{ salt: _implSalt() }(DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")));
save("AnchorStateRegistry", address(anchorStateRegistry));
console.log("AnchorStateRegistry deployed at %s", address(anchorStateRegistry));
addr_ = address(anchorStateRegistry);
}
/// @notice Deploy the SystemConfig
function deploySystemConfig() public broadcast returns (address addr_) {
console.log("Deploying SystemConfig implementation");
......@@ -869,6 +887,44 @@ contract Deploy is Deployer {
});
}
function initializeAnchorStateRegistry() public broadcast {
console.log("Upgrading and initializing AnchorStateRegistry proxy");
address anchorStateRegistryProxy = mustGetAddress("AnchorStateRegistryProxy");
address anchorStateRegistry = mustGetAddress("AnchorStateRegistry");
AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](3);
roots[0] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
l2BlockNumber: cfg.faultGameGenesisBlock()
})
});
roots[1] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
l2BlockNumber: cfg.faultGameGenesisBlock()
})
});
roots[2] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.ALPHABET,
outputRoot: OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
l2BlockNumber: cfg.faultGameGenesisBlock()
})
});
_upgradeAndCallViaSafe({
_proxy: payable(anchorStateRegistryProxy),
_implementation: anchorStateRegistry,
_innerCallData: abi.encodeCall(AnchorStateRegistry.initialize, (roots))
});
string memory version = AnchorStateRegistry(payable(anchorStateRegistryProxy)).version();
console.log("AnchorStateRegistry version: %s", version);
}
/// @notice Initialize the SystemConfig
function initializeSystemConfig() public broadcast {
console.log("Upgrading and initializing SystemConfig proxy");
......@@ -1222,6 +1278,7 @@ contract Deploy is Deployer {
_factory: factory,
_allowUpgrade: _allowUpgrade,
_params: FaultDisputeGameParams({
anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")),
weth: weth,
gameType: GameTypes.CANNON,
absolutePrestate: loadMipsAbsolutePrestate(),
......@@ -1242,6 +1299,7 @@ contract Deploy is Deployer {
_factory: factory,
_allowUpgrade: _allowUpgrade,
_params: FaultDisputeGameParams({
anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")),
weth: weth,
gameType: GameTypes.PERMISSIONED_CANNON,
absolutePrestate: loadMipsAbsolutePrestate(),
......@@ -1262,6 +1320,7 @@ contract Deploy is Deployer {
_factory: factory,
_allowUpgrade: _allowUpgrade,
_params: FaultDisputeGameParams({
anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")),
weth: weth,
gameType: GameTypes.ALPHABET,
absolutePrestate: outputAbsolutePrestate,
......@@ -1295,13 +1354,12 @@ contract Deploy is Deployer {
new FaultDisputeGame({
_gameType: _params.gameType,
_absolutePrestate: _params.absolutePrestate,
_genesisBlockNumber: cfg.faultGameGenesisBlock(),
_genesisOutputRoot: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
_maxGameDepth: _params.maxGameDepth,
_splitDepth: cfg.faultGameSplitDepth(),
_gameDuration: Duration.wrap(uint64(cfg.faultGameMaxDuration())),
_vm: _params.faultVm,
_weth: _params.weth,
_anchorStateRegistry: _params.anchorStateRegistry,
_l2ChainId: cfg.l2ChainID()
})
);
......@@ -1311,13 +1369,12 @@ contract Deploy is Deployer {
new PermissionedDisputeGame({
_gameType: _params.gameType,
_absolutePrestate: _params.absolutePrestate,
_genesisBlockNumber: cfg.faultGameGenesisBlock(),
_genesisOutputRoot: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
_maxGameDepth: _params.maxGameDepth,
_splitDepth: cfg.faultGameSplitDepth(),
_gameDuration: Duration.wrap(uint64(cfg.faultGameMaxDuration())),
_vm: _params.faultVm,
_weth: _params.weth,
_anchorStateRegistry: _params.anchorStateRegistry,
_l2ChainId: cfg.l2ChainID(),
_proposer: cfg.l2OutputOracleProposer(),
_challenger: cfg.l2OutputOracleChallenger()
......
......@@ -25,13 +25,7 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init {
function setUp() public override {
super.setUp();
super.init({
rootClaim: ROOT_CLAIM,
absolutePrestate: ABSOLUTE_PRESTATE,
l2BlockNumber: 0x10,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: ABSOLUTE_PRESTATE, l2BlockNumber: 0x10 });
}
/**
......
......@@ -9,6 +9,7 @@ library Types {
address L2OutputOracle;
address DisputeGameFactory;
address DelayedWETH;
address AnchorStateRegistry;
address OptimismMintableERC20Factory;
address OptimismPortal;
address OptimismPortal2;
......
......@@ -3,7 +3,9 @@ pragma solidity 0.8.15;
import { Proxy } from "src/universal/Proxy.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol";
import { StdAssertions } from "forge-std/StdAssertions.sol";
import "src/libraries/DisputeTypes.sol";
import "scripts/Deploy.s.sol";
/// @notice Deploys the Fault Proof Alpha Chad contracts.
......@@ -22,10 +24,12 @@ contract FPACOPS is Deploy, StdAssertions {
// Deploy the proxies.
deployERC1967Proxy("DisputeGameFactoryProxy");
deployERC1967Proxy("DelayedWETHProxy");
deployERC1967Proxy("AnchorStateRegistryProxy");
// Deploy implementations.
deployDisputeGameFactory();
deployDelayedWETH();
deployAnchorStateRegistry();
deployPreimageOracle();
deployMips();
......@@ -35,6 +39,7 @@ contract FPACOPS is Deploy, StdAssertions {
// Initialize the proxies.
initializeDisputeGameFactoryProxy();
initializeDelayedWETHProxy();
initializeAnchorStateRegistryProxy();
// Deploy the Cannon Fault game implementation and set it as game ID = 0.
setCannonFaultGameImplementation({ _allowUpgrade: false });
......@@ -78,6 +83,31 @@ contract FPACOPS is Deploy, StdAssertions {
);
}
function initializeAnchorStateRegistryProxy() internal broadcast {
console.log("Initializing AnchorStateRegistryProxy with AnchorStateRegistry.");
AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](3);
roots[0] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
l2BlockNumber: cfg.faultGameGenesisBlock()
})
});
roots[1] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
l2BlockNumber: cfg.faultGameGenesisBlock()
})
});
address asrProxy = mustGetAddress("AnchorStateRegistryProxy");
Proxy(payable(asrProxy)).upgradeToAndCall(
mustGetAddress("AnchorStateRegistry"), abi.encodeCall(AnchorStateRegistry.initialize, (roots))
);
}
/// @notice Transfers admin rights of the `DisputeGameFactoryProxy` to the `ProxyAdmin` and sets the
/// `DisputeGameFactory` owner to the `SystemOwnerSafe`.
function transferDGFOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast {
......@@ -137,8 +167,6 @@ contract FPACOPS is Deploy, StdAssertions {
assertEq(gameImpl.splitDepth(), cfg.faultGameSplitDepth());
assertEq(gameImpl.gameDuration().raw(), cfg.faultGameMaxDuration());
assertEq(gameImpl.absolutePrestate().raw(), bytes32(cfg.faultGameAbsolutePrestate()));
assertEq(gameImpl.genesisBlockNumber(), cfg.faultGameGenesisBlock());
assertEq(gameImpl.genesisOutputRoot().raw(), cfg.faultGameGenesisOutputRoot());
// Check the security override yoke configuration.
PermissionedDisputeGame soyGameImpl =
......@@ -147,8 +175,15 @@ contract FPACOPS is Deploy, StdAssertions {
assertEq(soyGameImpl.splitDepth(), cfg.faultGameSplitDepth());
assertEq(soyGameImpl.gameDuration().raw(), cfg.faultGameMaxDuration());
assertEq(soyGameImpl.absolutePrestate().raw(), bytes32(cfg.faultGameAbsolutePrestate()));
assertEq(soyGameImpl.genesisBlockNumber(), cfg.faultGameGenesisBlock());
assertEq(soyGameImpl.genesisOutputRoot().raw(), cfg.faultGameGenesisOutputRoot());
// Check the AnchorStateRegistry configuration.
AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistry"));
(Hash root1, uint256 l2BlockNumber1) = asr.anchors(GameTypes.CANNON);
(Hash root2, uint256 l2BlockNumber2) = asr.anchors(GameTypes.PERMISSIONED_CANNON);
assertEq(root1.raw(), cfg.faultGameGenesisOutputRoot());
assertEq(root2.raw(), cfg.faultGameGenesisOutputRoot());
assertEq(l2BlockNumber1, cfg.faultGameGenesisBlock());
assertEq(l2BlockNumber2, cfg.faultGameGenesisBlock());
}
/// @notice Prints a review of the fault proof configuration section of the deploy config.
......
......@@ -103,13 +103,17 @@
"initCodeHash": "0x9e0d25588d96934044c6f20b62b21444d734c85fe86b305efd8d226024e92725",
"sourceCodeHash": "0xa2d7d5a1de4159a41ff99c2f05d33b9b472c2d00ea62f817b372988f56650153"
},
"src/dispute/AnchorStateRegistry.sol": {
"initCodeHash": "0x2f8c56069e43e306b0e40fba43109188b29328e83569560021a68aa5d9f2486b",
"sourceCodeHash": "0xb6e67d68b801b7a110207b0c33802ea94cf26f9a7f3ebba78123d930a2eb0b2a"
},
"src/dispute/DisputeGameFactory.sol": {
"initCodeHash": "0x80d749a56c1776930fe0deb5c3c646217716e5875ace99c4d036af0452236476",
"sourceCodeHash": "0x1e5a6deded88804971fc1847c9eac65921771bff353437c0b29ed2f55513b984"
},
"src/dispute/FaultDisputeGame.sol": {
"initCodeHash": "0x9f8e47a4073639af201991a075c7eb03a73055750b3808281e7615b46d47a104",
"sourceCodeHash": "0xef3dee1a6dd89270b67c7e6a54862de9d11b9059cf053127bd26704e7e6b1fbf"
"initCodeHash": "0x9dcd4df1dd3e7a09dab46bfe1ebd9376f533cc533f9edce2f01aa754301e25aa",
"sourceCodeHash": "0xbe89df391f9cd4165389a7f6f65af752db13d0e508a1ec8430737aba5b7174dc"
},
"src/dispute/weth/DelayedWETH.sol": {
"initCodeHash": "0xf812f5a6de97162b48ccc847ff64c3be4ba575f1325d6e08fbf9dda91a7dc4c2",
......
[
{
"inputs": [
{
"internalType": "contract IDisputeGameFactory",
"name": "_disputeGameFactory",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "GameType",
"name": "",
"type": "uint32"
}
],
"name": "anchors",
"outputs": [
{
"internalType": "Hash",
"name": "root",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "l2BlockNumber",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "disputeGameFactory",
"outputs": [
{
"internalType": "contract IDisputeGameFactory",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "GameType",
"name": "gameType",
"type": "uint32"
},
{
"components": [
{
"internalType": "Hash",
"name": "root",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "l2BlockNumber",
"type": "uint256"
}
],
"internalType": "struct OutputRoot",
"name": "outputRoot",
"type": "tuple"
}
],
"internalType": "struct AnchorStateRegistry.StartingAnchorRoot[]",
"name": "_startingAnchorRoots",
"type": "tuple[]"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "tryUpdateAnchorState",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
}
]
\ No newline at end of file
......@@ -11,16 +11,6 @@
"name": "_absolutePrestate",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "_genesisBlockNumber",
"type": "uint256"
},
{
"internalType": "Hash",
"name": "_genesisOutputRoot",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "_maxGameDepth",
......@@ -46,6 +36,11 @@
"name": "_weth",
"type": "address"
},
{
"internalType": "contract IAnchorStateRegistry",
"name": "_anchorStateRegistry",
"type": "address"
},
{
"internalType": "uint256",
"name": "_l2ChainId",
......@@ -317,32 +312,6 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "genesisBlockNumber",
"outputs": [
{
"internalType": "uint256",
"name": "genesisBlockNumber_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "genesisOutputRoot",
"outputs": [
{
"internalType": "Hash",
"name": "genesisOutputRoot_",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
......@@ -509,6 +478,50 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "startingBlockNumber",
"outputs": [
{
"internalType": "uint256",
"name": "startingBlockNumber_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "startingOutputRoot",
"outputs": [
{
"internalType": "Hash",
"name": "root",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "l2BlockNumber",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "startingRootHash",
"outputs": [
{
"internalType": "Hash",
"name": "startingRootHash_",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "status",
......@@ -632,6 +645,11 @@
"name": "AlreadyInitialized",
"type": "error"
},
{
"inputs": [],
"name": "AnchorRootNotFound",
"type": "error"
},
{
"inputs": [],
"name": "BondTransferFailed",
......
......@@ -11,16 +11,6 @@
"name": "_absolutePrestate",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "_genesisBlockNumber",
"type": "uint256"
},
{
"internalType": "Hash",
"name": "_genesisOutputRoot",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "_maxGameDepth",
......@@ -46,6 +36,11 @@
"name": "_weth",
"type": "address"
},
{
"internalType": "contract IAnchorStateRegistry",
"name": "_anchorStateRegistry",
"type": "address"
},
{
"internalType": "uint256",
"name": "_l2ChainId",
......@@ -327,32 +322,6 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "genesisBlockNumber",
"outputs": [
{
"internalType": "uint256",
"name": "genesisBlockNumber_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "genesisOutputRoot",
"outputs": [
{
"internalType": "Hash",
"name": "genesisOutputRoot_",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
......@@ -519,6 +488,50 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "startingBlockNumber",
"outputs": [
{
"internalType": "uint256",
"name": "startingBlockNumber_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "startingOutputRoot",
"outputs": [
{
"internalType": "Hash",
"name": "root",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "l2BlockNumber",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "startingRootHash",
"outputs": [
{
"internalType": "Hash",
"name": "startingRootHash_",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "status",
......@@ -642,6 +655,11 @@
"name": "AlreadyInitialized",
"type": "error"
},
{
"inputs": [],
"name": "AnchorRootNotFound",
"type": "error"
},
{
"inputs": [],
"name": "BadAuth",
......
[
{
"bytes": "1",
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{
"bytes": "32",
"label": "anchors",
"offset": 0,
"slot": "1",
"type": "mapping(GameType => struct OutputRoot)"
}
]
\ No newline at end of file
......@@ -61,5 +61,12 @@
"offset": 1,
"slot": "5",
"type": "bool"
},
{
"bytes": "64",
"label": "startingOutputRoot",
"offset": 0,
"slot": "6",
"type": "struct OutputRoot"
}
]
\ No newline at end of file
......@@ -61,5 +61,12 @@
"offset": 1,
"slot": "5",
"type": "bool"
},
{
"bytes": "64",
"label": "startingOutputRoot",
"offset": 0,
"slot": "6",
"type": "struct OutputRoot"
}
]
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import { ISemver } from "src/universal/ISemver.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol";
import "src/libraries/DisputeTypes.sol";
contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver {
/// @notice Describes an initial anchor state for a game type.
struct StartingAnchorRoot {
GameType gameType;
OutputRoot outputRoot;
}
/// @notice Semantic version.
/// @custom:semver 0.1.0
string public constant version = "0.1.0";
/// @notice DisputeGameFactory address.
IDisputeGameFactory internal immutable DISPUTE_GAME_FACTORY;
/// @inheritdoc IAnchorStateRegistry
mapping(GameType => OutputRoot) public anchors;
/// @param _disputeGameFactory DisputeGameFactory address.
constructor(IDisputeGameFactory _disputeGameFactory) {
DISPUTE_GAME_FACTORY = _disputeGameFactory;
// Initialize the implementation with an empty array of starting anchor roots.
initialize(new StartingAnchorRoot[](0));
}
/// @notice Initializes the contract.
/// @param _startingAnchorRoots An array of starting anchor roots.
function initialize(StartingAnchorRoot[] memory _startingAnchorRoots) public initializer {
for (uint256 i = 0; i < _startingAnchorRoots.length; i++) {
StartingAnchorRoot memory startingAnchorRoot = _startingAnchorRoots[i];
anchors[startingAnchorRoot.gameType] = startingAnchorRoot.outputRoot;
}
}
/// @inheritdoc IAnchorStateRegistry
function disputeGameFactory() external view returns (IDisputeGameFactory) {
return DISPUTE_GAME_FACTORY;
}
/// @inheritdoc IAnchorStateRegistry
function tryUpdateAnchorState() external {
// Grab the game and game data.
IFaultDisputeGame game = IFaultDisputeGame(msg.sender);
(GameType gameType, Claim rootClaim, bytes memory extraData) = game.gameData();
// Grab the verified address of the game based on the game data.
// slither-disable-next-line unused-return
(IDisputeGame factoryRegisteredGame,) =
DISPUTE_GAME_FACTORY.games({ _gameType: gameType, _rootClaim: rootClaim, _extraData: extraData });
// Must be a valid game.
require(
address(factoryRegisteredGame) == address(game),
"AnchorStateRegistry: fault dispute game not registered with factory"
);
// No need to update anything if the anchor state is already newer.
if (game.l2BlockNumber() <= anchors[gameType].l2BlockNumber) {
return;
}
// Must be a game that resolved in favor of the state.
if (game.status() != GameStatus.DEFENDER_WINS) {
return;
}
// Actually update the anchor state.
anchors[gameType] = OutputRoot({ l2BlockNumber: game.l2BlockNumber(), root: Hash.wrap(game.rootClaim().raw()) });
}
}
......@@ -8,6 +8,7 @@ import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol";
import { IInitializable } from "src/dispute/interfaces/IInitializable.sol";
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
import { Clone } from "src/libraries/Clone.sol";
import { Types } from "src/libraries/Types.sol";
......@@ -41,18 +42,15 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
/// @notice An onchain VM that performs single instruction steps on a fault proof program trace.
IBigStepper internal immutable VM;
/// @notice The genesis block number.
uint256 internal immutable GENESIS_BLOCK_NUMBER;
/// @notice The genesis output root.
Hash internal immutable GENESIS_OUTPUT_ROOT;
/// @notice The game type ID.
GameType internal immutable GAME_TYPE;
/// @notice WETH contract for holding ETH.
IDelayedWETH internal immutable WETH;
/// @notice The anchor state registry.
IAnchorStateRegistry internal immutable ANCHOR_STATE_REGISTRY;
/// @notice The chain ID of the L2 network this contract argues about.
uint256 internal immutable L2_CHAIN_ID;
......@@ -89,30 +87,31 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
/// @notice Flag for the `initialize` function to prevent re-initialization.
bool internal initialized;
/// @notice The latest finalized output root, serving as the anchor for output bisection.
OutputRoot public startingOutputRoot;
/// @notice Semantic version.
/// @custom:semver 0.7.1
string public constant version = "0.7.1";
/// @custom:semver 0.8.1
string public constant version = "0.8.1";
/// @param _gameType The type ID of the game.
/// @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 _splitDepth The final depth of the output bisection portion of the game.
/// @param _gameDuration The duration of the game.
/// @param _vm An onchain VM that performs single instruction steps on an FPP trace.
/// @param _weth WETH contract for holding ETH.
/// @param _anchorStateRegistry The contract that stores the anchor state for each game type.
/// @param _l2ChainId Chain ID of the L2 network this contract argues about.
constructor(
GameType _gameType,
Claim _absolutePrestate,
uint256 _genesisBlockNumber,
Hash _genesisOutputRoot,
uint256 _maxGameDepth,
uint256 _splitDepth,
Duration _gameDuration,
IBigStepper _vm,
IDelayedWETH _weth,
IAnchorStateRegistry _anchorStateRegistry,
uint256 _l2ChainId
) {
// The split depth cannot be greater than or equal to the max game depth.
......@@ -120,13 +119,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
GAME_TYPE = _gameType;
ABSOLUTE_PRESTATE = _absolutePrestate;
GENESIS_BLOCK_NUMBER = _genesisBlockNumber;
GENESIS_OUTPUT_ROOT = _genesisOutputRoot;
MAX_GAME_DEPTH = _maxGameDepth;
SPLIT_DEPTH = _splitDepth;
GAME_DURATION = _gameDuration;
VM = _vm;
WETH = _weth;
ANCHOR_STATE_REGISTRY = _anchorStateRegistry;
L2_CHAIN_ID = _l2ChainId;
}
......@@ -352,8 +350,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// Load the disputed proposal's L2 block number as a big-endian uint64 in the
// high order 8 bytes of the word.
// We add the index at depth + 1 to the genesis block number to get the disputed L2 block number.
uint256 l2Number = GENESIS_BLOCK_NUMBER + disputedPos.traceIndex(SPLIT_DEPTH) + 1;
// We add the index at depth + 1 to the starting block number to get the disputed L2
// block number.
uint256 l2Number = startingOutputRoot.l2BlockNumber + disputedPos.traceIndex(SPLIT_DEPTH) + 1;
oracle.loadLocalData(_ident, uuid.raw(), bytes32(l2Number << 0xC0), 8, _partOffset);
} else if (_ident == LocalPreimageKey.CHAIN_ID) {
......@@ -395,7 +394,11 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
status_ = claimData[0].counteredBy == address(0) ? GameStatus.DEFENDER_WINS : GameStatus.CHALLENGER_WINS;
resolvedAt = Timestamp.wrap(uint64(block.timestamp));
// Update the status and emit the resolved event, note that we're performing an assignment here.
emit Resolved(status = status_);
// Try to update the anchor state, this should not revert.
ANCHOR_STATE_REGISTRY.tryUpdateAnchorState();
}
/// @inheritdoc IFaultDisputeGame
......@@ -492,6 +495,16 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
extraData_ = extraData();
}
/// @inheritdoc IFaultDisputeGame
function startingBlockNumber() external view returns (uint256 startingBlockNumber_) {
startingBlockNumber_ = startingOutputRoot.l2BlockNumber;
}
/// @inheritdoc IFaultDisputeGame
function startingRootHash() external view returns (Hash startingRootHash_) {
startingRootHash_ = startingOutputRoot.root;
}
////////////////////////////////////////////////////////////////
// MISC EXTERNAL //
////////////////////////////////////////////////////////////////
......@@ -507,14 +520,23 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
//
// Explicit checks:
// - The game must not have already been initialized.
// - An output root cannot be proposed at or before the genesis block.
// - An output root cannot be proposed at or before the starting block number.
// INVARIANT: The game must not have already been initialized.
if (initialized) revert AlreadyInitialized();
// Grab the latest anchor root.
(Hash root, uint256 rootBlockNumber) = ANCHOR_STATE_REGISTRY.anchors(GAME_TYPE);
// Should only happen if this is a new game type that hasn't been set up yet.
if (root.raw() == bytes32(0)) revert AnchorRootNotFound();
// Set the starting output root.
startingOutputRoot = OutputRoot({ l2BlockNumber: rootBlockNumber, root: root });
// Do not allow the game to be initialized if the root claim corresponds to a block at or before the
// configured genesis block number.
if (l2BlockNumber() <= GENESIS_BLOCK_NUMBER) revert UnexpectedRootClaim(rootClaim());
// configured starting block number.
if (l2BlockNumber() <= rootBlockNumber) revert UnexpectedRootClaim(rootClaim());
// 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,
......@@ -658,16 +680,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
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;
}
/// @notice Returns the WETH contract for holding ETH.
function weth() external view returns (IDelayedWETH weth_) {
weth_ = WETH;
......@@ -813,14 +825,14 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
// 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 this is an attack on the first output root (the block directly after the starting
// block number), 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(outputPos.raw() - 1), claimIdx, true);
(startingClaim_, startingPos_) = (starting.claim, starting.position);
} else {
startingClaim_ = Claim.wrap(GENESIS_OUTPUT_ROOT.raw());
startingClaim_ = Claim.wrap(startingOutputRoot.root.raw());
}
(disputedClaim_, disputedPos_) = (claim.claim, claim.position);
} else {
......
......@@ -2,6 +2,7 @@
pragma solidity 0.8.15;
import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
import { FaultDisputeGame, IFaultDisputeGame, IBigStepper, IInitializable } from "src/dispute/FaultDisputeGame.sol";
import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol";
......@@ -29,26 +30,24 @@ contract PermissionedDisputeGame is FaultDisputeGame {
/// @param _gameType The type ID of the game.
/// @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 _splitDepth The final depth of the output bisection portion of the game.
/// @param _gameDuration The duration of the game.
/// @param _vm An onchain VM that performs single instruction steps on an FPP trace.
/// @param _weth WETH contract for holding ETH.
/// @param _anchorStateRegistry The contract that stores the anchor state for each game type.
/// @param _l2ChainId Chain ID of the L2 network this contract argues about.
/// @param _proposer Address that is allowed to create instances of this contract.
/// @param _challenger Address that is allowed to challenge instances of this contract.
constructor(
GameType _gameType,
Claim _absolutePrestate,
uint256 _genesisBlockNumber,
Hash _genesisOutputRoot,
uint256 _maxGameDepth,
uint256 _splitDepth,
Duration _gameDuration,
IBigStepper _vm,
IDelayedWETH _weth,
IAnchorStateRegistry _anchorStateRegistry,
uint256 _l2ChainId,
address _proposer,
address _challenger
......@@ -56,13 +55,12 @@ contract PermissionedDisputeGame is FaultDisputeGame {
FaultDisputeGame(
_gameType,
_absolutePrestate,
_genesisBlockNumber,
_genesisOutputRoot,
_maxGameDepth,
_splitDepth,
_gameDuration,
_vm,
_weth,
_anchorStateRegistry,
_l2ChainId
)
{
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol";
import "src/libraries/DisputeTypes.sol";
/// @title IAnchorStateRegistry
/// @notice Describes a contract that stores the anchor state for each game type.
interface IAnchorStateRegistry {
/// @notice Returns the anchor state for the given game type.
/// @param _gameType The game type to get the anchor state for.
/// @return The anchor state for the given game type.
function anchors(GameType _gameType) external view returns (Hash, uint256);
/// @notice Returns the DisputeGameFactory address.
/// @return DisputeGameFactory address.
function disputeGameFactory() external view returns (IDisputeGameFactory);
/// @notice Callable by FaultDisputeGame contracts to update the anchor state. Pulls the anchor
/// state directly from the FaultDisputeGame contract and stores it in the registry if
/// the new anchor state is valid and the state is newer than the current anchor state.
function tryUpdateAnchorState() external;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.0;
import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.0;
import { IWETH } from "src/dispute/interfaces/IWETH.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.0;
import { IInitializable } from "src/dispute/interfaces/IInitializable.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.0;
import { IDisputeGame } from "./IDisputeGame.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.0;
import { IDisputeGame } from "./IDisputeGame.sol";
......@@ -67,4 +67,13 @@ interface IFaultDisputeGame is IDisputeGame {
/// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`.
function l2BlockNumber() external view returns (uint256 l2BlockNumber_);
/// @notice Starting output root and block number of the game.
function startingOutputRoot() external view returns (Hash startingRoot_, uint256 l2BlockNumber_);
/// @notice Only the starting block number of the game.
function startingBlockNumber() external view returns (uint256 startingBlockNumber_);
/// @notice Only the starting output root of the game.
function startingRootHash() external view returns (Hash startingRootHash_);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.0;
/// @title IInitializable
/// @notice An interface for initializable contracts.
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.0;
/// @title IWETH
/// @notice Interface for WETH9.
......
......@@ -95,6 +95,9 @@ error InvalidSplitDepth();
/// an instruction step.
error DuplicateStep();
/// @notice Thrown when an anchor root is not found for a given game type.
error AnchorRootNotFound();
////////////////////////////////////////////////////////////////
// `PermissionedDisputeGame` Errors //
////////////////////////////////////////////////////////////////
......
......@@ -89,6 +89,14 @@ enum GameStatus {
DEFENDER_WINS
}
/// @notice Represents an L2 output root and the L2 block number at which it was generated.
/// @custom:field root The output root.
/// @custom:field l2BlockNumber The L2 block number at which the output root was generated.
struct OutputRoot {
Hash root;
uint256 l2BlockNumber;
}
/// @title GameTypes
/// @notice A library that defines the IDs of games that can be played.
library GameTypes {
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol";
import { Test } from "forge-std/Test.sol";
import { FaultDisputeGame_Init, _changeClaimStatus } from "test/dispute/FaultDisputeGame.t.sol";
contract AnchorStateRegistry_Init is FaultDisputeGame_Init {
function setUp() public virtual override {
// Duplicating the initialization/setup logic of FaultDisputeGame_Test.
// See that test for more information, actual values here not really important.
Claim rootClaim = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10)));
bytes memory absolutePrestateData = abi.encode(0);
Claim absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED);
super.setUp();
super.init({ rootClaim: rootClaim, absolutePrestate: absolutePrestate, l2BlockNumber: 0x10 });
}
}
contract AnchorStateRegistry_Initialize_Test is AnchorStateRegistry_Init {
/// @dev Tests that initialization is successful.
function test_initialize_succeeds() public {
(Hash cannonRoot, uint256 cannonL2BlockNumber) = anchorStateRegistry.anchors(GameTypes.CANNON);
(Hash permissionedCannonRoot, uint256 permissionedCannonL2BlockNumber) =
anchorStateRegistry.anchors(GameTypes.PERMISSIONED_CANNON);
(Hash alphabetRoot, uint256 alphabetL2BlockNumber) = anchorStateRegistry.anchors(GameTypes.ALPHABET);
assertEq(cannonRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF);
assertEq(cannonL2BlockNumber, 0);
assertEq(permissionedCannonRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF);
assertEq(permissionedCannonL2BlockNumber, 0);
assertEq(alphabetRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF);
assertEq(alphabetL2BlockNumber, 0);
}
}
contract AnchorStateRegistry_TryUpdateAnchorState_Test is AnchorStateRegistry_Init {
/// @dev Tests that updating the anchor state succeeds when the game state is valid and newer.
function test_tryUpdateAnchorState_validNewerState_succeeds() public {
// Confirm that the anchor state is older than the game state.
(Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assert(l2BlockNumber < gameProxy.l2BlockNumber());
// Mock the state that we want.
vm.mockCall(
address(gameProxy), abi.encodeWithSelector(gameProxy.status.selector), abi.encode(GameStatus.DEFENDER_WINS)
);
// Try to update the anchor state.
vm.prank(address(gameProxy));
anchorStateRegistry.tryUpdateAnchorState();
// Confirm that the anchor state is now the same as the game state.
(root, l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assertEq(l2BlockNumber, gameProxy.l2BlockNumber());
assertEq(root.raw(), gameProxy.rootClaim().raw());
}
/// @dev Tests that updating the anchor state fails when the game state is valid but older.
function test_tryUpdateAnchorState_validOlderState_fails() public {
// Confirm that the anchor state is newer than the game state.
vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0));
(Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assert(l2BlockNumber >= gameProxy.l2BlockNumber());
// Mock the state that we want.
vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0));
vm.mockCall(
address(gameProxy), abi.encodeWithSelector(gameProxy.status.selector), abi.encode(GameStatus.DEFENDER_WINS)
);
// Try to update the anchor state.
vm.prank(address(gameProxy));
anchorStateRegistry.tryUpdateAnchorState();
// Confirm that the anchor state has not updated.
(Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assertEq(updatedL2BlockNumber, l2BlockNumber);
assertEq(updatedRoot.raw(), root.raw());
}
/// @dev Tests that updating the anchor state fails when the game state is invalid.
function test_tryUpdateAnchorState_invalidNewerState_fails() public {
// Confirm that the anchor state is older than the game state.
(Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assert(l2BlockNumber < gameProxy.l2BlockNumber());
// Mock the state that we want.
vm.mockCall(
address(gameProxy),
abi.encodeWithSelector(gameProxy.status.selector),
abi.encode(GameStatus.CHALLENGER_WINS)
);
// Try to update the anchor state.
vm.prank(address(gameProxy));
anchorStateRegistry.tryUpdateAnchorState();
// Confirm that the anchor state has not updated.
(Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assertEq(updatedL2BlockNumber, l2BlockNumber);
assertEq(updatedRoot.raw(), root.raw());
}
/// @dev Tests that updating the anchor state fails when the game is not registered with the factory.
function test_tryUpdateAnchorState_invalidGame_fails() public {
// Confirm that the anchor state is older than the game state.
(Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assert(l2BlockNumber < gameProxy.l2BlockNumber());
// Mock the state that we want.
vm.mockCall(
address(disputeGameFactory),
abi.encodeWithSelector(
disputeGameFactory.games.selector, gameProxy.gameType(), gameProxy.rootClaim(), gameProxy.extraData()
),
abi.encode(address(0), 0)
);
// Try to update the anchor state.
vm.prank(address(gameProxy));
vm.expectRevert("AnchorStateRegistry: fault dispute game not registered with factory");
anchorStateRegistry.tryUpdateAnchorState();
// Confirm that the anchor state has not updated.
(Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assertEq(updatedL2BlockNumber, l2BlockNumber);
assertEq(updatedRoot.raw(), root.raw());
}
}
......@@ -14,6 +14,7 @@ import "src/libraries/DisputeErrors.sol";
import { LibClock } from "src/dispute/lib/LibUDT.sol";
import { LibPosition } from "src/dispute/lib/LibPosition.sol";
import { IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
import { AlphabetVM } from "test/mocks/AlphabetVM.sol";
import { DisputeActor, HonestDisputeActor } from "test/actors/FaultDisputeActors.sol";
......@@ -32,15 +33,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
function init(
Claim rootClaim,
Claim absolutePrestate,
uint256 l2BlockNumber,
uint256 genesisBlockNumber,
Hash genesisOutputRoot
)
public
{
function init(Claim rootClaim, Claim absolutePrestate, uint256 l2BlockNumber) public {
// Set the time to a realistic date.
vm.warp(1690906994);
......@@ -53,15 +46,15 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
gameImpl = new FaultDisputeGame({
_gameType: GAME_TYPE,
_absolutePrestate: absolutePrestate,
_genesisBlockNumber: genesisBlockNumber,
_genesisOutputRoot: genesisOutputRoot,
_maxGameDepth: 2 ** 3,
_splitDepth: 2 ** 2,
_gameDuration: Duration.wrap(7 days),
_vm: _vm,
_weth: delayedWeth,
_anchorStateRegistry: anchorStateRegistry,
_l2ChainId: 10
});
// Register the game implementation with the factory.
disputeGameFactory.setImplementation(GAME_TYPE, gameImpl);
// Create a new game.
......@@ -70,8 +63,6 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
// Check immutables
assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw());
assertEq(gameProxy.absolutePrestate().raw(), absolutePrestate.raw());
assertEq(gameProxy.genesisBlockNumber(), genesisBlockNumber);
assertEq(gameProxy.genesisOutputRoot().raw(), genesisOutputRoot.raw());
assertEq(gameProxy.maxGameDepth(), 2 ** 3);
assertEq(gameProxy.splitDepth(), 2 ** 2);
assertEq(gameProxy.gameDuration().raw(), 7 days);
......@@ -103,13 +94,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED);
super.setUp();
super.init({
rootClaim: ROOT_CLAIM,
absolutePrestate: absolutePrestate,
l2BlockNumber: 0x10,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: absolutePrestate, l2BlockNumber: 0x10 });
}
////////////////////////////////////////////////////////////////
......@@ -128,13 +113,12 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
new FaultDisputeGame({
_gameType: GAME_TYPE,
_absolutePrestate: absolutePrestate,
_genesisBlockNumber: 0,
_genesisOutputRoot: Hash.wrap(bytes32(0)),
_maxGameDepth: 2 ** 3,
_splitDepth: _splitDepth,
_gameDuration: Duration.wrap(7 days),
_vm: alphabetVM,
_weth: DelayedWETH(payable(address(0))),
_anchorStateRegistry: IAnchorStateRegistry(address(0)),
_l2ChainId: 10
});
}
......@@ -172,10 +156,11 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// `IFaultDisputeGame` Implementation Tests //
////////////////////////////////////////////////////////////////
/// @dev Tests that the game cannot be initialized with an output root that commits to <= the configured genesis
/// @dev Tests that the game cannot be initialized with an output root that commits to <= the configured starting
/// block number
function testFuzz_initialize_cannotProposeGenesis_reverts(uint256 _blockNumber) public {
_blockNumber = bound(_blockNumber, 0, gameProxy.genesisBlockNumber());
(, uint256 startingL2Block) = gameProxy.startingOutputRoot();
_blockNumber = bound(_blockNumber, 0, startingL2Block);
Claim claim = _dummyClaim();
vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, claim));
......@@ -207,10 +192,10 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
_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();
// Assign the first 32 bytes in `extraData` to a valid L2 block number passed the starting block.
(, uint256 startingL2Block) = gameProxy.startingOutputRoot();
assembly {
mstore(add(_extraData, 0x20), add(genesisBlockNumber, 1))
mstore(add(_extraData, 0x20), add(startingL2Block, 1))
}
Claim claim = _dummyClaim();
......@@ -836,6 +821,65 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(disputeGameFactory.initBonds(GAME_TYPE), 0);
}
/// @dev Static unit test asserting that the anchor state updates when the game resolves in
/// favor of the defender and the anchor state is older than the game state.
function test_resolve_validNewerStateUpdatesAnchor_succeeds() public {
// Confirm that the anchor state is older than the game state.
(Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assert(l2BlockNumber < gameProxy.l2BlockNumber());
// Resolve the game.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
// Confirm that the anchor state is now the same as the game state.
(root, l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assertEq(l2BlockNumber, gameProxy.l2BlockNumber());
assertEq(root.raw(), gameProxy.rootClaim().raw());
}
/// @dev Static unit test asserting that the anchor state does not change when the game
/// resolves in favor of the defender but the game state is not newer than the anchor state.
function test_resolve_validOlderStateSameAnchor_succeeds() public {
// Mock the game block to be older than the game state.
vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0));
// Confirm that the anchor state is newer than the game state.
(Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assert(l2BlockNumber >= gameProxy.l2BlockNumber());
// Resolve the game.
vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
// Confirm that the anchor state is the same as the initial anchor state.
(Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assertEq(updatedL2BlockNumber, l2BlockNumber);
assertEq(updatedRoot.raw(), root.raw());
}
/// @dev Static unit test asserting that the anchor state does not change when the game
/// resolves in favor of the challenger, even if the game state is newer than the anchor.
function test_resolve_invalidStateSameAnchor_succeeds() public {
// Confirm that the anchor state is older than the game state.
(Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assert(l2BlockNumber < gameProxy.l2BlockNumber());
// Challenge the claim and resolve it.
gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim());
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
// Confirm that the anchor state is the same as the initial anchor state.
(Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
assertEq(updatedL2BlockNumber, l2BlockNumber);
assertEq(updatedRoot.raw(), root.raw());
}
/// @dev Static unit test asserting that credit may not be drained past allowance through reentrancy.
function test_claimCredit_claimAlreadyResolved_reverts() public {
ClaimCreditReenter reenter = new ClaimCreditReenter(gameProxy, vm);
......@@ -912,7 +956,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack{ value: MIN_BOND }(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC));
// Expected start/disputed claims
bytes32 startingClaim = gameProxy.genesisOutputRoot().raw();
(Hash root,) = gameProxy.startingOutputRoot();
bytes32 startingClaim = root.raw();
bytes32 disputedClaim = bytes32(uint256(3));
Position disputedPos = LibPosition.wrap(4, 0);
......@@ -1476,13 +1521,7 @@ contract FaultDispute_1v1_Actors_Test is FaultDisputeGame_Init {
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))
});
super.init({ rootClaim: rootClaim, absolutePrestate: absolutePrestateExec, l2BlockNumber: _rootClaim });
}
/// @dev Helper to create actors for the 1v1 dispute.
......
......@@ -39,15 +39,7 @@ contract PermissionedDisputeGame_Init is DisputeGameFactory_Init {
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
function init(
Claim rootClaim,
Claim absolutePrestate,
uint256 l2BlockNumber,
uint256 genesisBlockNumber,
Hash genesisOutputRoot
)
public
{
function init(Claim rootClaim, Claim absolutePrestate, uint256 l2BlockNumber) public {
// Set the time to a realistic date.
vm.warp(1690906994);
......@@ -63,13 +55,12 @@ contract PermissionedDisputeGame_Init is DisputeGameFactory_Init {
gameImpl = new PermissionedDisputeGame({
_gameType: GAME_TYPE,
_absolutePrestate: absolutePrestate,
_genesisBlockNumber: genesisBlockNumber,
_genesisOutputRoot: genesisOutputRoot,
_maxGameDepth: 2 ** 3,
_splitDepth: 2 ** 2,
_gameDuration: Duration.wrap(7 days),
_vm: _vm,
_weth: _weth,
_anchorStateRegistry: anchorStateRegistry,
_l2ChainId: 10,
_proposer: PROPOSER,
_challenger: CHALLENGER
......@@ -84,8 +75,6 @@ contract PermissionedDisputeGame_Init is DisputeGameFactory_Init {
// Check immutables
assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw());
assertEq(gameProxy.absolutePrestate().raw(), absolutePrestate.raw());
assertEq(gameProxy.genesisBlockNumber(), genesisBlockNumber);
assertEq(gameProxy.genesisOutputRoot().raw(), genesisOutputRoot.raw());
assertEq(gameProxy.maxGameDepth(), 2 ** 3);
assertEq(gameProxy.splitDepth(), 2 ** 2);
assertEq(gameProxy.gameDuration().raw(), 7 days);
......@@ -116,13 +105,7 @@ contract PermissionedDisputeGame_Test is PermissionedDisputeGame_Init {
absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED);
super.setUp();
super.init({
rootClaim: ROOT_CLAIM,
absolutePrestate: absolutePrestate,
l2BlockNumber: 0x10,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: absolutePrestate, l2BlockNumber: 0x10 });
}
/// @dev Tests that the proposer can create a permissioned dispute game.
......
......@@ -18,13 +18,7 @@ contract FaultDisputeGame_Solvency_Invariant is FaultDisputeGame_Init {
function setUp() public override {
super.setUp();
super.init({
rootClaim: ROOT_CLAIM,
absolutePrestate: ABSOLUTE_PRESTATE,
l2BlockNumber: 0x10,
genesisBlockNumber: 0,
genesisOutputRoot: Hash.wrap(bytes32(0))
});
super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: ABSOLUTE_PRESTATE, l2BlockNumber: 0x10 });
actor = new RandomClaimActor(gameProxy, vm);
......
......@@ -20,6 +20,7 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol";
import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { DeployConfig } from "scripts/DeployConfig.s.sol";
import { Deploy } from "scripts/Deploy.s.sol";
......@@ -62,6 +63,7 @@ contract Setup {
ProtocolVersions protocolVersions;
SuperchainConfig superchainConfig;
DataAvailabilityChallenge dataAvailabilityChallenge;
AnchorStateRegistry anchorStateRegistry;
L2CrossDomainMessenger l2CrossDomainMessenger =
L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER));
......@@ -114,6 +116,7 @@ contract Setup {
OptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"));
protocolVersions = ProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy"));
superchainConfig = SuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy"));
anchorStateRegistry = AnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy"));
vm.label(address(l2OutputOracle), "L2OutputOracle");
vm.label(deploy.mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy");
......
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