diff --git a/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol b/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol index 5042dfaf5..fd42c8cc5 100644 --- a/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol +++ b/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol @@ -3,20 +3,23 @@ pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; + /* Library Imports */ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol"; -/* Interface Imports */ +/* Inherited Interface Imports */ import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol"; + +/* External Interface Imports */ import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol"; +import { iOVM_SafetyCache } from "../../iOVM/execution/iOVM_SafetyCache.sol"; import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol"; /* Contract Imports */ import { OVM_ECDSAContractAccount } from "../accounts/OVM_ECDSAContractAccount.sol"; import { OVM_ProxyEOA } from "../accounts/OVM_ProxyEOA.sol"; -import { OVM_DeployerWhitelist } from "../precompiles/OVM_DeployerWhitelist.sol"; /** * @title OVM_ExecutionManager @@ -39,7 +42,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { * External Contract References * ********************************/ - iOVM_SafetyChecker internal ovmSafetyChecker; + iOVM_SafetyCache internal ovmSafetyCache; iOVM_StateManager internal ovmStateManager; @@ -81,7 +84,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ) Lib_AddressResolver(_libAddressManager) { - ovmSafetyChecker = iOVM_SafetyChecker(resolve("OVM_SafetyChecker")); + ovmSafetyCache = iOVM_SafetyCache(resolve("OVM_SafetyCache")); gasMeterConfig = _gasMeterConfig; globalContext = _globalContext; _resetContext(); @@ -808,8 +811,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { _revertWithFlag(RevertFlag.CREATE_COLLISION); } - // Check the creation bytecode against the OVM_SafetyChecker. - if (ovmSafetyChecker.isBytecodeSafe(_bytecode) == false) { + // Check the creation bytecode against the Safety Cache and Safety Checker. + if (ovmSafetyCache.checkAndRegisterSafeBytecode(_bytecode) == false) { _revertWithFlag(RevertFlag.UNSAFE_BYTECODE); } @@ -840,7 +843,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { // Again simply checking that the deployed code is safe too. Contracts can generate // arbitrary deployment code, so there's no easy way to analyze this beforehand. bytes memory deployedCode = Lib_EthUtils.getCode(ethAddress); - if (ovmSafetyChecker.isBytecodeSafe(deployedCode) == false) { + if (ovmSafetyCache.checkAndRegisterSafeBytecode(deployedCode) == false) { _revertWithFlag(RevertFlag.UNSAFE_BYTECODE); } @@ -870,7 +873,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { } /******************************************** - * Public Functions: Deployment Witelisting * + * Internal Functions: Deployment Witelisting * ********************************************/ /** @@ -1095,23 +1098,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { * Internal Functions: State Manipulation * ******************************************/ - /** - * Checks whether an account exists within the OVM_StateManager. - * @param _address Address of the account to check. - * @return _exists Whether or not the account exists. - */ - function _hasAccount( - address _address - ) - internal - returns ( - bool _exists - ) - { - _checkAccountLoad(_address); - return ovmStateManager.hasAccount(_address); - } - /** * Checks whether a known empty account exists within the OVM_StateManager. * @param _address Address of the account to check. diff --git a/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyCache.sol b/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyCache.sol new file mode 100644 index 000000000..099434ed5 --- /dev/null +++ b/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyCache.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.8.0; + +/* Library Imports */ +import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; + +/* External Interface Imports */ +import { iOVM_SafetyCache } from "../../iOVM/execution/iOVM_SafetyCache.sol"; + +/* Inherited Interface Imports */ +import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol"; + +/** + * @title OVM_SafetyCache + * @dev This contract implements a simple registry for caching the hash of any bytecode strings which have + * already been confirmed safe by the Safety Checker. + * + * Compiler used: solc + * Runtime target: EVM + */ +contract OVM_SafetyCache is iOVM_SafetyCache, Lib_AddressResolver { + + + /******************************************* + * Contract Variables: Contract References * + ******************************************/ + + iOVM_SafetyChecker internal ovmSafetyChecker; + + + /**************************************** + * Contract Variables: Internal Storage * + ****************************************/ + + mapping(bytes32 => bool) internal isSafeCodehash; + + + /*************** + * Constructor * + ***************/ + + /** + * @param _libAddressManager Address of the Address Manager. + */ + constructor( + address _libAddressManager + ) + Lib_AddressResolver(_libAddressManager) + { + ovmSafetyChecker = iOVM_SafetyChecker(resolve("OVM_SafetyChecker")); + } + + + /********************** + * External Functions * + *********************/ + + + /** Checks the registry to see if the verified bytecode is registered as safe. If not, calls to the + * SafetyChecker to see. + * @param _code A bytes32 hash of the code + * @return `true` if the bytecode is safe, `false` otherwise. + */ + function checkAndRegisterSafeBytecode( + bytes memory _code + ) + override + external + returns ( + bool + ) { + bytes32 codehash = keccak256(abi.encode(_code)); + if(isSafeCodehash[codehash] == true) { + return true; + } + + bool safe = ovmSafetyChecker.isBytecodeSafe(_code); + if(safe) { + isSafeCodehash[codehash] = true; + } + return safe; + } + + /** Used to check if bytecode has already been recorded as safe. + * @param _codehash A bytes32 hash of the code + */ + function isRegisteredSafeBytecode( + bytes32 _codehash + ) + override + external + view + returns ( + bool + ) + { + return isSafeCodehash[_codehash] == true; + } +} diff --git a/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol b/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol index ff90584a6..3164d1d5b 100644 --- a/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol +++ b/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; -/* Interface Imports */ +/* Inherited Interface Imports */ import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol"; /** diff --git a/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyCache.sol b/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyCache.sol new file mode 100644 index 000000000..13dfa20c7 --- /dev/null +++ b/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyCache.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.8.0; + +/** + * @title iOVM_SafetyCache + */ +interface iOVM_SafetyCache { + + /********************* + * External Functions * + **********************/ + function checkAndRegisterSafeBytecode(bytes memory _code) external returns (bool); + + function isRegisteredSafeBytecode(bytes32 _codehash) external view returns (bool); + +} diff --git a/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol b/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol index 848e47ddf..91e8465a7 100644 --- a/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol +++ b/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol @@ -10,5 +10,5 @@ interface iOVM_SafetyChecker { * Public Functions * ********************/ - function isBytecodeSafe(bytes calldata _bytecode) external pure returns (bool); + function isBytecodeSafe(bytes calldata _bytecode) external returns (bool); } diff --git a/contracts/test-helpers/Helper_SimpleOvmDeployer.sol b/contracts/test-helpers/Helper_SimpleOvmDeployer.sol new file mode 100644 index 000000000..9eb194d2a --- /dev/null +++ b/contracts/test-helpers/Helper_SimpleOvmDeployer.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT +import { Lib_SafeExecutionManagerWrapper } from "../optimistic-ethereum/libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol"; + +pragma solidity >0.5.0 <0.8.0; + +import "hardhat/console.sol"; + +contract Helper_SimpleOvmDeployer { + + // We load the bytcode to deploy as a constant, in order to avoid having to pass it as calldata during testing + // which gets us a more accurate gas benchmark + // slightly reduced bytecode from "ExchangeRates.sol" as used by Synthetix + // the 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' is replacing the unlinked library address + bytes constant largeBytecode = hex"60806040523480156200001c576000806200001962000ec0565b50505b506040516200677138038062006771833981810160405260a08110156200004d576000806200004a62000ec0565b50505b810190808051929190602001805192919060200180519291906020018051604051939291908464010000000082111562000091576000806200008e62000ec0565b50505b908301906020820185811115620000b257600080620000af62000ec0565b50505b8251866020820283011164010000000082111715620000db57600080620000d862000ec0565b50505b825250602001908051906020019060200280838360005b838110156200010c578082015183820152602001620000f2565b505050509050016040526020018051604051939291908464010000000082111562000141576000806200013e62000ec0565b50505b90830190602082018581111562000162576000806200015f62000ec0565b50505b82518660208202830111640100000000821117156200018b576000806200018862000ec0565b50505b825250602001908051906020019060200280838360005b83811015620001bc578082015183820152602001620001a2565b5050505090500160405250505082808660006001600160a01b0316816001600160a01b031614156200023f5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401604051809103906200023c62000ec0565b50505b8060006001816200024f62000f2d565b816001600160a01b0302191690836001600160a01b03160217906200027362000f8f565b5050507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c6000826040516001600160a01b039283168152911660208201526040908101905180910390a150806002600181620002ce62000f2d565b816001600160a01b0302191690836001600160a01b0316021790620002f262000f8f565b50505050508051825114620003445760405162461bcd60e51b815260040180806020018281038252602f8152602001806200667f602f9139604001915050604051809103906200034162000ec0565b50505b8360056001816200035462000f2d565b816001600160a01b0302191690836001600160a01b03160217906200037862000f8f565b50505062000454631cd554d160e21b73BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB63907af6c06040518163ffffffff1660e01b81526004016020604051808303818680620003c862000fde565b158015620003e057600080620003dd62000ec0565b50505b505a620003ec6200102b565b50505050501580156200040e573d6000803e3d60006200040b62000ec0565b50505b505050506040513d602081101562000430576000806200042d62000ec0565b50505b810190808051925050505a6200044562001121565b6001600160e01b036200048016565b6200047482825a6200046562001121565b6001600160e01b036200057e16565b505050505050620011be565b6000838152600b602052604090206000816200049b62000f2d565b91600183019150620004ac62000f8f565b505050604051604080820181526001600160d81b038416825264ffffffffff831660208084019190915260008681526004909152206000858152600b60205260408120620004f962000f2d565b81526020019081526020016000208151816001816200051762000f2d565b816001600160d81b0302191690836001600160d81b03160217906200053b62000f8f565b505050602082015181600160d81b816200055462000f2d565b8164ffffffffff021916908364ffffffffff160217906200057462000f8f565b5050505050505050565b60008251845114620005cd5760405162461bcd60e51b8152600401808060200182810382526038815260200180620067006038913960400191505060405180910390620005ca62000ec0565b50505b6102585a620005db62001121565b0182106200063a5760405162461bcd60e51b815260206004820152601f60248201527f54696d6520697320746f6f2066617220696e746f2074686520667574757265006044820152606401604051809103906200063762000ec0565b50505b60005b8451811015620007685760008582815181106200065657fe5b602002602001015190508482815181106200066d57fe5b6020026020010151620006bd5760405162461bcd60e51b8152600401808060200182810382526039815260200180620067386039913960400191505060405180910390620006ba62000ec0565b50505b80631cd554d160e21b1415620007105760405162461bcd60e51b8152600401808060200182810382526031815260200180620066ae60319139604001915050604051809103906200070d62000ec0565b50505b62000724816001600160e01b036200083316565b8410156200073357506200075f565b6200075d818684815181106200074557fe5b6020026020010151866001600160e01b036200048016565b505b6001016200063d565b507f1bc0fc8997efa076f59b5ef02c315bc5390f7a6d24d661ce12128c01a3b0ba578484604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015620007d2578082015183820152602001620007b8565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101562000813578082015183820152602001620007f9565b5050505090500194505050505060405180910390a15060015b9392505050565b600062000849826001600160e01b036200085c16565b6020015164ffffffffff1690505b919050565b6200086662001168565b60008281526006602052604081206000906200088162000f2d565b6001600160a01b036101009290920a9004169050801562000a5d576060604051602401604051601f19818303018152604091909152633fabe5a360e21b6020820180516001600160e01b031690911790529050600060606001600160a01b038416836040518082805190602001908083835b60208310620009145780518252601f199092019160209182019101620008f3565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855a6200094e6200117f565b50505050509150503d806000811462000984576040513d603f01601f191681016040523d815291503d6000602084013e62000989565b606091505b5091509150811562000a54576000808060208401845160a0811015620009b957600080620009b662000ec0565b50505b8101908080519291906020018051929190602001805192919060200180519291906020018051509598509396509094506040935050505051604080820190528062000a2c8b62000a1381876001600160e01b0362000b4916565b6001600160501b0388166001600160e01b0362000c4a16565b6001600160d81b031681526020018264ffffffffff1681525097505050505050505062000857565b50505062000b43565b6000838152600b6020526040812062000a7562000f2d565b905062000a8162001168565b600085815260046020526040902060008381526020919091526040902060405160408082019052908160008262000ab762000f2d565b6001600160d81b036101009290920a9004168152602001601b8262000adb62000f2d565b64ffffffffff6101009290920a9004169052509050604051604080820190528062000b1b8784516001600160d81b0316866001600160e01b0362000c4a16565b6001600160d81b03168152602001826020015164ffffffffff16815250935050505062000857565b50919050565b60008082121562000bab5760405162461bcd60e51b815260206004820152601b60248201527f4e656761746976652072617465206e6f7420737570706f72746564000000000060448201526064016040518091039062000ba862000ec0565b50505b600083815260076020526040812060009062000bc662000f2d565b906101000a900460ff1660ff16111562000c41576000838152600760205262000c1960126040832060009062000bfb62000f2d565b906101000a900460ff1660ff1662000df760201b62004da41760201c565b600a0a905062000c38818462000e5f60201b620044ca1790919060201c565b91505062000c44565b50805b92915050565b600062000c5662001191565b600085815260096020526040902060405160a0810160405290818162000c7b62000f2d565b81526020016001820162000c8e62000f2d565b81526020016002820162000ca162000f2d565b815260200160006003830162000cb662000f2d565b60ff6101009290920a9004161515815260200160016003830162000cd962000f2d565b60ff6101009290920a900416151590525090508051158062000cf9575083155b1562000d0957839150506200082c565b6000858152600c6020528492506040812062000d2462000f2d565b905080841015801562000d38575081606001515b1562000d4b578160200151925062000dee565b80841015801562000d5d575081608001515b1562000d70578160400151925062000dee565b600062000d8e6002845162000e5f60201b620044ca1790919060201c565b905085811162000da2576000935062000dbf565b62000dbc868262000df760201b62004da41790919060201c565b93505b8260200151841062000dd8578260200151935062000dec565b8260400151841162000dec57826040015193505b505b50509392505050565b60008282111562000e595760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f77000060448201526064016040518091039062000e5662000ec0565b50505b50900390565b60008262000e705750600062000c44565b8282028284828162000e7e57fe5b04146200082c5760405162461bcd60e51b8152600401808060200182810382526021815260200180620066df602191396040019150506040518091039062000dee5b632a2a7adb598160e01b8152600481016020815285602082015260005b8681101562000efa57808601518282016040015260200162000edd565b506020828760640184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b505050565b6303daa959598160e01b8152836004820152602081602483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051935060005b604081101562000f8a5760008282015260200162000f71565b505050565b6322bd64c0598160e01b8152836004820152846024820152600081604483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b60008152602062000f71565b638435035b598160e01b8152836004820152602081602483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602062000f71565b63ffe73914598160e01b81526200105f565b808083111562000c44575090919050565b808083101562000c44575090919050565b836004820152846024820152606060448201528660648201526084810160005b88811015620010995780880151828201526020016200107f565b506060828960a40184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b815160408301513d6000853e8b8b82606087013350600060045af15059620010f08d3d6200104e565b8c01620010fe81876200103d565b5b82811015620011155760008152602001620010ff565b50929c50505050505050565b63bdbf8c36598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602062000f71565b604051604080820190526000808252602082015290565b638540661f598160e01b81526200105f565b60405160a08101604090815260008083526020830181905290820181905260608201819052608082015290565b6154b180620011ce6000396000f3fe608060405234801561001957600080610016614e7b565b50505b506004361061031d5760003560e01c8063654a60ac116101b0578063935f4abd116100f7578063c2c8a676116100a0578063ce8480ea1161007a578063ce8480ea14610e1a578063de02795e14610e40578063fdadbc7e14610e665761031d565b8063c2c8a67614610c70578063c8e5bbd514610d04578063c8e6f39514610df45761031d565b8063b199c764116100d1578063b199c76414610aeb578063b295ad3414610b33578063bfa005ce14610b6f5761031d565b8063935f4abd14610a79578063ac82f60814610a9f578063af3aea8614610ac55761031d565b80637adbf973116101595780638295016a116101335780638295016a14610a13578063899ffef414610a695780638da5cb5b14610a715761031d565b80637adbf973146109a95780637dc0d1d0146109e55780637f6e9d15146109ed5761031d565b8063741853601161018a578063741853601461097357806379ba50971461097b5780637a018a1e146109835761031d565b8063654a60ac146108c25780637103353e146108f4578063728dec291461091a5761031d565b80632af64bd3116102745780633f0e084f1161021d5780634c36b837116101f75780634c36b8371461088c5780634f72def61461089457806353a47bb7146108ba5761031d565b80633f0e084f146107e65780634308a94f1461082857806345938849146108665761031d565b80632ea913d41161024e5780632ea913d4146107745780633375fcd11461079a57806338aa1b99146107c05761031d565b80632af64bd3146106815780632bed9e0c146106895780632d7371e1146106af5761031d565b80630ee4951b116102d65780632528f0fe116102b05780632528f0fe146105e1578063266da16b146106075780632678df96146106455761031d565b80630ee4951b14610551578063109e46a21461056b5780631627540c146105a35761031d565b806305a046e51161030757806305a046e5146103965780630a7d36d11461047d5780630c71cd23146105115761031d565b80629919c01461032b57806304f3bcec14610365575b600080610328614e7b565b50505b6103516004803603602081101561034a57600080610347614e7b565b50505b5035610e92565b604051901515815260200160405180910390f35b61036d610ead565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61042a600480360360208110156103b5576000806103b2614e7b565b50505b8101906020810181356401000000008111156103d9576000806103d6614e7b565b50505b8201836020820111156103f4576000806103f1614e7b565b50505b8035906020019184602083028401116401000000008311171561041f5760008061041c614e7b565b50505b509092509050610ed9565b60405160208082528190810183818151815260200191508051906020019060200280838360005b83811015610469578082015183820152602001610451565b505050509050019250505060405180910390f35b6103516004803603602081101561049c57600080610499614e7b565b50505b8101906020810181356401000000008111156104c0576000806104bd614e7b565b50505b8201836020820111156104db576000806104d8614e7b565b50505b8035906020019184602083028401116401000000008311171561050657600080610503614e7b565b50505b509092509050610f58565b610537600480360360208110156105305760008061052d614e7b565b50505b503561100b565b604051918252151560208201526040908101905180910390f35b6105596110d4565b60405190815260200160405180910390f35b6105596004803603608081101561058a57600080610587614e7b565b50505b50803590602081013590604081013590606001356110e4565b6105df600480360360208110156105c2576000806105bf614e7b565b50505b503573ffffffffffffffffffffffffffffffffffffffff16611127565b005b61035160048036036020811015610600576000806105fd614e7b565b50505b50356111c8565b610559600480360360a081101561062657600080610623614e7b565b50505b50803590602081013590604081013590606081013590608001356111e8565b61042a6004803603602081101561066457600080610661614e7b565b50505b503573ffffffffffffffffffffffffffffffffffffffff16611255565b61035161136e565b6105df600480360360208110156106a8576000806106a5614e7b565b50505b5035611563565b6106db600480360360408110156106ce576000806106cb614e7b565b50505b50803590602001356116d1565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561071f578082015183820152602001610707565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561075e578082015183820152602001610746565b5050505090500194505050505060405180910390f35b6105596004803603602081101561079357600080610790614e7b565b50505b50356117c2565b610351600480360360208110156107b9576000806107b6614e7b565b50505b50356117ed565b610351600480360360208110156107df576000806107dc614e7b565b50505b50356118eb565b6105df6004803603604081101561080557600080610802614e7b565b50505b508035906020013573ffffffffffffffffffffffffffffffffffffffff166118f9565b61084e6004803603602081101561084757600080610844614e7b565b50505b5035611c94565b60405191825260208201526040908101905180910390f35b6105df6004803603602081101561088557600080610882614e7b565b50505b5035611ce1565b61036d611e78565b610559600480360360208110156108b3576000806108b0614e7b565b50505b5035611e82565b61036d611e8e565b610559600480360360608110156108e1576000806108de614e7b565b50505b5080359060208101359060400135611e9a565b61036d6004803603602081101561091357600080610910614e7b565b50505b5035611eb2565b6109406004803603602081101561093957600080610936614e7b565b50505b5035611ecc565b604051948552602085019390935260408085019290925215156060840152901515608083015260a0909101905180910390f35b6105df611f37565b6105df6121ab565b610559600480360360208110156109a25760008061099f614e7b565b50505b50356123b8565b6105df600480360360208110156109c8576000806109c5614e7b565b50505b503573ffffffffffffffffffffffffffffffffffffffff166123c3565b61036d61248e565b61055960048036036020811015610a0c57600080610a09614e7b565b50505b503561249a565b610a4560048036036060811015610a3257600080610a2f614e7b565b50505b50803590602081013590604001356124b2565b60405180848152602001838152602001828152602001935050505060405180910390f35b61042a6124d2565b61036d61255a565b61055960048036036020811015610a9857600080610a95614e7b565b50505b5035612565565b61055960048036036020811015610abe57600080610abb614e7b565b50505b503561257d565b61035160048036036020811015610ae457600080610ae1614e7b565b50505b50356125ac565b6105df600480360360c0811015610b0a57600080610b07614e7b565b50505b50803590602081013590604081013590606081013590608081013515159060a0013515156125b7565b610b5960048036036020811015610b5257600080610b4f614e7b565b50505b5035612aaf565b60405160ff909116815260200160405180910390f35b61035160048036036060811015610b8e57600080610b8b614e7b565b50505b810190602081018135640100000000811115610bb257600080610baf614e7b565b50505b820183602082011115610bcd57600080610bca614e7b565b50505b80359060200191846020830284011164010000000083111715610bf857600080610bf5614e7b565b50505b919390929091602081019035640100000000811115610c1f57600080610c1c614e7b565b50505b820183602082011115610c3a57600080610c37614e7b565b50505b80359060200191846020830284011164010000000083111715610c6557600080610c62614e7b565b50505b919350915035612ad6565b61042a60048036036020811015610c8f57600080610c8c614e7b565b50505b810190602081018135640100000000811115610cb357600080610cb0614e7b565b50505b820183602082011115610cce57600080610ccb614e7b565b50505b80359060200191846020830284011164010000000083111715610cf957600080610cf6614e7b565b50505b509092509050612b5d565b610d9860048036036020811015610d2357600080610d20614e7b565b50505b810190602081018135640100000000811115610d4757600080610d44614e7b565b50505b820183602082011115610d6257600080610d5f614e7b565b50505b80359060200191846020830284011164010000000083111715610d8d57600080610d8a614e7b565b50505b509092509050612bd2565b604051811515602082015260408082528190810184818151815260200191508051906020019060200280838360005b83811015610ddf578082015183820152602001610dc7565b50505050905001935050505060405180910390f35b6105df60048036036020811015610e1357600080610e10614e7b565b50505b5035612d40565b61055960048036036020811015610e3957600080610e36614e7b565b50505b5035612ea3565b6105df60048036036020811015610e5f57600080610e5c614e7b565b50505b5035612eae565b61084e60048036036040811015610e8557600080610e82614e7b565b50505b508035906020013561315a565b6000610ea582610ea0613172565b613293565b90505b919050565b60006002610eb9614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60608082604051908082528060200260200182016040528015610f06578160200160208202803883390190505b50905060005b83811015610f4e57610f2f858583818110610f2357fe5b905060200201356132de565b828281518110610f3b57fe5b6020908102919091010152600101610f0c565b5090505b92915050565b600080610f63613172565b90506060610fa38585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506132fa92505050565b905060005b84811015610fff57818181518110610fbc57fe5b602002602001015180610fe65750610fe6868683818110610fd957fe5b9050602002013584613293565b15610ff75760019350505050610f52565b600101610fa8565b50600095945050505050565b600080611016614f41565b61101f846135e4565b9050837f735553440000000000000000000000000000000000000000000000000000000014156110755780517affffffffffffffffffffffffffffffffffffffffffffffffffffff169250600091506110cf9050565b8051611093611082613172565b836020015164ffffffffff16613985565b806110aa57506110aa856110a56139a8565b613a5e565b7affffffffffffffffffffffffffffffffffffffffffffffffffffff90911693509150505b915091565b60006110de613172565b90505b90565b600083815b6110f68783600101613be4565b915050801580611107575083850181115b156111145750905061111f565b6001909101906110e9565b949350505050565b61112f613f0a565b806001808061113c614ee6565b8173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790611178614f58565b5050507f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce228160405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a150565b60006111d682610ea0613172565b80610ea55750610ea5826110a56139a8565b6000838614156111f957508361124c565b60006112058785613be4565b50905060006112148685613be4565b509050806112275760009250505061124c565b6112478161123b898563ffffffff613fab16565b9063ffffffff613fc016565b925050505b95945050505050565b60606000600880611264614ee6565b905060405190808252806020026020018201604052801561128f578160200160208202803883390190505b50915060005b6008806112a0614ee6565b9050811015611367576000600882816112b7614ee6565b81106112bf57fe5b906000526020600020016112d1614ee6565b6000818152600660205290915073ffffffffffffffffffffffffffffffffffffffff86169060409020600090611305614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561135e578084848060010195508151811061135157fe5b6020026020010181815250505b50600101611295565b5050919050565b6000606061137a6124d2565b905060005b815181101561155a57600082828151811061139657fe5b602002602001015160008181526003602052909150604090206000906113ba614ee6565b73ffffffffffffffffffffffffffffffffffffffff6101009290920a900416600060026113e5614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166321f8a721836040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260048101919091526024016020604051808303818680611468614fa6565b15801561147d5760008061147a614e7b565b50505b505a611487614ff2565b50505050501580156114a6573d6000803e3d60006114a3614e7b565b50505b505050506040513d60208110156114c5576000806114c2614e7b565b50505b81019080805173ffffffffffffffffffffffffffffffffffffffff169390931415925082915061154090505750600081815260036020526040812060009061150b614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b1561155157600093505050506110e1565b5060010161137f565b50600191505090565b61156b613f0a565b6000818152600660205260408120600090611584614ee6565b73ffffffffffffffffffffffffffffffffffffffff6101009290920a9004169050806115ff5760405162461bcd60e51b815260206004820152601c60248201527f4e6f2061676772656761746f722065786973747320666f72206b6579000000006044820152606401604051809103906115fc614e7b565b50505b6000828152600660205260409020600181611618614ee6565b9073ffffffffffffffffffffffffffffffffffffffff0219169061163a614f58565b50506000828152600760205260409020600181611655614ee6565b9060ff02191690611664614f58565b50506000611673836008613fd5565b905080156116cc577fec70e890fc7db7de4059b114c9093a1f41283d18ffcfbcac45566feea4d4f777838360405191825273ffffffffffffffffffffffffffffffffffffffff1660208201526040908101905180910390a15b505050565b606080826040519080825280602002602001820160405280156116fe578160200160208202803883390190505b5091508260405190808252806020026020018201604052801561172b578160200160208202803883390190505b5090506000611739856140f3565b905060005b848110156117b8576117508683613be4565b85838151811061175c57fe5b6020026020010185848151811061176f57fe5b6020908102919091010191909152528161178b57506117bb9050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091019060010161173e565b50505b9250929050565b600a81816117ce614ee6565b81106117d657fe5b9060005260206000200190506117ea614ee6565b81565b60006117f76150dd565b600083815260096020526040902060405160a0810160405290818161181a614ee6565b81526020016001820161182b614ee6565b81526020016002820161183c614ee6565b815260200160006003830161184f614ee6565b60ff6101009290920a90041615158152602001600160038301611870614ee6565b60ff6101009290920a9004161515905250905080511580611892575080606001515b8061189e575080608001515b156118ad576000915050610ea8565b60006118b88461257d565b90506000811180156118dc57508160200151811015806118dc575081604001518111155b92505050610ea8565b50919050565b6000610ea5826110a56139a8565b611901613f0a565b80600073ffffffffffffffffffffffffffffffffffffffff821663668a0f026040518163ffffffff1660e01b81526004016020604051808303818680611945614fa6565b15801561195a57600080611957614e7b565b50505b505a611964614ff2565b5050505050158015611983573d6000803e3d6000611980614e7b565b50505b505050506040513d60208110156119a25760008061199f614e7b565b50505b81019080805193909310159250611a0b9150505760405162461bcd60e51b815260206004820152601b60248201527f476976656e2041676772656761746f7220697320696e76616c69640000000000604482015260640160405180910390611a08614e7b565b50505b60008173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b81526004016020604051808303818680611a4e614fa6565b158015611a6357600080611a60614e7b565b50505b505a611a6d614ff2565b5050505050158015611a8c573d6000803e3d6000611a89614e7b565b50505b505050506040513d6020811015611aab57600080611aa8614e7b565b50505b81019080805193505050601260ff831611159050611b035760405162461bcd60e51b815260040180806020018281038252603281526020018061541f6032913960400191505060405180910390611b00614e7b565b50505b6000848152600660205260408120600090611b1c614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611bb05783600880600181611b64614ee6565b018082611b6f614f58565b50506000928352917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830191506020902091929101611bac614f58565b5050505b60008481526006602052829060409020600181611bcb614ee6565b8173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790611c07614f58565b50505060008481526007602052819060409020600181611c25614ee6565b8160ff021916908360ff16021790611c3b614f58565b5050507f0bcae573430f69c5361e5d76534d3f61d2d803958778680cd74be9dc6299bc63848360405191825273ffffffffffffffffffffffffffffffffffffffff1660208201526040908101905180910390a150505050565b600080611c9f614f41565b611ca8846135e4565b9050805181602001517affffffffffffffffffffffffffffffffffffffffffffffffffffff909116935064ffffffffff16915050915091565b611ce9614202565b6000611cf48261257d565b11611d4e5760405162461bcd60e51b815260206004820152600c60248201527f52617465206973207a65726f0000000000000000000000000000000000000000604482015260640160405180910390611d4b614e7b565b50505b60008181526004602052604090206000828152600b60205260408120611d72614ee6565b8152602001908152602001600020600081600181611d8e614ee6565b907affffffffffffffffffffffffffffffffffffffffffffffffffffff02191690611db7614f58565b508290507b0100000000000000000000000000000000000000000000000000000081611de1614ee6565b9064ffffffffff02191690611df4614f58565b5050506000828152600b6020526040915020600081611e11614ee6565b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83019150611e3f614f58565b5050507fe69d655565c7ff1353d8eaeea62fb7904fa9696987431ec351be288c865f1ae18160405190815260200160405180910390a150565b60006110de6139a8565b600881816117ce614ee6565b60006001610eb9614ee6565b6000611ea78484846142a2565b509095945050505050565b600660205280600052604060002060009150610eb9614ee6565b6009602052806000526040600020905080611ee5614ee6565b9080600101611ef2614ee6565b9080600201611eff614ee6565b90600060038201611f0e614ee6565b906101000a900460ff169080600301600190611f28614ee6565b906101000a900460ff16905085565b6060611f416124d2565b905060005b81518110156121a7576000828281518110611f5d57fe5b602002602001015190506000806002611f74614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dacb2d0183846040517f5265736f6c766572206d697373696e67207461726765743a2000000000000000602082015260398101919091526059016040516020818303038152906040526040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561204357808201518382015260200161202b565b50505050905090810190601f1680156120705780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818680612089614fa6565b15801561209e5760008061209b614e7b565b50505b505a6120a8614ff2565b50505050501580156120c7573d6000803e3d60006120c4614e7b565b50505b505050506040513d60208110156120e6576000806120e3614e7b565b50505b810190808051600086815260036020529094508493506040925090502060018161210e614ee6565b8173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179061214a614f58565b5050507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68828260405191825273ffffffffffffffffffffffffffffffffffffffff1660208201526040908101905180910390a15050600101611f46565b5050565b600060016121b7614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff165a6121f361510a565b73ffffffffffffffffffffffffffffffffffffffff161461224e5760405162461bcd60e51b81526004018080602001828103825260358152602001806152b5603591396040019150506040518091039061224b614e7b565b50505b7fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c60008061227a614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1660016000906122a4614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9283168152911660208201526040908101905180910390a1600060016122fd614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a8161232a614ee6565b8173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790612366614f58565b5050506000600160006101000a8161237c614ee6565b8173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217906116cc614f58565b6000610ea5826140f3565b6123cb613f0a565b8060056001816123d9614ee6565b8173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790612415614f58565b5050507f3df77beb5db05fcdd70a30fc8adf3f83f9501b68579455adbd100b81809403946005600090612446614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a150565b60006005610eb9614ee6565b600c60205280600052604060002090506117ea614ee6565b60008060006124c28686866142a2565b9250925092505b93509350939050565b6060806124dd6142f4565b90506060600160405190808252806020026020018201604052801561250c578160200160208202803883390190505b5090507f45786368616e67657200000000000000000000000000000000000000000000008160008151811061253d57fe5b6020026020010181815250506125538282614361565b9250505090565b600080610eb9614ee6565b600b60205280600052604060002090506117ea614ee6565b6000612588826135e4565b517affffffffffffffffffffffffffffffffffffffffffffffffffffff1692915050565b6000610ea58261441d565b6125bf613f0a565b6000831161261c5760405162461bcd60e51b815260206004820152601a60248201527f6c6f7765724c696d6974206d7573742062652061626f76652030000000000000604482015260640160405180910390612619614e7b565b50505b8484116126635760405162461bcd60e51b815260040180806020018281038252602781526020018061548a6027913960400191505060405180910390612660614e7b565b50505b61267485600263ffffffff6144ca16565b84106126ba5760405162461bcd60e51b815260040180806020018281038252602e8152602001806153f1602e9139604001915050604051809103906126b7614e7b565b50505b8483106127015760405162461bcd60e51b81526004018080602001828103825260278152602001806153ca60279139604001915050604051809103906126fe614e7b565b50505b81801561270b5750805b156127655760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f7420667265657a6520617420626f7468206c696d69747300000000604482015260640160405180910390612762614e7b565b50505b600086815260096020526040812090508061277e614ee6565b6127dd5786600a80600181612791614ee6565b01808261279c614f58565b50506000928352917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301915060209020919291016127d9614f58565b5050505b8580826127e8614f58565b505050848160010181906127fa614f58565b5050508381600201819061280c614f58565b50505082806128185750815b1561291957826003820160018161282d614ee6565b8160ff02191690831515021790612842614f58565b50839150506003820161010081612857614ee6565b8160ff0219169083151502179061286c614f58565b505050600061287a886140f3565b6000898152600c6020529091508190604090208190612897614f58565b5050507ff72828471e37526c68fd812a1fa6eeff993c3f81bd96c0242dc5b3e144145df088856128c757866128c9565b875b835a6128d361510a565b604051938452602084019290925260408084019190915273ffffffffffffffffffffffffffffffffffffffff90911660608301526080909101905180910390a150612989565b60006003820160018161292a614ee6565b8160ff0219169083151502179061293f614f58565b5060009150506003820161010081612955614ee6565b8160ff0219169083151502179061296a614f58565b5050506000878152600c602052604081208190612985614f58565b5050505b60006129948861257d565b90508015612a56576129a4614532565b73ffffffffffffffffffffffffffffffffffffffff1663ce09694089836040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015260440160006040518083038160008780612a12614fa6565b158015612a2757600080612a24614e7b565b50505b505a612a31615150565b505050505050158015612a51573d6000803e3d6000612a4e614e7b565b50505b505050505b7f37efb38e92b0f94698f6df0c9070e2f00946862a042ac09e34ae8c547684240a888888886040518085815260200184815260200183815260200182815260200194505050505060405180910390a15050505050505050565b600760205280600052604060002060009150612ac9614ee6565b906101000a900460ff1681565b6000612ae0614202565b612b53868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250879150819050602080820201604051908101604052809392919081815260200183836020028082843760009201919091525087925061455d915050565b9695505050505050565b60608082604051908082528060200260200182016040528015612b8a578160200160208202803883390190505b50905060005b83811015610f4e57612bb3858583818110612ba757fe5b9050602002013561257d565b828281518110612bbf57fe5b6020908102919091010152600101612b90565b6060600082604051908082528060200260200182016040528015612c00578160200160208202803883390190505b5091506000612c0d613172565b90506060612c4d8686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506132fa92505050565b905060005b85811015612d3657612c62614f41565b612c7d888884818110612c7157fe5b905060200201356135e4565b905080517affffffffffffffffffffffffffffffffffffffffffffffffffffff16868381518110612caa57fe5b60200260200101818152505084158015612cf65750878783818110612ccb57fe5b905060200201357f735553440000000000000000000000000000000000000000000000000000000014155b15612d2d57828281518110612d0757fe5b602002602001015180612d2a5750612d2a84826020015164ffffffffff16613985565b94505b50600101612c52565b5050509250929050565b612d48613f0a565b6000818152600960205260408120612d5e614ee6565b11612db85760405162461bcd60e51b815260206004820152601860248201527f4e6f20696e766572746564207072696365206578697374730000000000000000604482015260640160405180910390612db5614e7b565b50505b600081815260096020526040902060008082612dd2614f58565b505060018201600090612de3614f58565b505060028201600090612df4614f58565b505060038201600181612e05614ee6565b9060ff02191690612e14614f58565b50506003820161010081612e26614ee6565b9060ff02191690612e35614f58565b505050506000612e4682600a613fd5565b905080156121a7577f37efb38e92b0f94698f6df0c9070e2f00946862a042ac09e34ae8c547684240a8260008060006040518085815260200184815260200183815260200182815260200194505050505060405180910390a15050565b6000610ea5826132de565b60008181526009602052604081209050600081612ec9614ee6565b11612f235760405162461bcd60e51b815260206004820152601e60248201527f43616e6e6f7420667265657a65206e6f6e2d696e766572736520726174650000604482015260640160405180910390612f20614e7b565b50505b600060038201612f31614ee6565b906101000a900460ff16158015612f5d5750600160038201612f51614ee6565b906101000a900460ff16155b612fb65760405162461bcd60e51b815260206004820152601a60248201527f546865207261746520697320616c72656164792066726f7a656e000000000000604482015260640160405180910390612fb3614e7b565b50505b6000612fc18361257d565b9050600081118015612ff3575081600101612fda614ee6565b81101580612ff3575081600201612fef614ee6565b8111155b156131015781600101613004614ee6565b811460038301600181613015614ee6565b8160ff0219169083151502179061302a614f58565b50505081600201613039614ee6565b8114600383016101008161304b614ee6565b8160ff02191690831515021790613060614f58565b505050600061306e846140f3565b6000858152600c602052909150819060409020819061308b614f58565b5050507ff72828471e37526c68fd812a1fa6eeff993c3f81bd96c0242dc5b3e144145df08483835a6130bb61510a565b604051938452602084019290925260408084019190915273ffffffffffffffffffffffffffffffffffffffff90911660608301526080909101905180910390a1506116cc565b60405162461bcd60e51b815260206004820152601260248201527f526174652077697468696e20626f756e64730000000000000000000000000000604482015260640160405180910390613153614e7b565b5050505050565b6000806131678484613be4565b915091509250929050565b600061317c6147f8565b73ffffffffffffffffffffffffffffffffffffffff166323257c2b7f53797374656d53657474696e67730000000000000000000000000000000000007f726174655374616c65506572696f6400000000000000000000000000000000006040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016020604051808303818680613228614fa6565b15801561323d5760008061323a614e7b565b50505b505a613247614ff2565b5050505050158015613266573d6000803e3d6000613263614e7b565b50505b505050506040513d602081101561328557600080613282614e7b565b50505b810190808051935050505090565b6000827f735553440000000000000000000000000000000000000000000000000000000014156132c557506000610f52565b6132d7826132d2856132de565b613985565b9392505050565b60006132e9826135e4565b6020015164ffffffffff1692915050565b606060006133066139a8565b905073ffffffffffffffffffffffffffffffffffffffff8116156135b15760608351604051908082528060200260200182016040528015613351578160200160208202803883390190505b50905060005b84518110156133e7576006600086838151811061337057fe5b60200260200101518152602001908152602001600020600090613391614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff168282815181106133ba57fe5b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613357565b508173ffffffffffffffffffffffffffffffffffffffff16637d723cac826040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b8381101561345457808201518382015260200161343c565b50505050905001925050506000604051808303818680613472614fa6565b15801561348757600080613484614e7b565b50505b505a613491614ff2565b50505050501580156134b0573d6000803e3d60006134ad614e7b565b50505b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015613500576000806134fd614e7b565b50505b810190808051604051939291908464010000000082111561352957600080613526614e7b565b50505b90830190602082018581111561354757600080613544614e7b565b50505b825186602082028301116401000000008211171561356d5760008061356a614e7b565b50505b825250602001908051906020019060200280838360005b8381101561359c578082015183820152602001613584565b505050509050016040525050509250506118e5565b82516040519080825280602002602001820160405280156135dc578160200160208202803883390190505b509392505050565b6135ec614f41565b6000828152600660205260408120600090613605614ee6565b73ffffffffffffffffffffffffffffffffffffffff6101009290920a900416905080156138775760606040516024016040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08183030181526040919091527ffeaf968c000000000000000000000000000000000000000000000000000000006020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16909117905290506000606073ffffffffffffffffffffffffffffffffffffffff8416836040518082805190602001908083835b6020831061371957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016136dc565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855a613751614ff2565b50505050509150503d80600081146137a3576040513d603f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01681016040523d815291503d6000602084013e6137a8565b606091505b5091509150811561386f576000808060208401845160a08110156137d4576000806137d1614e7b565b50505b810190808051929190602001805192919060200180519291906020018051929190602001805150959850939650909450604093505050505180604001604052806138348b6138228d87614823565b8769ffffffffffffffffffff166148fb565b7affffffffffffffffffffffffffffffffffffffffffffffffffffff1681526020018264ffffffffff16815250975050505050505050610ea8565b5050506118e5565b6000838152600b6020526040812061388d614ee6565b9050613897614f41565b60008581526004602052604090206000838152602091909152604090206040516040808201905290816000826138cb614ee6565b7affffffffffffffffffffffffffffffffffffffffffffffffffffff6101009290920a9004168152602001601b82613901614ee6565b64ffffffffff6101009290920a9004169052509050604051604080820190528061394a8784517affffffffffffffffffffffffffffffffffffffffffffffffffffff16866148fb565b7affffffffffffffffffffffffffffffffffffffffffffffffffffff168152602001826020015164ffffffffff168152509350505050610ea8565b60005a613990615216565b6139a0838563ffffffff614a7816565b109392505050565b60006139b26147f8565b73ffffffffffffffffffffffffffffffffffffffff16639ee5955a7f53797374656d53657474696e67730000000000000000000000000000000000007f61676772656761746f725761726e696e67466c616773000000000000000000006040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016020604051808303818680613228614fa6565b6000827f73555344000000000000000000000000000000000000000000000000000000001415613a9057506000610f52565b6000838152600660205260408120600090613aa9614ee6565b73ffffffffffffffffffffffffffffffffffffffff6101009290920a9004169050801580613aeb575073ffffffffffffffffffffffffffffffffffffffff8316155b15613afa576000915050610f52565b8273ffffffffffffffffffffffffffffffffffffffff1663357e47fe826040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016020604051808303818680613b76614fa6565b158015613b8b57600080613b88614e7b565b50505b505a613b95614ff2565b5050505050158015613bb4573d6000803e3d6000613bb1614e7b565b50505b505050506040513d6020811015613bd357600080613bd0614e7b565b50505b810190808051979650505050505050565b60008281526006602052808060408120600090613bff614ee6565b73ffffffffffffffffffffffffffffffffffffffff6101009290920a90041690508015613e395760608460405160248101919091526044016040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08183030181526040919091527f9a6fc8f5000000000000000000000000000000000000000000000000000000006020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16909117905290506000606073ffffffffffffffffffffffffffffffffffffffff8416836040518082805190602001908083835b60208310613d1c57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613cdf565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855a613d54614ff2565b50505050509150503d8060008114613da6576040513d603f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01681016040523d815291503d6000602084013e613dab565b606091505b50915091508115613e315760008060208301835160a0811015613dd657600080613dd3614e7b565b50505b8101908080519291906020018051929190602001805192919060200180519291906020018051906020019092919050505050935050925050613e228a613e1c8c85614823565b8b6148fb565b975095506117bb945050505050565b505050613f02565b613e41614f41565b6000868152600460205260409020600086815260209190915260409020604051604080820190529081600082613e75614ee6565b7affffffffffffffffffffffffffffffffffffffffffffffffffffff6101009290920a9004168152602001601b82613eab614ee6565b64ffffffffff6101009290920a9004169052509050613ee98682517affffffffffffffffffffffffffffffffffffffffffffffffffffff16876148fb565b816020015190945064ffffffffff1692506117bb915050565b509250929050565b600080613f15614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff165a613f5161510a565b73ffffffffffffffffffffffffffffffffffffffff1614613fa95760405162461bcd60e51b815260040180806020018281038252602f815260200180615342602f9139604001915050604051809103906121a7614e7b565b565b60006132d78383670de0b6b3a7640000614ad7565b60006132d78383670de0b6b3a7640000614b14565b6000805b8280613fe3614ee6565b90508110156140e95783838281613ff8614ee6565b811061400057fe5b90600052602060002001614012614ee6565b14156140e157828181614023614ee6565b811061402b57fe5b90600052602060002001600090614040614f58565b5050826001848061404f614ee6565b9050038161405b614ee6565b811061406357fe5b90600052602060002001614075614ee6565b838281614080614ee6565b811061408857fe5b90600052602060002001819061409c614f58565b50505082806140a9614ee6565b906140d6907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830161525c565b506001915050610f52565b600101613fd9565b5060009392505050565b60008181526006602052806040812060009061410d614ee6565b73ffffffffffffffffffffffffffffffffffffffff6101009290920a900416905080156141e4578073ffffffffffffffffffffffffffffffffffffffff1663668a0f026040518163ffffffff1660e01b81526004016020604051808303818680614175614fa6565b15801561418a57600080614187614e7b565b50505b505a614194614ff2565b50505050501580156141b3573d6000803e3d60006141b0614e7b565b50505b505050506040513d60208110156141d2576000806141cf614e7b565b50505b8101908080519450610ea89350505050565b6000838152600b602052604090206141fa614ee6565b915050610ea8565b6000600561420e614ee6565b906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff165a61424a61510a565b73ffffffffffffffffffffffffffffffffffffffff1614613fa95760405162461bcd60e51b815260040180806020018281038252602781526020018061531b60279139604001915050604051809103906121a7614e7b565b60008060006142b08661257d565b9150838614156142c45750839150806124c9565b6142cd8461257d565b905080156124c9576142e98161123b878563ffffffff613fab16565b925093509350939050565b60606001604051908082528060200260200182016040528015614321578160200160208202803883390190505b5090507f466c657869626c6553746f7261676500000000000000000000000000000000008160008151811061435257fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015614391578160200160208202803883390190505b50905060005b83518110156143d3578381815181106143ac57fe5b60200260200101518282815181106143c057fe5b6020908102919091010152600101614397565b5060005b8251811015614416578281815181106143ec57fe5b602002602001015182828651018151811061440357fe5b60209081029190910101526001016143d7565b5092915050565b60006144276150dd565b600083815260096020526040902060405160a0810160405290818161444a614ee6565b81526020016001820161445b614ee6565b81526020016002820161446c614ee6565b815260200160006003830161447f614ee6565b60ff6101009290920a900416151581526020016001600383016144a0614ee6565b60ff6101009290920a900416151590525090506060810151806132d7575080608001519392505050565b6000826144d957506000610f52565b828202828482816144e657fe5b04146132d75760405162461bcd60e51b81526004018080602001828103825260218152602001806153716021913960400191505060405180910390614529614e7b565b50509392505050565b60006110de7f45786368616e6765720000000000000000000000000000000000000000000000614b46565b600082518451146145a85760405162461bcd60e51b815260040180806020018281038252603881526020018061539260389139604001915050604051809103906145a5614e7b565b50505b6102585a6145b4615216565b0182106146105760405162461bcd60e51b815260206004820152601f60248201527f54696d6520697320746f6f2066617220696e746f20746865206675747572650060448201526064016040518091039061460d614e7b565b50505b60005b845181101561473257600085828151811061462a57fe5b6020026020010151905084828151811061464057fe5b602002602001015161468c5760405162461bcd60e51b81526004018080602001828103825260398152602001806154516039913960400191505060405180910390614689614e7b565b50505b807f735553440000000000000000000000000000000000000000000000000000000014156146f45760405162461bcd60e51b81526004018080602001828103825260318152602001806152ea60319139604001915050604051809103906146f1614e7b565b50505b6146fd816132de565b84101561470a575061472a565b6147288186848151811061471a57fe5b602002602001015186614c60565b505b600101614613565b507f1bc0fc8997efa076f59b5ef02c315bc5390f7a6d24d661ce12128c01a3b0ba5784846040518080602001806020018381038352858181518152602001915080519060"; + + // A fallback function that allows us to choose between deploying two different initCodes + function deploy(uint256 selection) + external + { + bytes memory prefix = hex'600D380380600D6000396000f3'; + bytes memory initCode; + if(selection == 0) { + // the resulting deployed bytecode is 0x00 + // do concat to be clear + bytes memory runtimeCode = hex'00'; + initCode = abi.encodePacked(prefix, runtimeCode); + } else if(selection == 1){ + initCode = abi.encodePacked(prefix, largeBytecode); + } + + address addr = Lib_SafeExecutionManagerWrapper.safeCREATE(gasleft(), initCode); + } +} diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager.gas-spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager.gas-spec.ts index f3ed69447..b4f620780 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager.gas-spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager.gas-spec.ts @@ -3,7 +3,7 @@ import { deployContractCode } from '../../../helpers/utils' /* External Imports */ import { ethers } from 'hardhat' -import { Contract, ContractFactory, Signer } from 'ethers' +import { BigNumber, Contract, ContractFactory, Signer } from 'ethers' import { smockit, MockContract } from '@eth-optimism/smock' /* Internal Imports */ @@ -12,6 +12,7 @@ import { NON_ZERO_ADDRESS, NON_NULL_BYTES32, GasMeasurement, + DUMMY_BYTES32, } from '../../../helpers' const DUMMY_GASMETERCONFIG = { @@ -30,85 +31,88 @@ const QUEUE_ORIGIN = { L1TOL2_QUEUE: 1, } -const DUMMY_TRANSACTION = { - timestamp: 111111111111, - blockNumber: 20, - l1QueueOrigin: QUEUE_ORIGIN.SEQUENCER_QUEUE, - l1TxOrigin: NON_ZERO_ADDRESS, - entrypoint: NON_ZERO_ADDRESS, // update this below - gasLimit: 10_000_000, - data: 0, +const getCreateAddress = async (stateManager: Contract, creator: string) => { + const creatorNonce = await stateManager.getAccountNonce(creator) + const createAddress = ethers.utils.getContractAddress({ + from: creator, + nonce: creatorNonce, + }) + return createAddress } -describe('OVM_ExecutionManager gas consumption', () => { - let wallet: Signer - before(async () => { - ;[wallet] = await ethers.getSigners() - }) +describe('OVM_ExecutionManager Benchmarks', () => { + describe('em.run() benchmark: executing a minimal contract', async () => { + let wallet: Signer + let Factory__OVM_ExecutionManager: ContractFactory + let OVM_ExecutionManager: Contract + let MOCK__STATE_MANAGER: MockContract + let AddressManager: Contract + let targetContractAddress: string + let gasMeasurement: GasMeasurement + let DUMMY_TRANSACTION + before(async () => { + ;[wallet] = await ethers.getSigners() + Factory__OVM_ExecutionManager = await ethers.getContractFactory( + 'OVM_ExecutionManager' + ) - let Factory__OVM_ExecutionManager: ContractFactory - let MOCK__STATE_MANAGER: MockContract - let AddressManager: Contract - let targetContractAddress: string - let gasMeasurement: GasMeasurement - before(async () => { - Factory__OVM_ExecutionManager = await ethers.getContractFactory( - 'OVM_ExecutionManager' - ) - - // Deploy a simple contract that just returns successfully with no data - targetContractAddress = await deployContractCode( - '60206001f3', - wallet, - 10_000_000 - ) - DUMMY_TRANSACTION.entrypoint = targetContractAddress - - AddressManager = await makeAddressManager() - - // deploy the state manager and mock it for the state transitioner - MOCK__STATE_MANAGER = await smockit( - await (await ethers.getContractFactory('OVM_StateManager')).deploy( - NON_ZERO_ADDRESS - ) - ) - - // Setup the SM to satisfy all the checks executed during EM.run() - MOCK__STATE_MANAGER.smocked.isAuthenticated.will.return.with(true) - MOCK__STATE_MANAGER.smocked.getAccountEthAddress.will.return.with( - targetContractAddress - ) - MOCK__STATE_MANAGER.smocked.hasAccount.will.return.with(true) - MOCK__STATE_MANAGER.smocked.testAndSetAccountLoaded.will.return.with(true) - - await AddressManager.setAddress( - 'OVM_StateManagerFactory', - MOCK__STATE_MANAGER.address - ) - - gasMeasurement = new GasMeasurement() - await gasMeasurement.init(wallet) - }) + DUMMY_TRANSACTION = { + timestamp: 111111111111, + blockNumber: 20, + l1QueueOrigin: QUEUE_ORIGIN.SEQUENCER_QUEUE, + l1TxOrigin: NON_ZERO_ADDRESS, + entrypoint: NON_ZERO_ADDRESS, // update this below + gasLimit: 10_000_000, + data: 0, + } - let OVM_ExecutionManager: Contract - beforeEach(async () => { - OVM_ExecutionManager = ( - await Factory__OVM_ExecutionManager.deploy( - AddressManager.address, - DUMMY_GASMETERCONFIG, - DUMMY_GLOBALCONTEXT + // Deploy a simple contract that just returns successfully with no data + targetContractAddress = await deployContractCode( + '60206001f3', + wallet, + 10_000_000 + ) + DUMMY_TRANSACTION.entrypoint = targetContractAddress + + AddressManager = await makeAddressManager() + + // deploy the state manager and mock it for the state transitioner + MOCK__STATE_MANAGER = await smockit( + await (await ethers.getContractFactory('OVM_StateManager')).deploy( + NON_ZERO_ADDRESS + ) ) - ).connect(wallet) - }) - describe('Measure cost of a very simple contract', async () => { + // Setup the SM to satisfy all the checks executed during EM.run() + MOCK__STATE_MANAGER.smocked.isAuthenticated.will.return.with(true) + MOCK__STATE_MANAGER.smocked.getAccountEthAddress.will.return.with( + targetContractAddress + ) + MOCK__STATE_MANAGER.smocked.hasAccount.will.return.with(true) + MOCK__STATE_MANAGER.smocked.testAndSetAccountLoaded.will.return.with(true) + + await AddressManager.setAddress( + 'OVM_StateManagerFactory', + MOCK__STATE_MANAGER.address + ) + + gasMeasurement = new GasMeasurement() + await gasMeasurement.init(wallet) + OVM_ExecutionManager = ( + await Factory__OVM_ExecutionManager.deploy( + AddressManager.address, + DUMMY_GASMETERCONFIG, + DUMMY_GLOBALCONTEXT + ) + ).connect(wallet) + }) it('Gas cost of run', async () => { const gasCost = await gasMeasurement.getGasCost( OVM_ExecutionManager, 'run', [DUMMY_TRANSACTION, MOCK__STATE_MANAGER.address] ) - console.log(`calculated gas cost of ${gasCost}`) + console.log(` calculated gas cost of ${gasCost}`) const benchmark: number = 226_516 expect(gasCost).to.be.lte(benchmark) @@ -118,4 +122,216 @@ describe('OVM_ExecutionManager gas consumption', () => { ) }) }) + describe('em.run() benchmark: contract deployment', async () => { + let Helper_SimpleDeployer: Contract + let wallet: Signer + let OVM_SafetyChecker: Contract + let OVM_SafetyCache: Contract + let MOCK__OVM_DeployerWhitelist: MockContract + + let OVM_StateManager: Contract + let AddressManager: Contract + let gasMeasurement: GasMeasurement + let OVM_ExecutionManager: Contract + let DUMMY_TRANSACTION + before(async () => { + ;[wallet] = await ethers.getSigners() + + AddressManager = await makeAddressManager() + + // Deploy Safety Checker and register it with the Address Manager + OVM_SafetyChecker = await ( + await ethers.getContractFactory('OVM_SafetyChecker') + ).deploy() + await AddressManager.setAddress( + 'OVM_SafetyChecker', + OVM_SafetyChecker.address + ) + + // Deploy Safety Cache and register it with the Address Manager + OVM_SafetyCache = await ( + await ethers.getContractFactory('OVM_SafetyCache') + ).deploy(AddressManager.address) + await AddressManager.setAddress( + 'OVM_SafetyCache', + OVM_SafetyCache.address + ) + + // Setup Mock Deployer Whitelist and register it with the Address Manager + MOCK__OVM_DeployerWhitelist = await smockit( + await ethers.getContractFactory('OVM_DeployerWhitelist') + ) + MOCK__OVM_DeployerWhitelist.smocked.isDeployerAllowed.will.return.with( + true + ) + await AddressManager.setAddress( + 'OVM_DeployerWhitelist', + MOCK__OVM_DeployerWhitelist.address + ) + + // Setup the EM + OVM_ExecutionManager = await ( + await ethers.getContractFactory('OVM_ExecutionManager') + ).deploy( + AddressManager.address, + DUMMY_GASMETERCONFIG, + DUMMY_GLOBALCONTEXT + ) + + // Deploy GasMeasurement utility + gasMeasurement = new GasMeasurement() + await gasMeasurement.init(wallet) + + // Setup the State Manger and modify it to allow execution to proceed + OVM_StateManager = await ( + await ethers.getContractFactory('OVM_StateManager') + ).deploy(await wallet.getAddress()) + + // Setup the SM to satisfy all the checks executed during EM.run() + await OVM_StateManager.putAccount( + '0x4200000000000000000000000000000000000002', + { + nonce: BigNumber.from(123), + balance: BigNumber.from(456), + storageRoot: DUMMY_BYTES32[0], + codeHash: DUMMY_BYTES32[1], + ethAddress: MOCK__OVM_DeployerWhitelist.address, + } + ) + await OVM_StateManager.setExecutionManager(OVM_ExecutionManager.address) + + // Deploy a simple OVM-safe contract that just deploys another contract + Helper_SimpleDeployer = await ( + await ethers.getContractFactory('Helper_SimpleOvmDeployer') + ).deploy() + + DUMMY_TRANSACTION = { + timestamp: 111111111111, + blockNumber: 20, + l1QueueOrigin: QUEUE_ORIGIN.SEQUENCER_QUEUE, + l1TxOrigin: NON_ZERO_ADDRESS, + entrypoint: Helper_SimpleDeployer.address, + gasLimit: 10_000_000, + data: Helper_SimpleDeployer.interface.encodeFunctionData( + 'deploy(uint256)', + [0] + ), + } + await OVM_StateManager.putAccount(Helper_SimpleDeployer.address, { + nonce: BigNumber.from(123), + balance: BigNumber.from(456), + storageRoot: DUMMY_BYTES32[0], + codeHash: DUMMY_BYTES32[1], + ethAddress: Helper_SimpleDeployer.address, + }) + }) + + it('Gas Benchmark: un-cached minimal contract deployment', async () => { + const createAddr = await getCreateAddress( + OVM_StateManager, + Helper_SimpleDeployer.address + ) + + // Set destination for first contract deployment + await OVM_StateManager.putEmptyAccount(createAddr) + const tx = await OVM_ExecutionManager.run( + DUMMY_TRANSACTION, + OVM_StateManager.address + ) + await tx.wait() + const gasCost = (await ethers.provider.getTransactionReceipt(tx.hash)) + .gasUsed + console.log(` calculated gas cost of ${gasCost}`) + + const benchmark: number = 581_993 + expect(gasCost).to.be.lte(benchmark) + expect(gasCost).to.be.gte( + benchmark - 1_000, + 'Gas cost has significantly decreased, consider updating the benchmark to reflect the change' + ) + }) + + it('Gas Benchmark: cached minimal contract deployment', async () => { + // Set destination for second contract deployment + const createAddr = await getCreateAddress( + OVM_StateManager, + Helper_SimpleDeployer.address + ) + await OVM_StateManager.putEmptyAccount(createAddr) + + // run the exact same flow as the previous. This time the Safety Cache should recognize the string. + const tx = await OVM_ExecutionManager.run( + DUMMY_TRANSACTION, + OVM_StateManager.address + ) + await tx.wait() + const gasCost = (await ethers.provider.getTransactionReceipt(tx.hash)) + .gasUsed + console.log(` calculated gas cost of ${gasCost}`) + + const benchmark: number = 415_329 + expect(gasCost).to.be.lte(benchmark) + expect(gasCost).to.be.gte( + benchmark - 1_000, + 'Gas cost has significantly decreased, consider updating the benchmark to reflect the change' + ) + }) + + it('Gas Benchmark: un-cached larger contract deployment ', async () => { + DUMMY_TRANSACTION.data = Helper_SimpleDeployer.interface.encodeFunctionData( + 'deploy(uint256)', + [1] + ) + + const createAddr = await getCreateAddress( + OVM_StateManager, + Helper_SimpleDeployer.address + ) + // Set destination for first contract deployment + await OVM_StateManager.putEmptyAccount(createAddr) + const tx = await OVM_ExecutionManager.run( + DUMMY_TRANSACTION, + OVM_StateManager.address + ) + await tx.wait() + const gasCost = (await ethers.provider.getTransactionReceipt(tx.hash)) + .gasUsed + console.log(` calculated gas cost of ${gasCost}`) + + const benchmark: number = 7_044_545 + expect(gasCost).to.be.lte(benchmark) + expect(gasCost).to.be.gte( + benchmark - 1_000, + 'Gas cost has significantly decreased, consider updating the benchmark to reflect the change' + ) + }) + + it('Gas Benchmark: cached larger contract deployment ', async () => { + DUMMY_TRANSACTION.data = Helper_SimpleDeployer.interface.encodeFunctionData( + 'deploy(uint256)', + [1] + ) + // Set destination for contract deployment + const createAddr = await getCreateAddress( + OVM_StateManager, + Helper_SimpleDeployer.address + ) + await OVM_StateManager.putEmptyAccount(createAddr) + const tx = await OVM_ExecutionManager.run( + DUMMY_TRANSACTION, + OVM_StateManager.address + ) + await tx.wait() + const gasCost = (await ethers.provider.getTransactionReceipt(tx.hash)) + .gasUsed + console.log(` calculated gas cost of ${gasCost}`) + + const benchmark: number = 5_537_215 + expect(gasCost).to.be.lte(benchmark) + expect(gasCost).to.be.gte( + benchmark - 1_000, + 'Gas cost has significantly decreased, consider updating the benchmark to reflect the change' + ) + }) + }) }) diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/context-opcodes.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/context-opcodes.spec.ts index bddcd4baa..eae7ef693 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/context-opcodes.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/context-opcodes.spec.ts @@ -29,7 +29,7 @@ const test_contextOpcodes: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/nuisance-gas.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/nuisance-gas.spec.ts index 2f1fd9f58..6a80bf423 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/nuisance-gas.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/nuisance-gas.spec.ts @@ -22,7 +22,7 @@ const test_nuisanceGas: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCALL.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCALL.spec.ts index 6ff25e814..6749a3ebd 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCALL.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCALL.spec.ts @@ -18,7 +18,7 @@ const test_ovmCALL: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATE.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATE.spec.ts index 849abb166..79014851c 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATE.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATE.spec.ts @@ -39,7 +39,7 @@ const test_ovmCREATE: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATEEOA.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATEEOA.spec.ts index 09ad78d59..39f3477e2 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATEEOA.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATEEOA.spec.ts @@ -16,7 +16,7 @@ const test_ovmCREATEEOA: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmDELEGATECALL.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmDELEGATECALL.spec.ts index a6d114c75..c63cd00b1 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmDELEGATECALL.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmDELEGATECALL.spec.ts @@ -16,7 +16,7 @@ const test_ovmDELEGATECALL: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmREVERT.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmREVERT.spec.ts index fb5590c90..90c11425c 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmREVERT.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmREVERT.spec.ts @@ -12,7 +12,7 @@ const test_ovmREVERT: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSLOAD.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSLOAD.spec.ts index eb401998a..6f71af6b4 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSLOAD.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSLOAD.spec.ts @@ -13,7 +13,7 @@ const test_ovmSLOAD: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts index 33b507805..78d1e2939 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts @@ -15,7 +15,7 @@ const test_ovmSTATICCALL: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/contracts/OVM/execution/OVM_ExecutionManager/run.spec.ts b/test/contracts/OVM/execution/OVM_ExecutionManager/run.spec.ts index 18cfd8afe..ae4eb260a 100644 --- a/test/contracts/OVM/execution/OVM_ExecutionManager/run.spec.ts +++ b/test/contracts/OVM/execution/OVM_ExecutionManager/run.spec.ts @@ -27,7 +27,7 @@ const test_run: TestDefinition = { preState: { ExecutionManager: { ovmStateManager: '$OVM_STATE_MANAGER', - ovmSafetyChecker: '$OVM_SAFETY_CHECKER', + ovmSafetyCache: '$OVM_SAFETY_CACHE', messageRecord: { nuisanceGasLeft: OVM_TX_GAS_LIMIT, }, diff --git a/test/helpers/test-runner/test-runner.ts b/test/helpers/test-runner/test-runner.ts index 27fcd2e74..62a467765 100644 --- a/test/helpers/test-runner/test-runner.ts +++ b/test/helpers/test-runner/test-runner.ts @@ -43,6 +43,7 @@ export class ExecutionManagerTestRunner { private snapshot: string private contracts: { OVM_SafetyChecker: Contract + OVM_SafetyCache: Contract OVM_StateManager: ModifiableContract OVM_ExecutionManager: ModifiableContract Helper_TestRunner: Contract @@ -50,6 +51,7 @@ export class ExecutionManagerTestRunner { OVM_DeployerWhitelist: Contract } = { OVM_SafetyChecker: undefined, + OVM_SafetyCache: undefined, OVM_StateManager: undefined, OVM_ExecutionManager: undefined, Helper_TestRunner: undefined, @@ -189,6 +191,7 @@ export class ExecutionManagerTestRunner { await ethers.getContractFactory('Lib_AddressManager') ).deploy() + // Setup SafetyChecker const SafetyChecker = await ( await ethers.getContractFactory('OVM_SafetyChecker') ).deploy() @@ -203,12 +206,30 @@ export class ExecutionManagerTestRunner { this.contracts.OVM_SafetyChecker.address ) + // Setup SafetyCache + const SafetyCache = await ( + await ethers.getContractFactory('OVM_SafetyCache') + ).deploy(AddressManager.address) + + const MockSafetyCache = await smockit(SafetyCache) + MockSafetyCache.smocked.isRegisteredSafeBytecode.will.return.with(true) + MockSafetyCache.smocked.checkAndRegisterSafeBytecode.will.return.with(true) + + this.contracts.OVM_SafetyCache = MockSafetyCache + + await AddressManager.setAddress( + 'OVM_SafetyCache', + this.contracts.OVM_SafetyCache.address + ) + + // Setup DeployerWhitelist const DeployerWhitelist = await ( await ethers.getContractFactory('OVM_DeployerWhitelist') ).deploy() this.contracts.OVM_DeployerWhitelist = DeployerWhitelist + // Setup EM this.contracts.OVM_ExecutionManager = await ( await smoddit('OVM_ExecutionManager') ).deploy( @@ -224,6 +245,7 @@ export class ExecutionManagerTestRunner { } ) + // Setup SM this.contracts.OVM_StateManager = await ( await smoddit('OVM_StateManager') ).deploy(await this.contracts.OVM_ExecutionManager.signer.getAddress()) @@ -252,6 +274,8 @@ export class ExecutionManagerTestRunner { return this.contracts.OVM_ExecutionManager.address } else if (kv === '$OVM_STATE_MANAGER') { return this.contracts.OVM_StateManager.address + } else if (kv === '$OVM_SAFETY_CACHE') { + return this.contracts.OVM_SafetyCache.address } else if (kv === '$OVM_SAFETY_CHECKER') { return this.contracts.OVM_SafetyChecker.address } else if (kv === '$OVM_CALL_HELPER') {