Commit efea631c authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #5939 from ethereum-optimism/feat/pops-cleanup

feat(ctb): Pull in relevant PoPs work
parents daaf917b 0a9342d5
...@@ -31,7 +31,7 @@ var ( ...@@ -31,7 +31,7 @@ var (
// DisputeGameFactoryMetaData contains all meta data concerning the DisputeGameFactory contract. // DisputeGameFactoryMetaData contains all meta data concerning the DisputeGameFactory contract.
var DisputeGameFactoryMetaData = &bind.MetaData{ var DisputeGameFactoryMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"Hash\",\"name\":\"uuid\",\"type\":\"bytes32\"}],\"name\":\"GameAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"}],\"name\":\"NoImplementation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"disputeProxy\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"}],\"name\":\"DisputeGameCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"impl\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"}],\"name\":\"ImplementationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"create\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"\",\"type\":\"uint8\"}],\"name\":\"gameImpls\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"games\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"_proxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"getGameUUID\",\"outputs\":[{\"internalType\":\"Hash\",\"name\":\"_uuid\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"contractIDisputeGame\",\"name\":\"impl\",\"type\":\"address\"}],\"name\":\"setImplementation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"Hash\",\"name\":\"uuid\",\"type\":\"bytes32\"}],\"name\":\"GameAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"}],\"name\":\"NoImplementation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"disputeProxy\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"}],\"name\":\"DisputeGameCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"impl\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"}],\"name\":\"ImplementationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"create\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"\",\"type\":\"uint8\"}],\"name\":\"gameImpls\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"games\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"_proxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"getGameUUID\",\"outputs\":[{\"internalType\":\"Hash\",\"name\":\"_uuid\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumGameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"internalType\":\"contractIDisputeGame\",\"name\":\"impl\",\"type\":\"address\"}],\"name\":\"setImplementation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: "0x608060405234801561001057600080fd5b50604051610d90380380610d9083398101604081905261002f91610171565b61003833610047565b61004181610097565b506101a1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61009f610115565b6001600160a01b0381166101095760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61011281610047565b50565b6000546001600160a01b0316331461016f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610100565b565b60006020828403121561018357600080fd5b81516001600160a01b038116811461019a57600080fd5b9392505050565b610be0806101b06000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b14610194578063c49d5271146101b2578063dfa162d3146101c5578063f2fde38b146101fb57600080fd5b806326daafbe1461008d5780633142e55e1461013f57806345583b7a14610177578063715018a61461018c575b600080fd5b61012c61009b366004610941565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0830180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086018051988652968352606087529451609f0190941683209190925291905291905290565b6040519081526020015b60405180910390f35b61015261014d366004610a2a565b61020e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610136565b61018a610185366004610ad3565b6104bf565b005b61018a610592565b60005473ffffffffffffffffffffffffffffffffffffffff16610152565b6101526101c0366004610a2a565b6105a6565b6101526101d3366004610b0a565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61018a610209366004610b2c565b61061d565b6000806001600087600281111561022757610227610b49565b600281111561023857610238610b49565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff169050806102a357856040517f44265d6f00000000000000000000000000000000000000000000000000000000815260040161029a9190610b78565b60405180910390fd5b60008585856040516020016102ba93929190610bb9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905061030a73ffffffffffffffffffffffffffffffffffffffff8316826106d4565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561035457600080fd5b505af1158015610368573d6000803e3d6000fd5b5050505060006103af888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061009b92505050565b60008181526002602052604090205490915073ffffffffffffffffffffffffffffffffffffffff1615610411576040517f014f6fe50000000000000000000000000000000000000000000000000000000081526004810182905260240161029a565b600081815260026020819052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87161790558790899081111561047357610473610b49565b60405173ffffffffffffffffffffffffffffffffffffffff8716907ffad0599ff449d8d9685eadecca8cb9e00924c5fd8367c1c09469824939e1ffec90600090a4505050949350505050565b6104c7610808565b80600160008460028111156104de576104de610b49565b60028111156104ef576104ef610b49565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600281111561054d5761054d610b49565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f623713f72f6e427a8044bb8b3bd6834357cf285decbaa21bcc73c1d0632c4d8490600090a35050565b61059a610808565b6105a46000610889565b565b6000600260006105ed878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061009b92505050565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1695945050505050565b610625610808565b73ffffffffffffffffffffffffffffffffffffffff81166106c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161029a565b6106d181610889565b50565b60006002825101603f8101600a81036040518360581b8260e81b177f6100003d81600a3d39f3363d3d373d3d3d3d610000806035363936013d7300001781528660601b601e8201527f5af43d3d93803e603357fd5bf300000000000000000000000000000000000000603282015285519150603f8101602087015b6020841061078c57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909301926020918201910161074f565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602085900360031b1b16815260f085901b9083015282816000f09450846107f9577febfef1880000000000000000000000000000000000000000000000000000000060005260206000fd5b90910160405250909392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161029a565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356003811061090d57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561095657600080fd5b61095f846108fe565b925060208401359150604084013567ffffffffffffffff8082111561098357600080fd5b818601915086601f83011261099757600080fd5b8135818111156109a9576109a9610912565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156109ef576109ef610912565b81604052828152896020848701011115610a0857600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60008060008060608587031215610a4057600080fd5b610a49856108fe565b935060208501359250604085013567ffffffffffffffff80821115610a6d57600080fd5b818701915087601f830112610a8157600080fd5b813581811115610a9057600080fd5b886020828501011115610aa257600080fd5b95989497505060200194505050565b73ffffffffffffffffffffffffffffffffffffffff811681146106d157600080fd5b60008060408385031215610ae657600080fd5b610aef836108fe565b91506020830135610aff81610ab1565b809150509250929050565b600060208284031215610b1c57600080fd5b610b25826108fe565b9392505050565b600060208284031215610b3e57600080fd5b8135610b2581610ab1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310610bb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b83815281836020830137600091016020019081529291505056fea164736f6c634300080f000a", Bin: "0x608060405234801561001057600080fd5b50604051610d8b380380610d8b83398101604081905261002f91610171565b61003833610047565b61004181610097565b506101a1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61009f610115565b6001600160a01b0381166101095760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61011281610047565b50565b6000546001600160a01b0316331461016f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610100565b565b60006020828403121561018357600080fd5b81516001600160a01b038116811461019a57600080fd5b9392505050565b610bdb806101b06000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b14610194578063c49d5271146101b2578063dfa162d3146101c5578063f2fde38b146101fb57600080fd5b806326daafbe1461008d5780633142e55e1461013f57806345583b7a14610177578063715018a61461018c575b600080fd5b61012c61009b36600461093c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0830180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086018051988652968352606087529451609f0190941683209190925291905291905290565b6040519081526020015b60405180910390f35b61015261014d366004610a25565b61020e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610136565b61018a610185366004610ace565b6104ba565b005b61018a61058d565b60005473ffffffffffffffffffffffffffffffffffffffff16610152565b6101526101c0366004610a25565b6105a1565b6101526101d3366004610b05565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61018a610209366004610b27565b610618565b6000806001600087600281111561022757610227610b44565b600281111561023857610238610b44565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff169050806102a357856040517f44265d6f00000000000000000000000000000000000000000000000000000000815260040161029a9190610b73565b60405180910390fd5b6103068585856040516020016102bb93929190610bb4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff8316906106cf565b91508173ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561035057600080fd5b505af1158015610364573d6000803e3d6000fd5b5050505060006103ab878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061009b92505050565b60008181526002602052604090205490915073ffffffffffffffffffffffffffffffffffffffff161561040d576040517f014f6fe50000000000000000000000000000000000000000000000000000000081526004810182905260240161029a565b600081815260026020819052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86161790558690889081111561046f5761046f610b44565b60405173ffffffffffffffffffffffffffffffffffffffff8616907ffad0599ff449d8d9685eadecca8cb9e00924c5fd8367c1c09469824939e1ffec90600090a45050949350505050565b6104c2610803565b80600160008460028111156104d9576104d9610b44565b60028111156104ea576104ea610b44565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600281111561054857610548610b44565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f623713f72f6e427a8044bb8b3bd6834357cf285decbaa21bcc73c1d0632c4d8490600090a35050565b610595610803565b61059f6000610884565b565b6000600260006105e8878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061009b92505050565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1695945050505050565b610620610803565b73ffffffffffffffffffffffffffffffffffffffff81166106c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161029a565b6106cc81610884565b50565b60006002825101603f8101600a81036040518360581b8260e81b177f6100003d81600a3d39f3363d3d373d3d3d3d610000806035363936013d7300001781528660601b601e8201527f5af43d3d93803e603357fd5bf300000000000000000000000000000000000000603282015285519150603f8101602087015b6020841061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909301926020918201910161074a565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602085900360031b1b16815260f085901b9083015282816000f09450846107f4577febfef1880000000000000000000000000000000000000000000000000000000060005260206000fd5b90910160405250909392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461059f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161029a565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356003811061090857600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561095157600080fd5b61095a846108f9565b925060208401359150604084013567ffffffffffffffff8082111561097e57600080fd5b818601915086601f83011261099257600080fd5b8135818111156109a4576109a461090d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156109ea576109ea61090d565b81604052828152896020848701011115610a0357600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60008060008060608587031215610a3b57600080fd5b610a44856108f9565b935060208501359250604085013567ffffffffffffffff80821115610a6857600080fd5b818701915087601f830112610a7c57600080fd5b813581811115610a8b57600080fd5b886020828501011115610a9d57600080fd5b95989497505060200194505050565b73ffffffffffffffffffffffffffffffffffffffff811681146106cc57600080fd5b60008060408385031215610ae157600080fd5b610aea836108f9565b91506020830135610afa81610aac565b809150509250929050565b600060208284031215610b1757600080fd5b610b20826108f9565b9392505050565b600060208284031215610b3957600080fd5b8135610b2081610aac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310610bae577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b83815281836020830137600091016020019081529291505056fea164736f6c634300080f000a",
} }
// DisputeGameFactoryABI is the input ABI used to generate the binding from. // DisputeGameFactoryABI is the input ABI used to generate the binding from.
......
...@@ -248,3 +248,21 @@ ...@@ -248,3 +248,21 @@
| Name | Type | Slot | Offset | Bytes | Contract | | Name | Type | Slot | Offset | Bytes | Contract |
|------|------|------|--------|-------|----------| |------|------|------|--------|-------|----------|
=======================
➡ contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory
=======================
| Name | Type | Slot | Offset | Bytes | Contract |
|--------------|-------------------------------------------------|------|--------|-------|-------------------------------------------------------------|
| _owner | address | 0 | 0 | 20 | contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory |
| gameImpls | mapping(enum GameType => contract IDisputeGame) | 1 | 0 | 32 | contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory |
| disputeGames | mapping(Hash => contract IDisputeGame) | 2 | 0 | 32 | contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory |
=======================
➡ contracts/dispute/BondManager.sol:BondManager
=======================
| Name | Type | Slot | Offset | Bytes | Contract |
|-------|---------------------------------------------|------|--------|-------|-----------------------------------------------|
| bonds | mapping(bytes32 => struct BondManager.Bond) | 0 | 0 | 32 | contracts/dispute/BondManager.sol:BondManager |
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { GameType } from "../libraries/DisputeTypes.sol"; import "../libraries/DisputeTypes.sol";
import { GameStatus } from "../libraries/DisputeTypes.sol";
import { SafeCall } from "../libraries/SafeCall.sol"; import { SafeCall } from "../libraries/SafeCall.sol";
import { IDisputeGame } from "./IDisputeGame.sol"; import { IDisputeGame } from "./interfaces/IDisputeGame.sol";
import { IDisputeGameFactory } from "./IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "./interfaces/IDisputeGameFactory.sol";
import { IBondManager } from "./interfaces/IBondManager.sol";
/** /**
* @title BondManager * @title BondManager
* @notice The Bond Manager serves as an escrow for permissionless output proposal bonds. * @notice The Bond Manager serves as an escrow for permissionless output proposal bonds.
*/ */
contract BondManager { contract BondManager is IBondManager {
/** /**
* @notice The Bond Type * @notice The Bond Type
*/ */
struct Bond { struct Bond {
address owner; address owner;
uint256 expiration;
bytes32 id; bytes32 id;
uint256 amount; uint128 expiration;
uint128 amount;
} }
/**
* @notice Mapping from bondId to bond.
*/
mapping(bytes32 => Bond) public bonds;
/**
* @notice BondPosted is emitted when a bond is posted.
* @param bondId is the id of the bond.
* @param owner is the address that owns the bond.
* @param expiration is the time at which the bond expires.
* @param amount is the amount of the bond.
*/
event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount);
/**
* @notice BondSeized is emitted when a bond is seized.
* @param bondId is the id of the bond.
* @param owner is the address that owns the bond.
* @param seizer is the address that seized the bond.
* @param amount is the amount of the bond.
*/
event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount);
/**
* @notice BondReclaimed is emitted when a bond is reclaimed by the owner.
* @param bondId is the id of the bond.
* @param claiment is the address that reclaimed the bond.
* @param amount is the amount of the bond.
*/
event BondReclaimed(bytes32 bondId, address claiment, uint256 amount);
/** /**
* @notice The permissioned dispute game factory. * @notice The permissioned dispute game factory.
* @dev Used to verify the status of bonds. * @dev Used to verify the status of bonds.
...@@ -67,6 +37,11 @@ contract BondManager { ...@@ -67,6 +37,11 @@ contract BondManager {
*/ */
uint256 private constant TRANSFER_GAS = 30_000; uint256 private constant TRANSFER_GAS = 30_000;
/**
* @notice Mapping from bondId to bond.
*/
mapping(bytes32 => Bond) public bonds;
/** /**
* @notice Instantiates the bond maanger with the registered dispute game factory. * @notice Instantiates the bond maanger with the registered dispute game factory.
* @param _disputeGameFactory is the dispute game factory. * @param _disputeGameFactory is the dispute game factory.
...@@ -76,37 +51,30 @@ contract BondManager { ...@@ -76,37 +51,30 @@ contract BondManager {
} }
/** /**
* @notice Post a bond with a given id and owner. * @inheritdoc IBondManager
* @dev This function will revert if the provided bondId is already in use.
* @param _bondId is the id of the bond.
* @param _bondOwner is the address that owns the bond.
* @param _minClaimHold is the minimum amount of time the owner
* must wait before reclaiming their bond.
*/ */
function post( function post(
bytes32 _bondId, bytes32 _bondId,
address _bondOwner, address _bondOwner,
uint256 _minClaimHold uint128 _minClaimHold
) external payable { ) external payable {
require(bonds[_bondId].owner == address(0), "BondManager: BondId already posted."); require(bonds[_bondId].owner == address(0), "BondManager: BondId already posted.");
require(_bondOwner != address(0), "BondManager: Owner cannot be the zero address."); require(_bondOwner != address(0), "BondManager: Owner cannot be the zero address.");
require(msg.value > 0, "BondManager: Value must be non-zero."); require(msg.value > 0, "BondManager: Value must be non-zero.");
uint256 expiration = _minClaimHold + block.timestamp; uint128 expiration = uint128(_minClaimHold + block.timestamp);
bonds[_bondId] = Bond({ bonds[_bondId] = Bond({
owner: _bondOwner, owner: _bondOwner,
expiration: expiration,
id: _bondId, id: _bondId,
amount: msg.value expiration: expiration,
amount: uint128(msg.value)
}); });
emit BondPosted(_bondId, _bondOwner, expiration, msg.value); emit BondPosted(_bondId, _bondOwner, expiration, msg.value);
} }
/** /**
* @notice Seizes the bond with the given id. * @inheritdoc IBondManager
* @dev This function will revert if there is no bond at the given id.
* @param _bondId is the id of the bond.
*/ */
function seize(bytes32 _bondId) external { function seize(bytes32 _bondId) external {
Bond memory b = bonds[_bondId]; Bond memory b = bonds[_bondId];
...@@ -131,10 +99,7 @@ contract BondManager { ...@@ -131,10 +99,7 @@ contract BondManager {
} }
/** /**
* @notice Seizes the bond with the given id and distributes it to recipients. * @inheritdoc IBondManager
* @dev This function will revert if there is no bond at the given id.
* @param _bondId is the id of the bond.
* @param _claimRecipients is a set of addresses to split the bond amongst.
*/ */
function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external { function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external {
Bond memory b = bonds[_bondId]; Bond memory b = bonds[_bondId];
...@@ -168,9 +133,7 @@ contract BondManager { ...@@ -168,9 +133,7 @@ contract BondManager {
} }
/** /**
* @notice Reclaims the bond of the bond owner. * @inheritdoc IBondManager
* @dev This function will revert if there is no bond at the given id.
* @param _bondId is the id of the bond.
*/ */
function reclaim(bytes32 _bondId) external { function reclaim(bytes32 _bondId) external {
Bond memory b = bonds[_bondId]; Bond memory b = bonds[_bondId];
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeErrors.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol"; import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol";
import { Claim } from "../libraries/DisputeTypes.sol"; import { IDisputeGame } from "./interfaces/IDisputeGame.sol";
import { Hash } from "../libraries/DisputeTypes.sol"; import { IDisputeGameFactory } from "./interfaces/IDisputeGameFactory.sol";
import { GameType } from "../libraries/DisputeTypes.sol";
import { NoImplementation } from "../libraries/DisputeErrors.sol";
import { GameAlreadyExists } from "../libraries/DisputeErrors.sol";
import { IDisputeGame } from "./IDisputeGame.sol";
import { IDisputeGameFactory } from "./IDisputeGameFactory.sol";
/** /**
* @title DisputeGameFactory * @title DisputeGameFactory
...@@ -25,7 +21,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory { ...@@ -25,7 +21,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory {
using ClonesWithImmutableArgs for address; using ClonesWithImmutableArgs for address;
/** /**
* @notice Mapping of `GameType`s to their respective `IDisputeGame` implementations. * @inheritdoc IDisputeGameFactory
*/ */
mapping(GameType => IDisputeGame) public gameImpls; mapping(GameType => IDisputeGame) public gameImpls;
...@@ -45,16 +41,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory { ...@@ -45,16 +41,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory {
} }
/** /**
* @notice Retrieves the hash of `gameType . rootClaim . extraData` * @inheritdoc IDisputeGameFactory
* to the deployed `DisputeGame` clone.
* @dev Note: `.` denotes concatenation.
* @param gameType The type of the DisputeGame.
* Used to decide the implementation to clone.
* @param rootClaim The root claim of the DisputeGame.
* @param extraData Any extra data that should be provided to the
* created dispute game.
* @return _proxy The clone of the `DisputeGame` created with the
* given parameters. `address(0)` if nonexistent.
*/ */
function games( function games(
GameType gameType, GameType gameType,
...@@ -65,15 +52,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory { ...@@ -65,15 +52,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory {
} }
/** /**
* @notice Creates a new DisputeGame proxy contract. * @inheritdoc IDisputeGameFactory
* @notice If a dispute game with the given parameters already exists,
* it will be returned.
* @param gameType The type of the DisputeGame.
* Used to decide the proxy implementation.
* @param rootClaim The root claim of the DisputeGame.
* @param extraData Any extra data that should be provided
* to the created dispute game.
* @return proxy The clone of the `DisputeGame`.
*/ */
function create( function create(
GameType gameType, GameType gameType,
...@@ -89,8 +68,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory { ...@@ -89,8 +68,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory {
} }
// Clone the implementation contract and initialize it with the given parameters. // Clone the implementation contract and initialize it with the given parameters.
bytes memory data = abi.encodePacked(rootClaim, extraData); proxy = IDisputeGame(address(impl).clone(abi.encodePacked(rootClaim, extraData)));
proxy = IDisputeGame(address(impl).clone(data));
proxy.initialize(); proxy.initialize();
// Compute the unique identifier for the dispute game. // Compute the unique identifier for the dispute game.
...@@ -107,23 +85,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory { ...@@ -107,23 +85,7 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory {
} }
/** /**
* @notice Sets the implementation contract for a specific `GameType`. * @inheritdoc IDisputeGameFactory
* @param gameType The type of the DisputeGame.
* @param impl The implementation contract for the given `GameType`.
*/
function setImplementation(GameType gameType, IDisputeGame impl) external onlyOwner {
gameImpls[gameType] = impl;
emit ImplementationSet(address(impl), gameType);
}
/**
* @notice Returns a unique identifier for the given dispute game parameters.
* @dev Hashes the concatenation of `gameType . rootClaim . extraData`
* without expanding memory.
* @param gameType The type of the DisputeGame.
* @param rootClaim The root claim of the DisputeGame.
* @param extraData Any extra data that should be provided to the created dispute game.
* @return _uuid The unique identifier for the given dispute game parameters.
*/ */
function getGameUUID( function getGameUUID(
GameType gameType, GameType gameType,
...@@ -160,4 +122,12 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory { ...@@ -160,4 +122,12 @@ contract DisputeGameFactory is Ownable, IDisputeGameFactory {
mstore(pointerOffset, tempC) mstore(pointerOffset, tempC)
} }
} }
/**
* @inheritdoc IDisputeGameFactory
*/
function setImplementation(GameType gameType, IDisputeGame impl) external onlyOwner {
gameImpls[gameType] = impl;
emit ImplementationSet(address(impl), gameType);
}
} }
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import { IDisputeGame } from "./IDisputeGame.sol";
/**
* @title IAttestationDisputeGame
* @notice The interface for an attestation-based DisputeGame meant to contest output
* proposals in Optimism's `L2OutputOracle` contract.
*/
interface IAttestationDisputeGame is IDisputeGame {
/**
* @notice A mapping of addresses from the `signerSet` to booleans signifying whether
* or not they have authorized the `rootClaim` to be invalidated.
* @param challenger The address to check for authorization.
* @return _challenged Whether or not the `challenger` has challenged the `rootClaim`.
*/
function challenges(address challenger) external view returns (bool _challenged);
/**
* @notice The signer set consists of authorized public keys that may challenge
* the `rootClaim`.
* @param addr The address to check for authorization.
* @return _isAuthorized Whether or not the `addr` is part of the signer set.
*/
function signerSet(address addr) external view returns (bool _isAuthorized);
/**
* @notice The amount of signatures required to successfully challenge the `rootClaim`
* output proposal. Once this threshold is met by members of the `signerSet`
* calling `challenge`, the game will be resolved to `CHALLENGER_WINS`.
* @custom:invariant The `signatureThreshold` may never be greater than the length
* of the `signerSet`.
* @return _signatureThreshold The amount of signatures required to successfully
* challenge the `rootClaim` output proposal.
*/
function frozenSignatureThreshold() external view returns (uint256 _signatureThreshold);
/**
* @notice Returns the L2 Block Number that the `rootClaim` commits to.
* Exists within the `extraData`.
* @return _l2BlockNumber The L2 Block Number that the `rootClaim` commits to.
*/
function l2BlockNumber() external view returns (uint256 _l2BlockNumber);
/**
* @notice Challenge the `rootClaim`.
* @dev - If the `ecrecover`ed address that created the signature is not a part of
* the signer set returned by `signerSet`, this function should revert.
* - If the `ecrecover`ed address that created the signature is not the
* msg.sender, this function should revert.
* - If the signature provided is the signature that breaches the signature
* threshold, the function should call the `resolve` function to resolve
* the game as `CHALLENGER_WINS`.
* - When the game resolves, the bond attached to the root claim should be
* distributed among the signers who participated in challenging the
* invalid claim.
* @param signature An EIP-712 signature committing to the `rootClaim` and
* `l2BlockNumber` (within the `extraData`) from a key that exists
* within the `signerSet`.
*/
function challenge(bytes calldata signature) external;
}
...@@ -6,6 +6,32 @@ pragma solidity ^0.8.15; ...@@ -6,6 +6,32 @@ pragma solidity ^0.8.15;
* @notice The Bond Manager holds ether posted as a bond for a bond id. * @notice The Bond Manager holds ether posted as a bond for a bond id.
*/ */
interface IBondManager { interface IBondManager {
/**
* @notice BondPosted is emitted when a bond is posted.
* @param bondId is the id of the bond.
* @param owner is the address that owns the bond.
* @param expiration is the time at which the bond expires.
* @param amount is the amount of the bond.
*/
event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount);
/**
* @notice BondSeized is emitted when a bond is seized.
* @param bondId is the id of the bond.
* @param owner is the address that owns the bond.
* @param seizer is the address that seized the bond.
* @param amount is the amount of the bond.
*/
event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount);
/**
* @notice BondReclaimed is emitted when a bond is reclaimed by the owner.
* @param bondId is the id of the bond.
* @param claiment is the address that reclaimed the bond.
* @param amount is the amount of the bond.
*/
event BondReclaimed(bytes32 bondId, address claiment, uint256 amount);
/** /**
* @notice Post a bond with a given id and owner. * @notice Post a bond with a given id and owner.
* @dev This function will revert if the provided bondId is already in use. * @dev This function will revert if the provided bondId is already in use.
...@@ -17,7 +43,7 @@ interface IBondManager { ...@@ -17,7 +43,7 @@ interface IBondManager {
function post( function post(
bytes32 _bondId, bytes32 _bondId,
address _bondOwner, address _bondOwner,
uint256 _minClaimHold uint128 _minClaimHold
) external payable; ) external payable;
/** /**
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { Claim } from "../libraries/DisputeTypes.sol"; import "../../libraries/DisputeTypes.sol";
import { GameType } from "../libraries/DisputeTypes.sol";
import { GameStatus } from "../libraries/DisputeTypes.sol";
import { Timestamp } from "../libraries/DisputeTypes.sol";
import { IVersioned } from "./IVersioned.sol"; import { IVersioned } from "./IVersioned.sol";
import { IBondManager } from "./IBondManager.sol"; import { IBondManager } from "./IBondManager.sol";
...@@ -21,8 +18,6 @@ interface IDisputeGame is IInitializable, IVersioned { ...@@ -21,8 +18,6 @@ interface IDisputeGame is IInitializable, IVersioned {
*/ */
event Resolved(GameStatus indexed status); event Resolved(GameStatus indexed status);
/// @notice Returns the timestamp that the DisputeGame contract was created at.
/** /**
* @notice Returns the timestamp that the DisputeGame contract was created at. * @notice Returns the timestamp that the DisputeGame contract was created at.
* @return _createdAt The timestamp that the DisputeGame contract was created at. * @return _createdAt The timestamp that the DisputeGame contract was created at.
...@@ -42,21 +37,21 @@ interface IDisputeGame is IInitializable, IVersioned { ...@@ -42,21 +37,21 @@ interface IDisputeGame is IInitializable, IVersioned {
* i.e. The game type should indicate the security model. * i.e. The game type should indicate the security model.
* @return _gameType The type of proof system being used. * @return _gameType The type of proof system being used.
*/ */
function gameType() external view returns (GameType _gameType); function gameType() external pure returns (GameType _gameType);
/** /**
* @notice Getter for the root claim. * @notice Getter for the root claim.
* @dev `clones-with-immutable-args` argument #2 * @dev `clones-with-immutable-args` argument #2
* @return _rootClaim The root claim of the DisputeGame. * @return _rootClaim The root claim of the DisputeGame.
*/ */
function rootClaim() external view returns (Claim _rootClaim); function rootClaim() external pure returns (Claim _rootClaim);
/** /**
* @notice Getter for the extra data. * @notice Getter for the extra data.
* @dev `clones-with-immutable-args` argument #3 * @dev `clones-with-immutable-args` argument #3
* @return _extraData Any extra data supplied to the dispute game contract by the creator. * @return _extraData Any extra data supplied to the dispute game contract by the creator.
*/ */
function extraData() external view returns (bytes memory _extraData); function extraData() external pure returns (bytes memory _extraData);
/** /**
* @notice Returns the address of the `BondManager` used. * @notice Returns the address of the `BondManager` used.
...@@ -73,4 +68,19 @@ interface IDisputeGame is IInitializable, IVersioned { ...@@ -73,4 +68,19 @@ interface IDisputeGame is IInitializable, IVersioned {
* @return _status The status of the game after resolution. * @return _status The status of the game after resolution.
*/ */
function resolve() external returns (GameStatus _status); function resolve() external returns (GameStatus _status);
/**
* @notice A compliant implementation of this interface should return the components of the
* game UUID's preimage provided in the cwia payload. The preimage of the UUID is
* constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes
* concatenation.
*/
function gameData()
external
pure
returns (
GameType _gameType,
Claim _rootClaim,
bytes memory _extraData
);
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { Claim } from "../libraries/DisputeTypes.sol"; import "../../libraries/DisputeTypes.sol";
import { GameType } from "../libraries/DisputeTypes.sol";
import { IDisputeGame } from "./IDisputeGame.sol"; import { IDisputeGame } from "./IDisputeGame.sol";
...@@ -75,4 +74,19 @@ interface IDisputeGameFactory { ...@@ -75,4 +74,19 @@ interface IDisputeGameFactory {
* @param impl The implementation contract for the given `GameType`. * @param impl The implementation contract for the given `GameType`.
*/ */
function setImplementation(GameType gameType, IDisputeGame impl) external; function setImplementation(GameType gameType, IDisputeGame impl) external;
/**
* @notice Returns a unique identifier for the given dispute game parameters.
* @dev Hashes the concatenation of `gameType . rootClaim . extraData`
* without expanding memory.
* @param gameType The type of the DisputeGame.
* @param rootClaim The root claim of the DisputeGame.
* @param extraData Any extra data that should be provided to the created dispute game.
* @return _uuid The unique identifier for the given dispute game parameters.
*/
function getGameUUID(
GameType gameType,
Claim rootClaim,
bytes memory extraData
) external pure returns (Hash _uuid);
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { Clock } from "../libraries/DisputeTypes.sol"; import "../../libraries/DisputeTypes.sol";
import { Claim } from "../libraries/DisputeTypes.sol";
import { Position } from "../libraries/DisputeTypes.sol";
import { Timestamp } from "../libraries/DisputeTypes.sol";
import { ClaimHash } from "../libraries/DisputeTypes.sol";
import { BondAmount } from "../libraries/DisputeTypes.sol";
import { IDisputeGame } from "./IDisputeGame.sol"; import { IDisputeGame } from "./IDisputeGame.sol";
...@@ -33,12 +28,6 @@ interface IFaultDisputeGame is IDisputeGame { ...@@ -33,12 +28,6 @@ interface IFaultDisputeGame is IDisputeGame {
*/ */
event Defend(ClaimHash indexed claimHash, Claim indexed pivot, address indexed claimant); event Defend(ClaimHash indexed claimHash, Claim indexed pivot, address indexed claimant);
/**
* @notice State variable of the starting timestamp of the game, set on deployment.
* @return The starting timestamp of the game
*/
function gameStart() external view returns (Timestamp);
/** /**
* @notice Maps a unique ClaimHash to a Claim. * @notice Maps a unique ClaimHash to a Claim.
* @param claimHash The unique ClaimHash * @param claimHash The unique ClaimHash
......
// SPDX-License-Identifier: BSD
pragma solidity ^0.8.15;
// solhint-disable
/**
* @title Clone
* @author zefram.eth, Saw-mon & Natalie, clabby
* @notice Provides helper functions for reading immutable args from calldata
* @dev Original: https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args/blob/105efee1b9127ed7f6fedf139e1fc796ce8791f2/src/Clone.sol
* @dev MODIFICATIONS:
* - Added `_getArgDynBytes` function.
*/
// solhint-enable
contract Clone {
uint256 private constant ONE_WORD = 0x20;
/**
* @notice Reads an immutable arg with type address
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
function _getArgAddress(uint256 argOffset) internal pure returns (address arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
arg := shr(0x60, calldataload(add(offset, argOffset)))
}
}
/**
* @notice Reads an immutable arg with type uint256
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
function _getArgUint256(uint256 argOffset) internal pure returns (uint256 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
arg := calldataload(add(offset, argOffset))
}
}
/**
* @notice Reads an immutable arg with type bytes32
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
function _getArgFixedBytes(uint256 argOffset) internal pure returns (bytes32 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
arg := calldataload(add(offset, argOffset))
}
}
/**
* @notice Reads a uint256 array stored in the immutable args.
* @param argOffset The offset of the arg in the packed data
* @param arrLen Number of elements in the array
* @return arr The array
*/
function _getArgUint256Array(uint256 argOffset, uint64 arrLen)
internal
pure
returns (uint256[] memory arr)
{
uint256 offset = _getImmutableArgsOffset() + argOffset;
arr = new uint256[](arrLen);
assembly {
calldatacopy(add(arr, ONE_WORD), offset, shl(5, arrLen))
}
}
/**
* @notice Reads a dynamic bytes array stored in the immutable args.
* @param argOffset The offset of the arg in the packed data
* @param arrLen Number of elements in the array
* @return arr The array
*/
function _getArgDynBytes(uint256 argOffset, uint64 arrLen)
internal
pure
returns (bytes memory arr)
{
uint256 offset = _getImmutableArgsOffset() + argOffset;
arr = new bytes(arrLen);
assembly {
calldatacopy(add(arr, ONE_WORD), offset, arrLen)
}
}
/**
* @notice Reads an immutable arg with type uint64
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
function _getArgUint64(uint256 argOffset) internal pure returns (uint64 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
arg := shr(0xc0, calldataload(add(offset, argOffset)))
}
}
/**
* @notice Reads an immutable arg with type uint8
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
function _getArgUint8(uint256 argOffset) internal pure returns (uint8 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
arg := shr(0xf8, calldataload(add(offset, argOffset)))
}
}
/**
* @return offset The offset of the packed immutable args in calldata
*/
function _getImmutableArgsOffset() internal pure returns (uint256 offset) {
assembly {
offset := sub(calldatasize(), shr(0xf0, calldataload(sub(calldatasize(), 2))))
}
}
}
...@@ -5,8 +5,8 @@ import "forge-std/Test.sol"; ...@@ -5,8 +5,8 @@ import "forge-std/Test.sol";
import "../libraries/DisputeTypes.sol"; import "../libraries/DisputeTypes.sol";
import { IDisputeGame } from "../dispute/IDisputeGame.sol"; import { IDisputeGame } from "../dispute/interfaces/IDisputeGame.sol";
import { IBondManager } from "../dispute/IBondManager.sol"; import { IBondManager } from "../dispute/interfaces/IBondManager.sol";
import { DisputeGameFactory } from "../dispute/DisputeGameFactory.sol"; import { DisputeGameFactory } from "../dispute/DisputeGameFactory.sol";
...@@ -45,23 +45,21 @@ contract BondManager_Test is Test { ...@@ -45,23 +45,21 @@ contract BondManager_Test is Test {
function testFuzz_post_succeeds( function testFuzz_post_succeeds(
bytes32 bondId, bytes32 bondId,
address owner, address owner,
uint256 minClaimHold, uint128 minClaimHold,
uint256 amount uint128 amount
) public { ) public {
vm.assume(owner != address(0)); vm.assume(owner != address(0));
vm.assume(owner != address(bm)); vm.assume(owner != address(bm));
vm.assume(owner != address(this)); vm.assume(owner != address(this));
// Create2Deployer // Create2Deployer
vm.assume(owner != address(0x4e59b44847b379578588920cA78FbF26c0B4956C)); vm.assume(owner != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));
vm.assume(amount != 0); amount = uint128(bound(amount, 1, type(uint128).max));
unchecked { minClaimHold = uint128(bound(minClaimHold, 0, type(uint128).max - block.timestamp));
vm.assume(block.timestamp + minClaimHold > minClaimHold);
}
vm.deal(address(this), amount); vm.deal(address(this), amount);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
uint256 expiration = block.timestamp + minClaimHold; uint128 expiration = uint128(block.timestamp + minClaimHold);
emit BondPosted(bondId, owner, expiration, amount); emit BondPosted(bondId, owner, expiration, amount);
bm.post{ value: amount }(bondId, owner, minClaimHold); bm.post{ value: amount }(bondId, owner, minClaimHold);
...@@ -69,9 +67,9 @@ contract BondManager_Test is Test { ...@@ -69,9 +67,9 @@ contract BondManager_Test is Test {
// Validate the bond // Validate the bond
( (
address newFetchedOwner, address newFetchedOwner,
uint256 fetchedExpiration,
bytes32 fetchedBondId, bytes32 fetchedBondId,
uint256 bondAmount uint128 fetchedExpiration,
uint128 bondAmount
) = bm.bonds(bondId); ) = bm.bonds(bondId);
assertEq(newFetchedOwner, owner); assertEq(newFetchedOwner, owner);
assertEq(fetchedExpiration, block.timestamp + minClaimHold); assertEq(fetchedExpiration, block.timestamp + minClaimHold);
...@@ -85,15 +83,13 @@ contract BondManager_Test is Test { ...@@ -85,15 +83,13 @@ contract BondManager_Test is Test {
function testFuzz_post_duplicates_reverts( function testFuzz_post_duplicates_reverts(
bytes32 bondId, bytes32 bondId,
address owner, address owner,
uint256 minClaimHold, uint128 minClaimHold,
uint256 amount uint128 amount
) public { ) public {
vm.assume(owner != address(0)); vm.assume(owner != address(0));
amount = amount / 2; amount = amount / 2;
vm.assume(amount != 0); amount = uint128(bound(amount, 1, type(uint128).max));
unchecked { minClaimHold = uint128(bound(minClaimHold, 0, type(uint128).max - block.timestamp));
vm.assume(block.timestamp + minClaimHold > minClaimHold);
}
vm.deal(address(this), amount); vm.deal(address(this), amount);
bm.post{ value: amount }(bondId, owner, minClaimHold); bm.post{ value: amount }(bondId, owner, minClaimHold);
...@@ -108,8 +104,8 @@ contract BondManager_Test is Test { ...@@ -108,8 +104,8 @@ contract BondManager_Test is Test {
*/ */
function testFuzz_post_zeroAddress_reverts( function testFuzz_post_zeroAddress_reverts(
bytes32 bondId, bytes32 bondId,
uint256 minClaimHold, uint128 minClaimHold,
uint256 amount uint128 amount
) public { ) public {
address owner = address(0); address owner = address(0);
vm.deal(address(this), amount); vm.deal(address(this), amount);
...@@ -123,10 +119,10 @@ contract BondManager_Test is Test { ...@@ -123,10 +119,10 @@ contract BondManager_Test is Test {
function testFuzz_post_zeroAddress_reverts( function testFuzz_post_zeroAddress_reverts(
bytes32 bondId, bytes32 bondId,
address owner, address owner,
uint256 minClaimHold uint128 minClaimHold
) public { ) public {
vm.assume(owner != address(0)); vm.assume(owner != address(0));
uint256 amount = 0; uint128 amount = 0;
vm.deal(address(this), amount); vm.deal(address(this), amount);
vm.expectRevert("BondManager: Value must be non-zero."); vm.expectRevert("BondManager: Value must be non-zero.");
bm.post{ value: amount }(bondId, owner, minClaimHold); bm.post{ value: amount }(bondId, owner, minClaimHold);
...@@ -152,16 +148,14 @@ contract BondManager_Test is Test { ...@@ -152,16 +148,14 @@ contract BondManager_Test is Test {
function testFuzz_seize_expired_reverts( function testFuzz_seize_expired_reverts(
bytes32 bondId, bytes32 bondId,
address owner, address owner,
uint256 minClaimHold, uint128 minClaimHold,
uint256 amount uint128 amount
) public { ) public {
vm.assume(owner != address(0)); vm.assume(owner != address(0));
vm.assume(owner != address(bm)); vm.assume(owner != address(bm));
vm.assume(owner != address(this)); vm.assume(owner != address(this));
vm.assume(amount != 0); amount = uint128(bound(amount, 1, type(uint128).max));
unchecked { minClaimHold = uint128(bound(minClaimHold, 0, type(uint128).max - block.timestamp));
vm.assume(block.timestamp + minClaimHold + 1 > minClaimHold);
}
vm.deal(address(this), amount); vm.deal(address(this), amount);
bm.post{ value: amount }(bondId, owner, minClaimHold); bm.post{ value: amount }(bondId, owner, minClaimHold);
...@@ -176,16 +170,15 @@ contract BondManager_Test is Test { ...@@ -176,16 +170,15 @@ contract BondManager_Test is Test {
function testFuzz_seize_unauthorized_reverts( function testFuzz_seize_unauthorized_reverts(
bytes32 bondId, bytes32 bondId,
address owner, address owner,
uint256 minClaimHold, uint128 minClaimHold,
uint256 amount uint128 amount
) public { ) public {
vm.assume(owner != address(0)); vm.assume(owner != address(0));
vm.assume(owner != address(bm)); vm.assume(owner != address(bm));
vm.assume(owner != address(this)); vm.assume(owner != address(this));
vm.assume(amount != 0); amount = uint128(bound(amount, 1, type(uint128).max));
unchecked { minClaimHold = uint128(bound(minClaimHold, 0, type(uint128).max - block.timestamp));
vm.assume(block.timestamp + minClaimHold > minClaimHold);
}
vm.deal(address(this), amount); vm.deal(address(this), amount);
bm.post{ value: amount }(bondId, owner, minClaimHold); bm.post{ value: amount }(bondId, owner, minClaimHold);
...@@ -200,12 +193,10 @@ contract BondManager_Test is Test { ...@@ -200,12 +193,10 @@ contract BondManager_Test is Test {
*/ */
function testFuzz_seize_succeeds( function testFuzz_seize_succeeds(
bytes32 bondId, bytes32 bondId,
uint256 minClaimHold, uint128 minClaimHold,
bytes calldata extraData bytes calldata extraData
) public { ) public {
unchecked { minClaimHold = uint128(bound(minClaimHold, 0, type(uint128).max - block.timestamp));
vm.assume(block.timestamp + minClaimHold > minClaimHold);
}
vm.deal(address(this), 1 ether); vm.deal(address(this), 1 ether);
bm.post{ value: 1 ether }(bondId, address(0xba5ed), minClaimHold); bm.post{ value: 1 ether }(bondId, address(0xba5ed), minClaimHold);
...@@ -255,12 +246,10 @@ contract BondManager_Test is Test { ...@@ -255,12 +246,10 @@ contract BondManager_Test is Test {
*/ */
function testFuzz_seizeAndSplit_succeeds( function testFuzz_seizeAndSplit_succeeds(
bytes32 bondId, bytes32 bondId,
uint256 minClaimHold, uint128 minClaimHold,
bytes calldata extraData bytes calldata extraData
) public { ) public {
unchecked { minClaimHold = uint128(bound(minClaimHold, 0, type(uint128).max - block.timestamp));
vm.assume(block.timestamp + minClaimHold > minClaimHold);
}
vm.deal(address(this), 1 ether); vm.deal(address(this), 1 ether);
bm.post{ value: 1 ether }(bondId, address(0xba5ed), minClaimHold); bm.post{ value: 1 ether }(bondId, address(0xba5ed), minClaimHold);
...@@ -316,15 +305,16 @@ contract BondManager_Test is Test { ...@@ -316,15 +305,16 @@ contract BondManager_Test is Test {
function testFuzz_reclaim_succeeds( function testFuzz_reclaim_succeeds(
bytes32 bondId, bytes32 bondId,
address owner, address owner,
uint256 minClaimHold, uint128 minClaimHold,
uint256 amount uint128 amount
) public { ) public {
vm.assume(owner != address(factory));
vm.assume(owner != address(bm));
vm.assume(owner != address(this));
vm.assume(owner != address(0)); vm.assume(owner != address(0));
vm.assume(owner.code.length == 0); vm.assume(owner.code.length == 0);
vm.assume(amount != 0); amount = uint128(bound(amount, 1, type(uint128).max));
unchecked { minClaimHold = uint128(bound(minClaimHold, 0, type(uint128).max - block.timestamp));
vm.assume(block.timestamp + minClaimHold > minClaimHold);
}
assumeNoPrecompiles(owner); assumeNoPrecompiles(owner);
// Post the bond // Post the bond
...@@ -332,7 +322,7 @@ contract BondManager_Test is Test { ...@@ -332,7 +322,7 @@ contract BondManager_Test is Test {
bm.post{ value: amount }(bondId, owner, minClaimHold); bm.post{ value: amount }(bondId, owner, minClaimHold);
// We can't claim if the block.timestamp is less than the bond expiration. // We can't claim if the block.timestamp is less than the bond expiration.
(, uint256 expiration, , ) = bm.bonds(bondId); (, , uint256 expiration, ) = bm.bonds(bondId);
if (expiration > block.timestamp) { if (expiration > block.timestamp) {
vm.prank(owner); vm.prank(owner);
vm.expectRevert("BondManager: Bond isn't claimable yet."); vm.expectRevert("BondManager: Bond isn't claimable yet.");
...@@ -351,7 +341,7 @@ contract BondManager_Test is Test { ...@@ -351,7 +341,7 @@ contract BondManager_Test is Test {
* @title MockAttestationDisputeGame * @title MockAttestationDisputeGame
* @dev A mock dispute game for testing bond seizures. * @dev A mock dispute game for testing bond seizures.
*/ */
contract MockAttestationDisputeGame is IDisputeGame { contract MockAttestationDisputeGame {
GameStatus internal gameStatus; GameStatus internal gameStatus;
BondManager bm; BondManager bm;
Claim internal rc; Claim internal rc;
...@@ -419,11 +409,11 @@ contract MockAttestationDisputeGame is IDisputeGame { ...@@ -419,11 +409,11 @@ contract MockAttestationDisputeGame is IDisputeGame {
* ------------------------------------------- * -------------------------------------------
*/ */
function createdAt() external pure override returns (Timestamp _createdAt) { function createdAt() external pure returns (Timestamp _createdAt) {
return Timestamp.wrap(uint64(0)); return Timestamp.wrap(uint64(0));
} }
function status() external view override returns (GameStatus _status) { function status() external view returns (GameStatus _status) {
return gameStatus; return gameStatus;
} }
...@@ -431,7 +421,7 @@ contract MockAttestationDisputeGame is IDisputeGame { ...@@ -431,7 +421,7 @@ contract MockAttestationDisputeGame is IDisputeGame {
return GameType.ATTESTATION; return GameType.ATTESTATION;
} }
function rootClaim() external view override returns (Claim _rootClaim) { function rootClaim() external view returns (Claim _rootClaim) {
return rc; return rc;
} }
...@@ -439,7 +429,21 @@ contract MockAttestationDisputeGame is IDisputeGame { ...@@ -439,7 +429,21 @@ contract MockAttestationDisputeGame is IDisputeGame {
return ed; return ed;
} }
function bondManager() external view override returns (IBondManager _bondManager) { function gameData()
external
pure
returns (
GameType,
Claim,
bytes memory
)
{
assembly {
revert(0, 0)
}
}
function bondManager() external view returns (IBondManager _bondManager) {
return IBondManager(address(bm)); return IBondManager(address(bm));
} }
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "forge-std/Test.sol";
import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol";
import { Clone } from "../libraries/Clone.sol";
contract ExampleClone is Clone {
uint256 argOffset;
constructor(uint256 _argOffset) {
argOffset = _argOffset;
}
function addressArg() public view returns (address) {
return _getArgAddress(argOffset);
}
function uintArg() public view returns (uint256) {
return _getArgUint256(argOffset);
}
function fixedBytesArg() public view returns (bytes32) {
return _getArgFixedBytes(argOffset);
}
function uintArrayArg(uint64 arrLen) public view returns (uint256[] memory) {
return _getArgUint256Array(argOffset, arrLen);
}
function dynBytesArg(uint64 arrLen) public view returns (bytes memory) {
return _getArgDynBytes(argOffset, arrLen);
}
function uint64Arg() public view returns (uint64) {
return _getArgUint64(argOffset);
}
function uint8Arg() public view returns (uint8) {
return _getArgUint8(argOffset);
}
}
contract ExampleCloneFactory {
using ClonesWithImmutableArgs for address;
ExampleClone public implementation;
constructor(ExampleClone implementation_) {
implementation = implementation_;
}
function createAddressClone(address arg) external returns (ExampleClone clone) {
bytes memory data = abi.encodePacked(arg);
clone = ExampleClone(address(implementation).clone(data));
}
function createUintClone(uint256 arg) external returns (ExampleClone clone) {
bytes memory data = abi.encodePacked(arg);
clone = ExampleClone(address(implementation).clone(data));
}
function createFixedBytesClone(bytes32 arg) external returns (ExampleClone clone) {
bytes memory data = abi.encodePacked(arg);
clone = ExampleClone(address(implementation).clone(data));
}
function createUintArrayClone(uint256[] memory arg) external returns (ExampleClone clone) {
bytes memory data = abi.encodePacked(arg);
clone = ExampleClone(address(implementation).clone(data));
}
function createDynBytesClone(bytes memory arg) external returns (ExampleClone clone) {
bytes memory data = abi.encodePacked(arg);
clone = ExampleClone(address(implementation).clone(data));
}
function createUint64Clone(uint64 arg) external returns (ExampleClone clone) {
bytes memory data = abi.encodePacked(arg);
clone = ExampleClone(address(implementation).clone(data));
}
function createUint8Clone(uint8 arg) external returns (ExampleClone clone) {
bytes memory data = abi.encodePacked(arg);
clone = ExampleClone(address(implementation).clone(data));
}
function createClone(bytes memory randomCalldata) external returns (ExampleClone clone) {
clone = ExampleClone(address(implementation).clone(randomCalldata));
}
}
contract Clones_Test is Test {
function testFuzz_clone_addressArg_succeeds(uint256 argOffset, address param) public {
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createAddressClone(param);
address fetched = clone.addressArg();
assertEq(fetched, param);
}
function testFuzz_clone_uintArg_succeeds(uint256 argOffset, uint256 param) public {
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createUintClone(param);
uint256 fetched = clone.uintArg();
assertEq(fetched, param);
}
function testFuzz_clone_fixedBytesArg_succeeds(uint256 argOffset, bytes32 param) public {
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createFixedBytesClone(param);
bytes32 fetched = clone.fixedBytesArg();
assertEq(fetched, param);
}
function testFuzz_clone_uintArrayArg_succeeds(uint256 argOffset, uint256[] memory param)
public
{
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createUintArrayClone(param);
uint256[] memory fetched = clone.uintArrayArg(uint64(param.length));
assertEq(fetched, param);
}
function testFuzz_clone_dynBytesArg_succeeds(uint256 argOffset, bytes memory param) public {
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createDynBytesClone(param);
bytes memory fetched = clone.dynBytesArg(uint64(param.length));
assertEq(fetched, param);
}
function testFuzz_clone_uint64Arg_succeeds(uint256 argOffset, uint64 param) public {
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createUint64Clone(param);
uint64 fetched = clone.uint64Arg();
assertEq(fetched, param);
}
function testFuzz_clone_uint8Arg_succeeds(uint256 argOffset, uint8 param) public {
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createUint8Clone(param);
uint8 fetched = clone.uint8Arg();
assertEq(fetched, param);
}
}
...@@ -6,7 +6,7 @@ import "../libraries/DisputeErrors.sol"; ...@@ -6,7 +6,7 @@ import "../libraries/DisputeErrors.sol";
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { DisputeGameFactory } from "../dispute/DisputeGameFactory.sol"; import { DisputeGameFactory } from "../dispute/DisputeGameFactory.sol";
import { IDisputeGame } from "../dispute/IDisputeGame.sol"; import { IDisputeGame } from "../dispute/interfaces/IDisputeGame.sol";
contract DisputeGameFactory_Test is Test { contract DisputeGameFactory_Test is Test {
DisputeGameFactory factory; DisputeGameFactory factory;
......
...@@ -31,6 +31,8 @@ contracts=( ...@@ -31,6 +31,8 @@ contracts=(
contracts/legacy/L1ChugSplashProxy.sol:L1ChugSplashProxy contracts/legacy/L1ChugSplashProxy.sol:L1ChugSplashProxy
contracts/universal/OptimismMintableERC20.sol:OptimismMintableERC20 contracts/universal/OptimismMintableERC20.sol:OptimismMintableERC20
contracts/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory contracts/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory
contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory
contracts/dispute/BondManager.sol:BondManager
) )
dir=$(dirname "$0") dir=$(dirname "$0")
......
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