Commit be0011d2 authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: run forge fmt

parent 2ef045ce
...@@ -121,7 +121,7 @@ contract Deploy is Deployer { ...@@ -121,7 +121,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the AddressManager /// @notice Deploy the AddressManager
function deployAddressManager() broadcast() public returns (address) { function deployAddressManager() public broadcast returns (address) {
AddressManager manager = new AddressManager(); AddressManager manager = new AddressManager();
require(manager.owner() == msg.sender); require(manager.owner() == msg.sender);
...@@ -131,7 +131,7 @@ contract Deploy is Deployer { ...@@ -131,7 +131,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the ProxyAdmin /// @notice Deploy the ProxyAdmin
function deployProxyAdmin() broadcast() public returns (address) { function deployProxyAdmin() public broadcast returns (address) {
ProxyAdmin admin = new ProxyAdmin({ ProxyAdmin admin = new ProxyAdmin({
_owner: msg.sender _owner: msg.sender
}); });
...@@ -150,7 +150,7 @@ contract Deploy is Deployer { ...@@ -150,7 +150,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L1StandardBridgeProxy /// @notice Deploy the L1StandardBridgeProxy
function deployL1StandardBridgeProxy() broadcast() public returns (address) { function deployL1StandardBridgeProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
L1ChugSplashProxy proxy = new L1ChugSplashProxy(proxyAdmin); L1ChugSplashProxy proxy = new L1ChugSplashProxy(proxyAdmin);
...@@ -163,7 +163,7 @@ contract Deploy is Deployer { ...@@ -163,7 +163,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L2OutputOracleProxy /// @notice Deploy the L2OutputOracleProxy
function deployL2OutputOracleProxy() broadcast() public returns (address) { function deployL2OutputOracleProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({ Proxy proxy = new Proxy({
_admin: proxyAdmin _admin: proxyAdmin
...@@ -178,7 +178,7 @@ contract Deploy is Deployer { ...@@ -178,7 +178,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L1CrossDomainMessengerProxy /// @notice Deploy the L1CrossDomainMessengerProxy
function deployL1CrossDomainMessengerProxy() broadcast() public returns (address) { function deployL1CrossDomainMessengerProxy() public broadcast returns (address) {
AddressManager addressManager = AddressManager(mustGetAddress("AddressManager")); AddressManager addressManager = AddressManager(mustGetAddress("AddressManager"));
string memory contractName = "OVM_L1CrossDomainMessenger"; string memory contractName = "OVM_L1CrossDomainMessenger";
ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, contractName); ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, contractName);
...@@ -197,7 +197,7 @@ contract Deploy is Deployer { ...@@ -197,7 +197,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the OptimismPortalProxy /// @notice Deploy the OptimismPortalProxy
function deployOptimismPortalProxy() broadcast() public returns (address) { function deployOptimismPortalProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({ Proxy proxy = new Proxy({
_admin: proxyAdmin _admin: proxyAdmin
...@@ -213,7 +213,7 @@ contract Deploy is Deployer { ...@@ -213,7 +213,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the OptimismMintableERC20FactoryProxy /// @notice Deploy the OptimismMintableERC20FactoryProxy
function deployOptimismMintableERC20FactoryProxy() broadcast() public returns (address) { function deployOptimismMintableERC20FactoryProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({ Proxy proxy = new Proxy({
_admin: proxyAdmin _admin: proxyAdmin
...@@ -229,7 +229,7 @@ contract Deploy is Deployer { ...@@ -229,7 +229,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L1ERC721BridgeProxy /// @notice Deploy the L1ERC721BridgeProxy
function deployL1ERC721BridgeProxy() broadcast() public returns (address) { function deployL1ERC721BridgeProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({ Proxy proxy = new Proxy({
_admin: proxyAdmin _admin: proxyAdmin
...@@ -245,7 +245,7 @@ contract Deploy is Deployer { ...@@ -245,7 +245,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the SystemConfigProxy /// @notice Deploy the SystemConfigProxy
function deploySystemConfigProxy() broadcast() public returns (address) { function deploySystemConfigProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({ Proxy proxy = new Proxy({
_admin: proxyAdmin _admin: proxyAdmin
...@@ -261,7 +261,7 @@ contract Deploy is Deployer { ...@@ -261,7 +261,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the DisputeGameFactoryProxy /// @notice Deploy the DisputeGameFactoryProxy
function deployDisputeGameFactoryProxy() onlyDevnet broadcast() public returns (address) { function deployDisputeGameFactoryProxy() public onlyDevnet broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({ Proxy proxy = new Proxy({
_admin: proxyAdmin _admin: proxyAdmin
...@@ -277,7 +277,7 @@ contract Deploy is Deployer { ...@@ -277,7 +277,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L1CrossDomainMessenger /// @notice Deploy the L1CrossDomainMessenger
function deployL1CrossDomainMessenger() broadcast() public returns (address) { function deployL1CrossDomainMessenger() public broadcast returns (address) {
L1CrossDomainMessenger messenger = new L1CrossDomainMessenger(); L1CrossDomainMessenger messenger = new L1CrossDomainMessenger();
require(address(messenger.PORTAL()) == address(0)); require(address(messenger.PORTAL()) == address(0));
...@@ -293,7 +293,7 @@ contract Deploy is Deployer { ...@@ -293,7 +293,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the OptimismPortal /// @notice Deploy the OptimismPortal
function deployOptimismPortal() broadcast() public returns (address) { function deployOptimismPortal() public broadcast returns (address) {
OptimismPortal portal = new OptimismPortal(); OptimismPortal portal = new OptimismPortal();
require(address(portal.L2_ORACLE()) == address(0)); require(address(portal.L2_ORACLE()) == address(0));
...@@ -308,7 +308,7 @@ contract Deploy is Deployer { ...@@ -308,7 +308,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L2OutputOracle /// @notice Deploy the L2OutputOracle
function deployL2OutputOracle() broadcast() public returns (address) { function deployL2OutputOracle() public broadcast returns (address) {
L2OutputOracle oracle = new L2OutputOracle({ L2OutputOracle oracle = new L2OutputOracle({
_submissionInterval: cfg.l2OutputOracleSubmissionInterval(), _submissionInterval: cfg.l2OutputOracleSubmissionInterval(),
_l2BlockTime: cfg.l2BlockTime(), _l2BlockTime: cfg.l2BlockTime(),
...@@ -335,7 +335,7 @@ contract Deploy is Deployer { ...@@ -335,7 +335,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the OptimismMintableERC20Factory /// @notice Deploy the OptimismMintableERC20Factory
function deployOptimismMintableERC20Factory() broadcast() public returns (address) { function deployOptimismMintableERC20Factory() public broadcast returns (address) {
address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy"); address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(l1StandardBridgeProxy); OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(l1StandardBridgeProxy);
...@@ -348,7 +348,7 @@ contract Deploy is Deployer { ...@@ -348,7 +348,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the DisputeGameFactory /// @notice Deploy the DisputeGameFactory
function deployDisputeGameFactory() onlyDevnet broadcast() public returns (address) { function deployDisputeGameFactory() public onlyDevnet broadcast returns (address) {
DisputeGameFactory factory = new DisputeGameFactory(); DisputeGameFactory factory = new DisputeGameFactory();
save("DisputeGameFactory", address(factory)); save("DisputeGameFactory", address(factory));
console.log("DisputeGameFactory deployed at %s", address(factory)); console.log("DisputeGameFactory deployed at %s", address(factory));
...@@ -357,7 +357,7 @@ contract Deploy is Deployer { ...@@ -357,7 +357,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the BlockOracle /// @notice Deploy the BlockOracle
function deployBlockOracle() onlyDevnet broadcast() public returns (address) { function deployBlockOracle() public onlyDevnet broadcast returns (address) {
BlockOracle oracle = new BlockOracle(); BlockOracle oracle = new BlockOracle();
save("BlockOracle", address(oracle)); save("BlockOracle", address(oracle));
console.log("BlockOracle deployed at %s", address(oracle)); console.log("BlockOracle deployed at %s", address(oracle));
...@@ -366,7 +366,7 @@ contract Deploy is Deployer { ...@@ -366,7 +366,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the PreimageOracle /// @notice Deploy the PreimageOracle
function deployPreimageOracle() onlyDevnet broadcast() public returns (address) { function deployPreimageOracle() public onlyDevnet broadcast returns (address) {
PreimageOracle preimageOracle = new PreimageOracle(); PreimageOracle preimageOracle = new PreimageOracle();
save("PreimageOracle", address(preimageOracle)); save("PreimageOracle", address(preimageOracle));
console.log("PreimageOracle deployed at %s", address(preimageOracle)); console.log("PreimageOracle deployed at %s", address(preimageOracle));
...@@ -375,7 +375,7 @@ contract Deploy is Deployer { ...@@ -375,7 +375,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy Mips /// @notice Deploy Mips
function deployMips() onlyDevnet broadcast() public returns (address) { function deployMips() public onlyDevnet broadcast returns (address) {
MIPS mips = new MIPS(IPreimageOracle(mustGetAddress("PreimageOracle"))); MIPS mips = new MIPS(IPreimageOracle(mustGetAddress("PreimageOracle")));
save("Mips", address(mips)); save("Mips", address(mips));
console.log("MIPS deployed at %s", address(mips)); console.log("MIPS deployed at %s", address(mips));
...@@ -384,8 +384,9 @@ contract Deploy is Deployer { ...@@ -384,8 +384,9 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the SystemConfig /// @notice Deploy the SystemConfig
function deploySystemConfig() broadcast() public returns (address) { function deploySystemConfig() public broadcast returns (address) {
SystemConfig config = new SystemConfig(); SystemConfig config = new SystemConfig();
bytes32 batcherHash = bytes32(uint256(uint160(cfg.batchSenderAddress())));
require(config.owner() == address(0xdEaD)); require(config.owner() == address(0xdEaD));
require(config.overhead() == 0); require(config.overhead() == 0);
...@@ -417,7 +418,7 @@ contract Deploy is Deployer { ...@@ -417,7 +418,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L1StandardBridge /// @notice Deploy the L1StandardBridge
function deployL1StandardBridge() broadcast() public returns (address) { function deployL1StandardBridge() public broadcast returns (address) {
L1StandardBridge bridge = new L1StandardBridge(); L1StandardBridge bridge = new L1StandardBridge();
require(address(bridge.MESSENGER()) == address(0)); require(address(bridge.MESSENGER()) == address(0));
...@@ -432,7 +433,7 @@ contract Deploy is Deployer { ...@@ -432,7 +433,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the L1ERC721Bridge /// @notice Deploy the L1ERC721Bridge
function deployL1ERC721Bridge() broadcast() public returns (address) { function deployL1ERC721Bridge() public broadcast returns (address) {
L1ERC721Bridge bridge = new L1ERC721Bridge(); L1ERC721Bridge bridge = new L1ERC721Bridge();
require(address(bridge.MESSENGER()) == address(0)); require(address(bridge.MESSENGER()) == address(0));
...@@ -445,7 +446,7 @@ contract Deploy is Deployer { ...@@ -445,7 +446,7 @@ contract Deploy is Deployer {
} }
/// @notice Transfer ownership of the address manager to the ProxyAdmin /// @notice Transfer ownership of the address manager to the ProxyAdmin
function transferAddressManagerOwnership() broadcast() public { function transferAddressManagerOwnership() public broadcast {
AddressManager addressManager = AddressManager(mustGetAddress("AddressManager")); AddressManager addressManager = AddressManager(mustGetAddress("AddressManager"));
address owner = addressManager.owner(); address owner = addressManager.owner();
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
...@@ -458,7 +459,7 @@ contract Deploy is Deployer { ...@@ -458,7 +459,7 @@ contract Deploy is Deployer {
} }
/// @notice Initialize the DisputeGameFactory /// @notice Initialize the DisputeGameFactory
function initializeDisputeGameFactory() onlyDevnet broadcast() public { function initializeDisputeGameFactory() public onlyDevnet broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy"); address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy");
address disputeGameFactory = mustGetAddress("DisputeGameFactory"); address disputeGameFactory = mustGetAddress("DisputeGameFactory");
...@@ -466,10 +467,7 @@ contract Deploy is Deployer { ...@@ -466,10 +467,7 @@ contract Deploy is Deployer {
proxyAdmin.upgradeAndCall({ proxyAdmin.upgradeAndCall({
_proxy: payable(disputeGameFactoryProxy), _proxy: payable(disputeGameFactoryProxy),
_implementation: disputeGameFactory, _implementation: disputeGameFactory,
_data: abi.encodeCall( _data: abi.encodeCall(DisputeGameFactory.initialize, (msg.sender))
DisputeGameFactory.initialize,
(msg.sender)
)
}); });
string memory version = DisputeGameFactory(disputeGameFactoryProxy).version(); string memory version = DisputeGameFactory(disputeGameFactoryProxy).version();
...@@ -477,7 +475,7 @@ contract Deploy is Deployer { ...@@ -477,7 +475,7 @@ contract Deploy is Deployer {
} }
/// @notice Initialize the SystemConfig /// @notice Initialize the SystemConfig
function initializeSystemConfig() broadcast() public { function initializeSystemConfig() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address systemConfigProxy = mustGetAddress("SystemConfigProxy"); address systemConfigProxy = mustGetAddress("SystemConfigProxy");
address systemConfig = mustGetAddress("SystemConfig"); address systemConfig = mustGetAddress("SystemConfig");
...@@ -508,7 +506,7 @@ contract Deploy is Deployer { ...@@ -508,7 +506,7 @@ contract Deploy is Deployer {
optimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy") optimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy")
}) })
) )
) )
}); });
SystemConfig config = SystemConfig(systemConfigProxy); SystemConfig config = SystemConfig(systemConfigProxy);
...@@ -539,7 +537,7 @@ contract Deploy is Deployer { ...@@ -539,7 +537,7 @@ contract Deploy is Deployer {
} }
/// @notice Initialize the L1StandardBridge /// @notice Initialize the L1StandardBridge
function initializeL1StandardBridge() broadcast() public { function initializeL1StandardBridge() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy"); address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
address l1StandardBridge = mustGetAddress("L1StandardBridge"); address l1StandardBridge = mustGetAddress("L1StandardBridge");
...@@ -554,10 +552,7 @@ contract Deploy is Deployer { ...@@ -554,10 +552,7 @@ contract Deploy is Deployer {
proxyAdmin.upgradeAndCall({ proxyAdmin.upgradeAndCall({
_proxy: payable(l1StandardBridgeProxy), _proxy: payable(l1StandardBridgeProxy),
_implementation: l1StandardBridge, _implementation: l1StandardBridge,
_data: abi.encodeCall( _data: abi.encodeCall(L1StandardBridge.initialize, (L1CrossDomainMessenger(l1CrossDomainMessengerProxy)))
L1StandardBridge.initialize,
(L1CrossDomainMessenger(l1CrossDomainMessengerProxy))
)
}); });
string memory version = L1StandardBridge(payable(l1StandardBridgeProxy)).version(); string memory version = L1StandardBridge(payable(l1StandardBridgeProxy)).version();
...@@ -573,11 +568,10 @@ contract Deploy is Deployer { ...@@ -573,11 +568,10 @@ contract Deploy is Deployer {
// during predeployment simulation on OP Mainnet if there is a bug. // during predeployment simulation on OP Mainnet if there is a bug.
bytes32 slot0 = vm.load(address(bridge), bytes32(uint256(0))); bytes32 slot0 = vm.load(address(bridge), bytes32(uint256(0)));
require(slot0 == bytes32(uint256(2))); require(slot0 == bytes32(uint256(2)));
} }
/// @notice Initialize the L1ERC721Bridge /// @notice Initialize the L1ERC721Bridge
function initializeL1ERC721Bridge() broadcast() public { function initializeL1ERC721Bridge() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1ERC721BridgeProxy = mustGetAddress("L1ERC721BridgeProxy"); address l1ERC721BridgeProxy = mustGetAddress("L1ERC721BridgeProxy");
address l1ERC721Bridge = mustGetAddress("L1ERC721Bridge"); address l1ERC721Bridge = mustGetAddress("L1ERC721Bridge");
...@@ -586,10 +580,7 @@ contract Deploy is Deployer { ...@@ -586,10 +580,7 @@ contract Deploy is Deployer {
proxyAdmin.upgradeAndCall({ proxyAdmin.upgradeAndCall({
_proxy: payable(l1ERC721BridgeProxy), _proxy: payable(l1ERC721BridgeProxy),
_implementation: l1ERC721Bridge, _implementation: l1ERC721Bridge,
_data: abi.encodeCall( _data: abi.encodeCall(L1ERC721Bridge.initialize, (L1CrossDomainMessenger(l1CrossDomainMessengerProxy)))
L1ERC721Bridge.initialize,
(L1CrossDomainMessenger(l1CrossDomainMessengerProxy))
)
}); });
L1ERC721Bridge bridge = L1ERC721Bridge(l1ERC721BridgeProxy); L1ERC721Bridge bridge = L1ERC721Bridge(l1ERC721BridgeProxy);
...@@ -601,7 +592,7 @@ contract Deploy is Deployer { ...@@ -601,7 +592,7 @@ contract Deploy is Deployer {
} }
/// @notice Ininitialize the OptimismMintableERC20Factory /// @notice Ininitialize the OptimismMintableERC20Factory
function initializeOptimismMintableERC20Factory() broadcast() public { function initializeOptimismMintableERC20Factory() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address optimismMintableERC20FactoryProxy = mustGetAddress("OptimismMintableERC20FactoryProxy"); address optimismMintableERC20FactoryProxy = mustGetAddress("OptimismMintableERC20FactoryProxy");
address optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20Factory"); address optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20Factory");
...@@ -620,7 +611,7 @@ contract Deploy is Deployer { ...@@ -620,7 +611,7 @@ contract Deploy is Deployer {
} }
/// @notice initializeL1CrossDomainMessenger /// @notice initializeL1CrossDomainMessenger
function initializeL1CrossDomainMessenger() broadcast() public { function initializeL1CrossDomainMessenger() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy"); address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger"); address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger");
...@@ -638,18 +629,14 @@ contract Deploy is Deployer { ...@@ -638,18 +629,14 @@ contract Deploy is Deployer {
proxyAdmin.setImplementationName(l1CrossDomainMessengerProxy, contractName); proxyAdmin.setImplementationName(l1CrossDomainMessengerProxy, contractName);
} }
require( require(
keccak256(bytes(proxyAdmin.implementationName(l1CrossDomainMessengerProxy))) == keccak256(bytes(contractName)) keccak256(bytes(proxyAdmin.implementationName(l1CrossDomainMessengerProxy)))
== keccak256(bytes(contractName))
); );
proxyAdmin.upgradeAndCall({ proxyAdmin.upgradeAndCall({
_proxy: payable(l1CrossDomainMessengerProxy), _proxy: payable(l1CrossDomainMessengerProxy),
_implementation: l1CrossDomainMessenger, _implementation: l1CrossDomainMessenger,
_data: abi.encodeCall( _data: abi.encodeCall(L1CrossDomainMessenger.initialize, (OptimismPortal(payable(optimismPortalProxy))))
L1CrossDomainMessenger.initialize,
(
OptimismPortal(payable(optimismPortalProxy))
)
)
}); });
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxy); L1CrossDomainMessenger messenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxy);
...@@ -663,7 +650,7 @@ contract Deploy is Deployer { ...@@ -663,7 +650,7 @@ contract Deploy is Deployer {
} }
/// @notice Initialize the L2OutputOracle /// @notice Initialize the L2OutputOracle
function initializeL2OutputOracle() broadcast() public { function initializeL2OutputOracle() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy"); address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy");
address l2OutputOracle = mustGetAddress("L2OutputOracle"); address l2OutputOracle = mustGetAddress("L2OutputOracle");
...@@ -679,7 +666,7 @@ contract Deploy is Deployer { ...@@ -679,7 +666,7 @@ contract Deploy is Deployer {
cfg.l2OutputOracleProposer(), cfg.l2OutputOracleProposer(),
cfg.l2OutputOracleChallenger() cfg.l2OutputOracleChallenger()
) )
) )
}); });
L2OutputOracle oracle = L2OutputOracle(l2OutputOracleProxy); L2OutputOracle oracle = L2OutputOracle(l2OutputOracleProxy);
...@@ -701,7 +688,7 @@ contract Deploy is Deployer { ...@@ -701,7 +688,7 @@ contract Deploy is Deployer {
} }
/// @notice Initialize the OptimismPortal /// @notice Initialize the OptimismPortal
function initializeOptimismPortal() broadcast() public { function initializeOptimismPortal() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address optimismPortalProxy = mustGetAddress("OptimismPortalProxy"); address optimismPortalProxy = mustGetAddress("OptimismPortalProxy");
address optimismPortal = mustGetAddress("OptimismPortal"); address optimismPortal = mustGetAddress("OptimismPortal");
...@@ -718,13 +705,8 @@ contract Deploy is Deployer { ...@@ -718,13 +705,8 @@ contract Deploy is Deployer {
_implementation: optimismPortal, _implementation: optimismPortal,
_data: abi.encodeCall( _data: abi.encodeCall(
OptimismPortal.initialize, OptimismPortal.initialize,
( (L2OutputOracle(l2OutputOracleProxy), guardian, SystemConfig(systemConfigProxy), false)
L2OutputOracle(l2OutputOracleProxy),
guardian,
SystemConfig(systemConfigProxy),
false
) )
)
}); });
OptimismPortal portal = OptimismPortal(payable(optimismPortalProxy)); OptimismPortal portal = OptimismPortal(payable(optimismPortalProxy));
...@@ -738,7 +720,7 @@ contract Deploy is Deployer { ...@@ -738,7 +720,7 @@ contract Deploy is Deployer {
} }
/// @notice Transfer ownership of the ProxyAdmin contract to the final system owner /// @notice Transfer ownership of the ProxyAdmin contract to the final system owner
function transferProxyAdminOwnership() broadcast() public { function transferProxyAdminOwnership() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address owner = proxyAdmin.owner(); address owner = proxyAdmin.owner();
address finalSystemOwner = cfg.finalSystemOwner(); address finalSystemOwner = cfg.finalSystemOwner();
...@@ -749,7 +731,7 @@ contract Deploy is Deployer { ...@@ -749,7 +731,7 @@ contract Deploy is Deployer {
} }
/// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner /// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner
function transferDisputeGameFactoryOwnership() onlyDevnet broadcast() public { function transferDisputeGameFactoryOwnership() public onlyDevnet broadcast {
DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
address owner = disputeGameFactory.owner(); address owner = disputeGameFactory.owner();
address finalSystemOwner = cfg.finalSystemOwner(); address finalSystemOwner = cfg.finalSystemOwner();
...@@ -760,7 +742,7 @@ contract Deploy is Deployer { ...@@ -760,7 +742,7 @@ contract Deploy is Deployer {
} }
/// @notice Sets the implementation for the `FAULT` game type in the `DisputeGameFactory` /// @notice Sets the implementation for the `FAULT` game type in the `DisputeGameFactory`
function setFaultGameImplementation() onlyDevnet broadcast() public { function setFaultGameImplementation() public onlyDevnet broadcast {
// Create the absolute prestate dump // Create the absolute prestate dump
string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json"); string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json");
bytes32 mipsAbsolutePrestate; bytes32 mipsAbsolutePrestate;
...@@ -777,11 +759,15 @@ contract Deploy is Deployer { ...@@ -777,11 +759,15 @@ contract Deploy is Deployer {
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
for (uint8 i; i < 2; i++) { for (uint8 i; i < 2; i++) {
Claim absolutePrestate = Claim.wrap(i == 0 ? bytes32(cfg.faultGameAbsolutePrestate()) : mipsAbsolutePrestate); Claim absolutePrestate =
IBigStepper faultVm = IBigStepper(i == 0 ? address(new AlphabetVM(absolutePrestate)) : mustGetAddress("Mips")); Claim.wrap(i == 0 ? bytes32(cfg.faultGameAbsolutePrestate()) : mipsAbsolutePrestate);
IBigStepper faultVm =
IBigStepper(i == 0 ? address(new AlphabetVM(absolutePrestate)) : mustGetAddress("Mips"));
GameType gameType = GameType.wrap(i); GameType gameType = GameType.wrap(i);
if (address(factory.gameImpls(gameType)) == address(0)) { if (address(factory.gameImpls(gameType)) == address(0)) {
factory.setImplementation(gameType, new FaultDisputeGame({ factory.setImplementation(
gameType,
new FaultDisputeGame({
_gameType: gameType, _gameType: gameType,
_absolutePrestate: absolutePrestate, _absolutePrestate: absolutePrestate,
_maxGameDepth: i == 0 ? 4 : cfg.faultGameMaxDepth(), // The max depth of the alphabet game is always 4 _maxGameDepth: i == 0 ? 4 : cfg.faultGameMaxDepth(), // The max depth of the alphabet game is always 4
...@@ -789,8 +775,13 @@ contract Deploy is Deployer { ...@@ -789,8 +775,13 @@ contract Deploy is Deployer {
_vm: faultVm, _vm: faultVm,
_l2oo: L2OutputOracle(mustGetAddress("L2OutputOracleProxy")), _l2oo: L2OutputOracle(mustGetAddress("L2OutputOracleProxy")),
_blockOracle: BlockOracle(mustGetAddress("BlockOracle")) _blockOracle: BlockOracle(mustGetAddress("BlockOracle"))
})); })
console.log("DisputeGameFactoryProxy: set `FaultDisputeGame` implementation (Backend: %s | GameType: %s)", i == 0 ? "AlphabetVM" : "MIPS", vm.toString(i)); );
console.log(
"DisputeGameFactoryProxy: set `FaultDisputeGame` implementation (Backend: %s | GameType: %s)",
i == 0 ? "AlphabetVM" : "MIPS",
vm.toString(i)
);
} }
} }
} }
......
...@@ -106,7 +106,7 @@ contract DeployConfig is Script { ...@@ -106,7 +106,7 @@ contract DeployConfig is Script {
} catch { } catch {
try vm.parseJsonUint(_json, "$.l1StartingBlockTag") returns (uint256 tag) { try vm.parseJsonUint(_json, "$.l1StartingBlockTag") returns (uint256 tag) {
return _getBlockByTag(vm.toString(tag)); return _getBlockByTag(vm.toString(tag));
} catch {} } catch { }
} }
} }
revert("l1StartingBlockTag must be a bytes32, string or uint256 or cannot fetch l1StartingBlockTag"); revert("l1StartingBlockTag must be a bytes32, string or uint256 or cannot fetch l1StartingBlockTag");
......
...@@ -39,7 +39,7 @@ contract DeployL2 is Deployer { ...@@ -39,7 +39,7 @@ contract DeployL2 is Deployer {
} }
/// @notice Deploy the EAS implementation. /// @notice Deploy the EAS implementation.
function deployEAS() broadcast() public returns (address) { function deployEAS() public broadcast returns (address) {
EAS eas = new EAS(); EAS eas = new EAS();
ISchemaRegistry registry = eas.getSchemaRegistry(); ISchemaRegistry registry = eas.getSchemaRegistry();
...@@ -55,7 +55,7 @@ contract DeployL2 is Deployer { ...@@ -55,7 +55,7 @@ contract DeployL2 is Deployer {
} }
/// @notice Deploy the SchemaManager implementation. /// @notice Deploy the SchemaManager implementation.
function deploySchemaRegistry() broadcast() public returns (address) { function deploySchemaRegistry() public broadcast returns (address) {
SchemaRegistry registry = new SchemaRegistry(); SchemaRegistry registry = new SchemaRegistry();
save("SchemaRegistry", address(registry)); save("SchemaRegistry", address(registry));
...@@ -67,4 +67,3 @@ contract DeployL2 is Deployer { ...@@ -67,4 +67,3 @@ contract DeployL2 is Deployer {
return address(registry); return address(registry);
} }
} }
...@@ -53,17 +53,17 @@ abstract contract Deployer is Script { ...@@ -53,17 +53,17 @@ abstract contract Deployer is Script {
/// @notice The path to the temp deployments file /// @notice The path to the temp deployments file
string internal tempDeploymentsPath; string internal tempDeploymentsPath;
/// @notice Error for when attempting to fetch a deployment and it does not exist /// @notice Error for when attempting to fetch a deployment and it does not exist
error DeploymentDoesNotExist(string); error DeploymentDoesNotExist(string);
/// @notice Error for when trying to save an invalid deployment /// @notice Error for when trying to save an invalid deployment
error InvalidDeployment(string); error InvalidDeployment(string);
/// @notice The storage slot that holds the address of the implementation. /// @notice The storage slot that holds the address of the implementation.
/// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) /// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
bytes32 internal constant IMPLEMENTATION_KEY =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; bytes32 internal constant IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/// @notice The storage slot that holds the address of the owner. /// @notice The storage slot that holds the address of the owner.
/// bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) /// bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
bytes32 internal constant OWNER_KEY = bytes32 internal constant OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/// @notice Create the global variables and set up the filesystem /// @notice Create the global variables and set up the filesystem
function setUp() public virtual { function setUp() public virtual {
...@@ -76,7 +76,7 @@ abstract contract Deployer is Script { ...@@ -76,7 +76,7 @@ abstract contract Deployer is Script {
deployPath = string.concat(root, "/broadcast/", deployScript, ".s.sol/", vm.toString(chainId), "/", deployFile); deployPath = string.concat(root, "/broadcast/", deployScript, ".s.sol/", vm.toString(chainId), "/", deployFile);
deploymentsDir = string.concat(root, "/deployments/", deploymentContext); deploymentsDir = string.concat(root, "/deployments/", deploymentContext);
try vm.createDir(deploymentsDir, true) {} catch (bytes memory) {} try vm.createDir(deploymentsDir, true) { } catch (bytes memory) { }
string memory chainIdPath = string.concat(deploymentsDir, "/.chainId"); string memory chainIdPath = string.concat(deploymentsDir, "/.chainId");
try vm.readFile(chainIdPath) returns (string memory localChainId) { try vm.readFile(chainIdPath) returns (string memory localChainId) {
...@@ -89,7 +89,8 @@ abstract contract Deployer is Script { ...@@ -89,7 +89,8 @@ abstract contract Deployer is Script {
console.log("Connected to network with chainid %s", chainId); console.log("Connected to network with chainid %s", chainId);
tempDeploymentsPath = string.concat(deploymentsDir, "/.deploy"); tempDeploymentsPath = string.concat(deploymentsDir, "/.deploy");
try vm.readFile(tempDeploymentsPath) returns (string memory) {} catch { try vm.readFile(tempDeploymentsPath) returns (string memory) { }
catch {
vm.writeJson("{}", tempDeploymentsPath); vm.writeJson("{}", tempDeploymentsPath);
} }
console.log("Storing temp deployment data in %s", tempDeploymentsPath); console.log("Storing temp deployment data in %s", tempDeploymentsPath);
...@@ -121,7 +122,7 @@ abstract contract Deployer is Script { ...@@ -121,7 +122,7 @@ abstract contract Deployer is Script {
try vm.readFile(artifactPath) returns (string memory res) { try vm.readFile(artifactPath) returns (string memory res) {
numDeployments = stdJson.readUint(string(res), "$.numDeployments"); numDeployments = stdJson.readUint(string(res), "$.numDeployments");
vm.removeFile(artifactPath); vm.removeFile(artifactPath);
} catch {} } catch { }
numDeployments++; numDeployments++;
Artifact memory artifact = Artifact({ Artifact memory artifact = Artifact({
...@@ -142,10 +143,7 @@ abstract contract Deployer is Script { ...@@ -142,10 +143,7 @@ abstract contract Deployer is Script {
string memory json = _serializeArtifact(artifact); string memory json = _serializeArtifact(artifact);
vm.writeJson({ vm.writeJson({ json: json, path: artifactPath });
json: json,
path: artifactPath
});
} }
console.log("Synced temp deploy files, deleting %s", tempDeploymentsPath); console.log("Synced temp deploy files, deleting %s", tempDeploymentsPath);
...@@ -154,7 +152,7 @@ abstract contract Deployer is Script { ...@@ -154,7 +152,7 @@ abstract contract Deployer is Script {
/// @notice Returns the name of the deployment script. Children contracts /// @notice Returns the name of the deployment script. Children contracts
/// must implement this to ensure that the deploy artifacts can be found. /// must implement this to ensure that the deploy artifacts can be found.
function name() public virtual pure returns (string memory); function name() public pure virtual returns (string memory);
/// @notice Returns all of the deployments done in the current context. /// @notice Returns all of the deployments done in the current context.
function newDeployments() external view returns (Deployment[] memory) { function newDeployments() external view returns (Deployment[] memory) {
...@@ -222,10 +220,7 @@ abstract contract Deployer is Script { ...@@ -222,10 +220,7 @@ abstract contract Deployer is Script {
revert InvalidDeployment("AlreadyExists"); revert InvalidDeployment("AlreadyExists");
} }
Deployment memory deployment = Deployment({ Deployment memory deployment = Deployment({ name: _name, addr: payable(_deployed) });
name: _name,
addr: payable(_deployed)
});
_namedDeployments[_name] = deployment; _namedDeployments[_name] = deployment;
_newDeployments.push(deployment); _newDeployments.push(deployment);
_writeTemp(_name, _deployed); _writeTemp(_name, _deployed);
...@@ -247,10 +242,7 @@ abstract contract Deployer is Script { ...@@ -247,10 +242,7 @@ abstract contract Deployer is Script {
for (uint256 i; i < names.length; i++) { for (uint256 i; i < names.length; i++) {
string memory contractName = names[i]; string memory contractName = names[i];
address addr = stdJson.readAddress(json, string.concat("$.", contractName)); address addr = stdJson.readAddress(json, string.concat("$.", contractName));
deployments[i] = Deployment({ deployments[i] = Deployment({ name: contractName, addr: payable(addr) });
name: contractName,
addr: payable(addr)
});
} }
return deployments; return deployments;
} }
...@@ -260,7 +252,17 @@ abstract contract Deployer is Script { ...@@ -260,7 +252,17 @@ abstract contract Deployer is Script {
string[] memory cmd = new string[](3); string[] memory cmd = new string[](3);
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.jq, " -r '.transactions[] | select(.contractAddress == ", '"', vm.toString(_addr), '"', ") | select(.transactionType == ", '"CREATE"', ")' < ", deployPath); cmd[2] = string.concat(
Executables.jq,
" -r '.transactions[] | select(.contractAddress == ",
'"',
vm.toString(_addr),
'"',
") | select(.transactionType == ",
'"CREATE"',
")' < ",
deployPath
);
bytes memory res = vm.ffi(cmd); bytes memory res = vm.ffi(cmd);
return string(res); return string(res);
} }
...@@ -284,13 +286,16 @@ abstract contract Deployer is Script { ...@@ -284,13 +286,16 @@ abstract contract Deployer is Script {
return code; return code;
} }
/// @notice Removes the semantic versioning from a contract name. The semver will exist if the contract is compiled more than /// @notice Removes the semantic versioning from a contract name. The semver will exist if the contract is compiled
/// more than
/// once with different versions of the compiler. /// once with different versions of the compiler.
function _stripSemver(string memory _name) internal returns (string memory) { function _stripSemver(string memory _name) internal returns (string memory) {
string[] memory cmd = new string[](3); string[] memory cmd = new string[](3);
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.echo, " ", _name, " | ", Executables.sed, " -E 's/[.][0-9]+\\.[0-9]+\\.[0-9]+//g'"); cmd[2] = string.concat(
Executables.echo, " ", _name, " | ", Executables.sed, " -E 's/[.][0-9]+\\.[0-9]+\\.[0-9]+//g'"
);
bytes memory res = vm.ffi(cmd); bytes memory res = vm.ffi(cmd);
return string(res); return string(res);
} }
...@@ -326,7 +331,8 @@ abstract contract Deployer is Script { ...@@ -326,7 +331,8 @@ abstract contract Deployer is Script {
cmd[2] = string.concat(Executables.forge, " config --json | ", Executables.jq, " -r .out"); cmd[2] = string.concat(Executables.forge, " config --json | ", Executables.jq, " -r .out");
bytes memory res = vm.ffi(cmd); bytes memory res = vm.ffi(cmd);
string memory contractName = _stripSemver(_name); string memory contractName = _stripSemver(_name);
string memory forgeArtifactPath = string.concat(vm.projectRoot(), "/", string(res), "/", contractName, ".sol/", _name, ".json"); string memory forgeArtifactPath =
string.concat(vm.projectRoot(), "/", string(res), "/", contractName, ".sol/", _name, ".json");
return forgeArtifactPath; return forgeArtifactPath;
} }
...@@ -342,7 +348,15 @@ abstract contract Deployer is Script { ...@@ -342,7 +348,15 @@ abstract contract Deployer is Script {
string[] memory cmd = new string[](3); string[] memory cmd = new string[](3);
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.jq, " -r '.receipts[] | select(.contractAddress == ", '"', vm.toString(addr), '"', ")' < ", deployPath); cmd[2] = string.concat(
Executables.jq,
" -r '.receipts[] | select(.contractAddress == ",
'"',
vm.toString(addr),
'"',
")' < ",
deployPath
);
bytes memory res = vm.ffi(cmd); bytes memory res = vm.ffi(cmd);
string memory receipt = string(res); string memory receipt = string(res);
return receipt; return receipt;
...@@ -400,10 +414,7 @@ abstract contract Deployer is Script { ...@@ -400,10 +414,7 @@ abstract contract Deployer is Script {
/// @notice Adds a deployment to the temp deployments file /// @notice Adds a deployment to the temp deployments file
function _writeTemp(string memory _name, address _deployed) internal { function _writeTemp(string memory _name, address _deployed) internal {
vm.writeJson({ vm.writeJson({ json: stdJson.serialize("", _name, _deployed), path: tempDeploymentsPath });
json: stdJson.serialize("", _name, _deployed),
path: tempDeploymentsPath
});
} }
/// @notice Turns an Artifact into a json serialized string /// @notice Turns an Artifact into a json serialized string
...@@ -438,7 +449,7 @@ abstract contract Deployer is Script { ...@@ -438,7 +449,7 @@ abstract contract Deployer is Script {
uint256 chainid = vm.envOr("CHAIN_ID", block.chainid); uint256 chainid = vm.envOr("CHAIN_ID", block.chainid);
if (chainid == Chains.Mainnet) { if (chainid == Chains.Mainnet) {
return "mainnet"; return "mainnet";
} else if (chainid == Chains.Goerli) { } else if (chainid == Chains.Goerli) {
return "goerli"; return "goerli";
} else if (chainid == Chains.OPGoerli) { } else if (chainid == Chains.OPGoerli) {
return "optimism-goerli"; return "optimism-goerli";
...@@ -471,15 +482,9 @@ abstract contract Deployer is Script { ...@@ -471,15 +482,9 @@ abstract contract Deployer is Script {
string memory path = string.concat(deploymentsDir, "/", _name, ".json"); string memory path = string.concat(deploymentsDir, "/", _name, ".json");
try vm.readFile(path) returns (string memory json) { try vm.readFile(path) returns (string memory json) {
bytes memory addr = stdJson.parseRaw(json, "$.address"); bytes memory addr = stdJson.parseRaw(json, "$.address");
return Deployment({ return Deployment({ addr: abi.decode(addr, (address)), name: _name });
addr: abi.decode(addr, (address)),
name: _name
});
} catch { } catch {
return Deployment({ return Deployment({ addr: payable(address(0)), name: "" });
addr: payable(address(0)),
name: ""
});
} }
} }
} }
...@@ -54,13 +54,7 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init { ...@@ -54,13 +54,7 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init {
uint256 numClaims = uint256(vm.load(address(gameProxy), bytes32(uint256(1)))); uint256 numClaims = uint256(vm.load(address(gameProxy), bytes32(uint256(1))));
IFaultDisputeGame.ClaimData[] memory gameData = new IFaultDisputeGame.ClaimData[](numClaims); IFaultDisputeGame.ClaimData[] memory gameData = new IFaultDisputeGame.ClaimData[](numClaims);
for (uint256 i = 0; i < numClaims; i++) { for (uint256 i = 0; i < numClaims; i++) {
( (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(i);
uint32 parentIndex,
bool countered,
Claim claim,
Position position,
Clock clock
) = gameProxy.claimData(i);
gameData[i] = IFaultDisputeGame.ClaimData({ gameData[i] = IFaultDisputeGame.ClaimData({
parentIndex: parentIndex, parentIndex: parentIndex,
......
...@@ -31,20 +31,20 @@ contract FeeVaultWithdrawal is Script { ...@@ -31,20 +31,20 @@ contract FeeVaultWithdrawal is Script {
address vault = vaults[i]; address vault = vaults[i];
bool shouldCall = canWithdrawal(vault); bool shouldCall = canWithdrawal(vault);
if (shouldCall) { if (shouldCall) {
calls.push(IMulticall3.Call3({ calls.push(
target: vault, IMulticall3.Call3({
allowFailure: false, target: vault,
callData: abi.encodeWithSelector(FeeVault.withdraw.selector) allowFailure: false,
})); callData: abi.encodeWithSelector(FeeVault.withdraw.selector)
})
);
address recipient = FeeVault(payable(vault)).RECIPIENT(); address recipient = FeeVault(payable(vault)).RECIPIENT();
uint256 balance = vault.balance; uint256 balance = vault.balance;
log(balance, recipient, vault); log(balance, recipient, vault);
} else { } else {
string memory logline = string.concat( string memory logline =
vm.toString(vault), string.concat(vm.toString(vault), " does not have a large enough balance to withdraw.");
" does not have a large enough balance to withdraw."
);
console.log(logline); console.log(logline);
} }
} }
...@@ -67,12 +67,7 @@ contract FeeVaultWithdrawal is Script { ...@@ -67,12 +67,7 @@ contract FeeVaultWithdrawal is Script {
/// @notice Logs the information relevant to the user. /// @notice Logs the information relevant to the user.
function log(uint256 _balance, address _recipient, address _vault) internal view { function log(uint256 _balance, address _recipient, address _vault) internal view {
string memory logline = string.concat( string memory logline = string.concat(
"Withdrawing ", "Withdrawing ", vm.toString(_balance), " to ", vm.toString(_recipient), " from ", vm.toString(_vault)
vm.toString(_balance),
" to ",
vm.toString(_recipient),
" from ",
vm.toString(_vault)
); );
console.log(logline); console.log(logline);
} }
......
...@@ -31,11 +31,7 @@ contract SemverLock is Script { ...@@ -31,11 +31,7 @@ contract SemverLock is Script {
commands = new string[](3); commands = new string[](3);
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = string.concat( commands[2] = string.concat("echo \"", _files[i], "\"| sed -E \'s|src/.*/(.+)\\.sol|\\1|\'");
"echo \"",
_files[i],
"\"| sed -E \'s|src/.*/(.+)\\.sol|\\1|\'"
);
string memory contractName = string(vm.ffi(commands)); string memory contractName = string(vm.ffi(commands));
commands[0] = "bash"; commands[0] = "bash";
...@@ -44,14 +40,8 @@ contract SemverLock is Script { ...@@ -44,14 +40,8 @@ contract SemverLock is Script {
string memory artifactsDir = string(vm.ffi(commands)); string memory artifactsDir = string(vm.ffi(commands));
// Parse the artifact to get the contract's initcode hash. // Parse the artifact to get the contract's initcode hash.
bytes memory initCode = vm.getCode(string.concat( bytes memory initCode =
artifactsDir, vm.getCode(string.concat(artifactsDir, "/", contractName, ".sol/", contractName, ".json"));
"/",
contractName,
".sol/",
contractName,
".json"
));
// Serialize the source hash in JSON. // Serialize the source hash in JSON.
string memory j = vm.serializeBytes32(out, _files[i], keccak256(abi.encodePacked(fileContents, initCode))); string memory j = vm.serializeBytes32(out, _files[i], keccak256(abi.encodePacked(fileContents, initCode)));
......
...@@ -35,7 +35,12 @@ interface IGnosisSafe { ...@@ -35,7 +35,12 @@ interface IGnosisSafe {
function approveHash(bytes32 hashToApprove) external; function approveHash(bytes32 hashToApprove) external;
function approvedHashes(address, bytes32) external view returns (uint256); function approvedHashes(address, bytes32) external view returns (uint256);
function changeThreshold(uint256 _threshold) external; function changeThreshold(uint256 _threshold) external;
function checkNSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures, uint256 requiredSignatures) function checkNSignatures(
bytes32 dataHash,
bytes memory data,
bytes memory signatures,
uint256 requiredSignatures
)
external external
view; view;
function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures) external view; function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures) external view;
...@@ -53,7 +58,10 @@ interface IGnosisSafe { ...@@ -53,7 +58,10 @@ interface IGnosisSafe {
address gasToken, address gasToken,
address refundReceiver, address refundReceiver,
uint256 _nonce uint256 _nonce
) external view returns (bytes memory); )
external
view
returns (bytes memory);
function execTransaction( function execTransaction(
address to, address to,
uint256 value, uint256 value,
...@@ -65,15 +73,31 @@ interface IGnosisSafe { ...@@ -65,15 +73,31 @@ interface IGnosisSafe {
address gasToken, address gasToken,
address refundReceiver, address refundReceiver,
bytes memory signatures bytes memory signatures
) external payable returns (bool success); )
function execTransactionFromModule(address to, uint256 value, bytes memory data, Enum.Operation operation)
external external
payable
returns (bool success); returns (bool success);
function execTransactionFromModuleReturnData(address to, uint256 value, bytes memory data, Enum.Operation operation) function execTransactionFromModule(
address to,
uint256 value,
bytes memory data,
Enum.Operation operation
)
external
returns (bool success);
function execTransactionFromModuleReturnData(
address to,
uint256 value,
bytes memory data,
Enum.Operation operation
)
external external
returns (bool success, bytes memory returnData); returns (bool success, bytes memory returnData);
function getChainId() external view returns (uint256); function getChainId() external view returns (uint256);
function getModulesPaginated(address start, uint256 pageSize) function getModulesPaginated(
address start,
uint256 pageSize
)
external external
view view
returns (address[] memory array, address next); returns (address[] memory array, address next);
...@@ -91,12 +115,22 @@ interface IGnosisSafe { ...@@ -91,12 +115,22 @@ interface IGnosisSafe {
address gasToken, address gasToken,
address refundReceiver, address refundReceiver,
uint256 _nonce uint256 _nonce
) external view returns (bytes32); )
external
view
returns (bytes32);
function isModuleEnabled(address module) external view returns (bool); function isModuleEnabled(address module) external view returns (bool);
function isOwner(address owner) external view returns (bool); function isOwner(address owner) external view returns (bool);
function nonce() external view returns (uint256); function nonce() external view returns (uint256);
function removeOwner(address prevOwner, address owner, uint256 _threshold) external; function removeOwner(address prevOwner, address owner, uint256 _threshold) external;
function requiredTxGas(address to, uint256 value, bytes memory data, Enum.Operation operation) external returns (uint256); function requiredTxGas(
address to,
uint256 value,
bytes memory data,
Enum.Operation operation
)
external
returns (uint256);
function setFallbackHandler(address handler) external; function setFallbackHandler(address handler) external;
function setGuard(address guard) external; function setGuard(address guard) external;
function setup( function setup(
...@@ -108,7 +142,8 @@ interface IGnosisSafe { ...@@ -108,7 +142,8 @@ interface IGnosisSafe {
address paymentToken, address paymentToken,
uint256 payment, uint256 payment,
address paymentReceiver address paymentReceiver
) external; )
external;
function signedMessages(bytes32) external view returns (uint256); function signedMessages(bytes32) external view returns (uint256);
function simulateAndRevert(address targetContract, bytes memory calldataPayload) external; function simulateAndRevert(address targetContract, bytes memory calldataPayload) external;
function swapOwner(address prevOwner, address oldOwner, address newOwner) external; function swapOwner(address prevOwner, address oldOwner, address newOwner) external;
......
...@@ -22,14 +22,14 @@ library LibSort { ...@@ -22,14 +22,14 @@ library LibSort {
let h := add(a, shl(5, n)) // High slot. let h := add(a, shl(5, n)) // High slot.
let s := 0x20 let s := 0x20
let w := not(31) let w := not(31)
for { let i := add(a, s) } 1 {} { for { let i := add(a, s) } 1 { } {
i := add(i, s) i := add(i, s)
if gt(i, h) { break } if gt(i, h) { break }
let k := mload(i) // Key. let k := mload(i) // Key.
let j := add(i, w) // The slot before the current slot. let j := add(i, w) // The slot before the current slot.
let v := mload(j) // The value of `j`. let v := mload(j) // The value of `j`.
if iszero(gt(v, k)) { continue } if iszero(gt(v, k)) { continue }
for {} 1 {} { for { } 1 { } {
mstore(add(j, s), v) mstore(add(j, s), v)
j := add(j, w) // `sub(j, 0x20)`. j := add(j, w) // `sub(j, 0x20)`.
v := mload(j) v := mload(j)
...@@ -73,7 +73,7 @@ library LibSort { ...@@ -73,7 +73,7 @@ library LibSort {
// Let the stack be the start of the free memory. // Let the stack be the start of the free memory.
let stack := mload(0x40) let stack := mload(0x40)
for {} iszero(lt(n, 2)) {} { for { } iszero(lt(n, 2)) { } {
// Push `l` and `h` to the stack. // Push `l` and `h` to the stack.
// The `shl` by 5 is equivalent to multiplying by `0x20`. // The `shl` by 5 is equivalent to multiplying by `0x20`.
let l := add(a, s) let l := add(a, s)
...@@ -94,7 +94,7 @@ library LibSort { ...@@ -94,7 +94,7 @@ library LibSort {
} }
// If the array is reversed sorted. // If the array is reversed sorted.
if eq(j, l) { if eq(j, l) {
for {} 1 {} { for { } 1 { } {
let t := mload(l) let t := mload(l)
mstore(l, mload(h)) mstore(l, mload(h))
mstore(h, t) mstore(h, t)
...@@ -112,7 +112,7 @@ library LibSort { ...@@ -112,7 +112,7 @@ library LibSort {
break break
} }
for { let stackBottom := mload(0x40) } iszero(eq(stack, stackBottom)) {} { for { let stackBottom := mload(0x40) } iszero(eq(stack, stackBottom)) { } {
// Pop `l` and `h` from the stack. // Pop `l` and `h` from the stack.
stack := sub(stack, 0x40) stack := sub(stack, 0x40)
let l := mload(stack) let l := mload(stack)
...@@ -128,14 +128,14 @@ library LibSort { ...@@ -128,14 +128,14 @@ library LibSort {
mstore(i, mload(l)) mstore(i, mload(l))
mstore(l, t) mstore(l, t)
} }
for {} 1 {} { for { } 1 { } {
i := add(i, s) i := add(i, s)
if gt(i, h) { break } if gt(i, h) { break }
let k := mload(i) // Key. let k := mload(i) // Key.
let j := add(i, w) // The slot before the current slot. let j := add(i, w) // The slot before the current slot.
let v := mload(j) // The value of `j`. let v := mload(j) // The value of `j`.
if iszero(gt(v, k)) { continue } if iszero(gt(v, k)) { continue }
for {} 1 {} { for { } 1 { } {
mstore(add(j, s), v) mstore(add(j, s), v)
j := add(j, w) j := add(j, w)
v := mload(j) v := mload(j)
...@@ -176,13 +176,13 @@ library LibSort { ...@@ -176,13 +176,13 @@ library LibSort {
// The value of the pivot slot. // The value of the pivot slot.
let x := mload(p) let x := mload(p)
p := h p := h
for { let i := l } 1 {} { for { let i := l } 1 { } {
for {} 1 {} { for { } 1 { } {
i := add(i, s) i := add(i, s)
if iszero(gt(x, mload(i))) { break } if iszero(gt(x, mload(i))) { break }
} }
let j := p let j := p
for {} 1 {} { for { } 1 { } {
j := add(j, w) j := add(j, w)
if iszero(lt(x, mload(j))) { break } if iszero(lt(x, mload(j))) { break }
} }
...@@ -239,7 +239,7 @@ library LibSort { ...@@ -239,7 +239,7 @@ library LibSort {
let x := add(a, 0x20) let x := add(a, 0x20)
let y := add(a, 0x40) let y := add(a, 0x40)
let end := add(a, shl(5, add(mload(a), 1))) let end := add(a, shl(5, add(mload(a), 1)))
for {} 1 {} { for { } 1 { } {
if iszero(eq(mload(x), mload(y))) { if iszero(eq(mload(x), mload(y))) {
x := add(x, 0x20) x := add(x, 0x20)
mstore(x, mload(y)) mstore(x, mload(y))
...@@ -264,31 +264,19 @@ library LibSort { ...@@ -264,31 +264,19 @@ library LibSort {
/// @dev Returns whether `a` contains `needle`, /// @dev Returns whether `a` contains `needle`,
/// and the index of the nearest element less than or equal to `needle`. /// and the index of the nearest element less than or equal to `needle`.
function searchSorted(uint256[] memory a, uint256 needle) function searchSorted(uint256[] memory a, uint256 needle) internal pure returns (bool found, uint256 index) {
internal
pure
returns (bool found, uint256 index)
{
(found, index) = _searchSorted(a, needle, 0); (found, index) = _searchSorted(a, needle, 0);
} }
/// @dev Returns whether `a` contains `needle`, /// @dev Returns whether `a` contains `needle`,
/// and the index of the nearest element less than or equal to `needle`. /// and the index of the nearest element less than or equal to `needle`.
function searchSorted(int256[] memory a, int256 needle) function searchSorted(int256[] memory a, int256 needle) internal pure returns (bool found, uint256 index) {
internal
pure
returns (bool found, uint256 index)
{
(found, index) = _searchSorted(_toUints(a), uint256(needle), 1 << 255); (found, index) = _searchSorted(_toUints(a), uint256(needle), 1 << 255);
} }
/// @dev Returns whether `a` contains `needle`, /// @dev Returns whether `a` contains `needle`,
/// and the index of the nearest element less than or equal to `needle`. /// and the index of the nearest element less than or equal to `needle`.
function searchSorted(address[] memory a, address needle) function searchSorted(address[] memory a, address needle) internal pure returns (bool found, uint256 index) {
internal
pure
returns (bool found, uint256 index)
{
(found, index) = _searchSorted(_toUints(a), uint256(uint160(needle)), 0); (found, index) = _searchSorted(_toUints(a), uint256(uint160(needle)), 0);
} }
...@@ -300,7 +288,7 @@ library LibSort { ...@@ -300,7 +288,7 @@ library LibSort {
let s := 0x20 let s := 0x20
let w := not(31) let w := not(31)
let h := add(a, shl(5, mload(a))) let h := add(a, shl(5, mload(a)))
for { a := add(a, s) } 1 {} { for { a := add(a, s) } 1 { } {
let t := mload(a) let t := mload(a)
mstore(a, mload(h)) mstore(a, mload(h))
mstore(h, t) mstore(h, t)
...@@ -329,7 +317,7 @@ library LibSort { ...@@ -329,7 +317,7 @@ library LibSort {
result := 1 result := 1
if iszero(lt(mload(a), 2)) { if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a))) let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} { for { a := add(a, 0x20) } 1 { } {
let p := mload(a) let p := mload(a)
a := add(a, 0x20) a := add(a, 0x20)
result := iszero(gt(p, mload(a))) result := iszero(gt(p, mload(a)))
...@@ -346,7 +334,7 @@ library LibSort { ...@@ -346,7 +334,7 @@ library LibSort {
result := 1 result := 1
if iszero(lt(mload(a), 2)) { if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a))) let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} { for { a := add(a, 0x20) } 1 { } {
let p := mload(a) let p := mload(a)
a := add(a, 0x20) a := add(a, 0x20)
result := iszero(sgt(p, mload(a))) result := iszero(sgt(p, mload(a)))
...@@ -368,7 +356,7 @@ library LibSort { ...@@ -368,7 +356,7 @@ library LibSort {
result := 1 result := 1
if iszero(lt(mload(a), 2)) { if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a))) let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} { for { a := add(a, 0x20) } 1 { } {
let p := mload(a) let p := mload(a)
a := add(a, 0x20) a := add(a, 0x20)
result := lt(p, mload(a)) result := lt(p, mload(a))
...@@ -385,7 +373,7 @@ library LibSort { ...@@ -385,7 +373,7 @@ library LibSort {
result := 1 result := 1
if iszero(lt(mload(a), 2)) { if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a))) let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} { for { a := add(a, 0x20) } 1 { } {
let p := mload(a) let p := mload(a)
a := add(a, 0x20) a := add(a, 0x20)
result := slt(p, mload(a)) result := slt(p, mload(a))
...@@ -402,91 +390,55 @@ library LibSort { ...@@ -402,91 +390,55 @@ library LibSort {
/// @dev Returns the sorted set difference of `a` and `b`. /// @dev Returns the sorted set difference of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function difference(uint256[] memory a, uint256[] memory b) function difference(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) {
internal
pure
returns (uint256[] memory c)
{
c = _difference(a, b, 0); c = _difference(a, b, 0);
} }
/// @dev Returns the sorted set difference between `a` and `b`. /// @dev Returns the sorted set difference between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function difference(int256[] memory a, int256[] memory b) function difference(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) {
internal
pure
returns (int256[] memory c)
{
c = _toInts(_difference(_toUints(a), _toUints(b), 1 << 255)); c = _toInts(_difference(_toUints(a), _toUints(b), 1 << 255));
} }
/// @dev Returns the sorted set difference between `a` and `b`. /// @dev Returns the sorted set difference between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function difference(address[] memory a, address[] memory b) function difference(address[] memory a, address[] memory b) internal pure returns (address[] memory c) {
internal
pure
returns (address[] memory c)
{
c = _toAddresses(_difference(_toUints(a), _toUints(b), 0)); c = _toAddresses(_difference(_toUints(a), _toUints(b), 0));
} }
/// @dev Returns the sorted set intersection between `a` and `b`. /// @dev Returns the sorted set intersection between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function intersection(uint256[] memory a, uint256[] memory b) function intersection(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) {
internal
pure
returns (uint256[] memory c)
{
c = _intersection(a, b, 0); c = _intersection(a, b, 0);
} }
/// @dev Returns the sorted set intersection between `a` and `b`. /// @dev Returns the sorted set intersection between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function intersection(int256[] memory a, int256[] memory b) function intersection(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) {
internal
pure
returns (int256[] memory c)
{
c = _toInts(_intersection(_toUints(a), _toUints(b), 1 << 255)); c = _toInts(_intersection(_toUints(a), _toUints(b), 1 << 255));
} }
/// @dev Returns the sorted set intersection between `a` and `b`. /// @dev Returns the sorted set intersection between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function intersection(address[] memory a, address[] memory b) function intersection(address[] memory a, address[] memory b) internal pure returns (address[] memory c) {
internal
pure
returns (address[] memory c)
{
c = _toAddresses(_intersection(_toUints(a), _toUints(b), 0)); c = _toAddresses(_intersection(_toUints(a), _toUints(b), 0));
} }
/// @dev Returns the sorted set union of `a` and `b`. /// @dev Returns the sorted set union of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function union(uint256[] memory a, uint256[] memory b) function union(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) {
internal
pure
returns (uint256[] memory c)
{
c = _union(a, b, 0); c = _union(a, b, 0);
} }
/// @dev Returns the sorted set union of `a` and `b`. /// @dev Returns the sorted set union of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function union(int256[] memory a, int256[] memory b) function union(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) {
internal
pure
returns (int256[] memory c)
{
c = _toInts(_union(_toUints(a), _toUints(b), 1 << 255)); c = _toInts(_union(_toUints(a), _toUints(b), 1 << 255));
} }
/// @dev Returns the sorted set union between `a` and `b`. /// @dev Returns the sorted set union between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function union(address[] memory a, address[] memory b) function union(address[] memory a, address[] memory b) internal pure returns (address[] memory c) {
internal
pure
returns (address[] memory c)
{
c = _toAddresses(_union(_toUints(a), _toUints(b), 0)); c = _toAddresses(_union(_toUints(a), _toUints(b), 0));
} }
...@@ -535,7 +487,7 @@ library LibSort { ...@@ -535,7 +487,7 @@ library LibSort {
/// @solidity memory-safe-assembly /// @solidity memory-safe-assembly
assembly { assembly {
let w := shl(255, 1) let w := shl(255, 1)
for { let end := add(a, shl(5, mload(a))) } iszero(eq(a, end)) {} { for { let end := add(a, shl(5, mload(a))) } iszero(eq(a, end)) { } {
a := add(a, 0x20) a := add(a, 0x20)
mstore(a, add(mload(a), w)) mstore(a, add(mload(a), w))
} }
...@@ -544,7 +496,11 @@ library LibSort { ...@@ -544,7 +496,11 @@ library LibSort {
/// @dev Returns whether `a` contains `needle`, /// @dev Returns whether `a` contains `needle`,
/// and the index of the nearest element less than or equal to `needle`. /// and the index of the nearest element less than or equal to `needle`.
function _searchSorted(uint256[] memory a, uint256 needle, uint256 signed) function _searchSorted(
uint256[] memory a,
uint256 needle,
uint256 signed
)
private private
pure pure
returns (bool found, uint256 index) returns (bool found, uint256 index)
...@@ -555,7 +511,7 @@ library LibSort { ...@@ -555,7 +511,7 @@ library LibSort {
let s := 0x20 let s := 0x20
let l := add(a, s) // Slot of the start of search. let l := add(a, s) // Slot of the start of search.
let h := add(a, shl(5, mload(a))) // Slot of the end of search. let h := add(a, shl(5, mload(a))) // Slot of the end of search.
for { needle := add(signed, needle) } 1 {} { for { needle := add(signed, needle) } 1 { } {
// Average of `l` and `h`. // Average of `l` and `h`.
m := add(shl(5, shr(6, add(l, h))), and(31, l)) m := add(shl(5, shr(6, add(l, h))), and(31, l))
let t := add(signed, mload(m)) let t := add(signed, mload(m))
...@@ -578,7 +534,11 @@ library LibSort { ...@@ -578,7 +534,11 @@ library LibSort {
/// @dev Returns the sorted set difference of `a` and `b`. /// @dev Returns the sorted set difference of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function _difference(uint256[] memory a, uint256[] memory b, uint256 signed) function _difference(
uint256[] memory a,
uint256[] memory b,
uint256 signed
)
private private
pure pure
returns (uint256[] memory c) returns (uint256[] memory c)
...@@ -592,7 +552,7 @@ library LibSort { ...@@ -592,7 +552,7 @@ library LibSort {
a := add(a, s) a := add(a, s)
b := add(b, s) b := add(b, s)
let k := c let k := c
for {} iszero(or(gt(a, aEnd), gt(b, bEnd))) {} { for { } iszero(or(gt(a, aEnd), gt(b, bEnd))) { } {
let u := mload(a) let u := mload(a)
let v := mload(b) let v := mload(b)
if iszero(xor(u, v)) { if iszero(xor(u, v)) {
...@@ -608,7 +568,7 @@ library LibSort { ...@@ -608,7 +568,7 @@ library LibSort {
mstore(k, u) mstore(k, u)
a := add(a, s) a := add(a, s)
} }
for {} iszero(gt(a, aEnd)) {} { for { } iszero(gt(a, aEnd)) { } {
k := add(k, s) k := add(k, s)
mstore(k, mload(a)) mstore(k, mload(a))
a := add(a, s) a := add(a, s)
...@@ -620,7 +580,11 @@ library LibSort { ...@@ -620,7 +580,11 @@ library LibSort {
/// @dev Returns the sorted set intersection between `a` and `b`. /// @dev Returns the sorted set intersection between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function _intersection(uint256[] memory a, uint256[] memory b, uint256 signed) function _intersection(
uint256[] memory a,
uint256[] memory b,
uint256 signed
)
private private
pure pure
returns (uint256[] memory c) returns (uint256[] memory c)
...@@ -634,7 +598,7 @@ library LibSort { ...@@ -634,7 +598,7 @@ library LibSort {
a := add(a, s) a := add(a, s)
b := add(b, s) b := add(b, s)
let k := c let k := c
for {} iszero(or(gt(a, aEnd), gt(b, bEnd))) {} { for { } iszero(or(gt(a, aEnd), gt(b, bEnd))) { } {
let u := mload(a) let u := mload(a)
let v := mload(b) let v := mload(b)
if iszero(xor(u, v)) { if iszero(xor(u, v)) {
...@@ -657,11 +621,7 @@ library LibSort { ...@@ -657,11 +621,7 @@ library LibSort {
/// @dev Returns the sorted set union of `a` and `b`. /// @dev Returns the sorted set union of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified. /// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function _union(uint256[] memory a, uint256[] memory b, uint256 signed) function _union(uint256[] memory a, uint256[] memory b, uint256 signed) private pure returns (uint256[] memory c) {
private
pure
returns (uint256[] memory c)
{
/// @solidity memory-safe-assembly /// @solidity memory-safe-assembly
assembly { assembly {
let s := 0x20 let s := 0x20
...@@ -671,7 +631,7 @@ library LibSort { ...@@ -671,7 +631,7 @@ library LibSort {
a := add(a, s) a := add(a, s)
b := add(b, s) b := add(b, s)
let k := c let k := c
for {} iszero(or(gt(a, aEnd), gt(b, bEnd))) {} { for { } iszero(or(gt(a, aEnd), gt(b, bEnd))) { } {
let u := mload(a) let u := mload(a)
let v := mload(b) let v := mload(b)
if iszero(xor(u, v)) { if iszero(xor(u, v)) {
...@@ -691,12 +651,12 @@ library LibSort { ...@@ -691,12 +651,12 @@ library LibSort {
mstore(k, u) mstore(k, u)
a := add(a, s) a := add(a, s)
} }
for {} iszero(gt(a, aEnd)) {} { for { } iszero(gt(a, aEnd)) { } {
k := add(k, s) k := add(k, s)
mstore(k, mload(a)) mstore(k, mload(a))
a := add(a, s) a := add(a, s)
} }
for {} iszero(gt(b, bEnd)) {} { for { } iszero(gt(b, bEnd)) { } {
k := add(k, s) k := add(k, s)
mstore(k, mload(b)) mstore(k, mload(b))
b := add(b, s) b := add(b, s)
......
...@@ -68,7 +68,7 @@ contract DeleteOutput is SafeBuilder { ...@@ -68,7 +68,7 @@ contract DeleteOutput is SafeBuilder {
} }
/// @notice Test coverage of the script. /// @notice Test coverage of the script.
function test_script_succeeds() skipWhenNotForking external { function test_script_succeeds() external skipWhenNotForking {
uint256 _index = getLatestIndex(); uint256 _index = getLatestIndex();
require(_index != 0, "DeleteOutput: No outputs to delete."); require(_index != 0, "DeleteOutput: No outputs to delete.");
...@@ -103,10 +103,7 @@ contract DeleteOutput is SafeBuilder { ...@@ -103,10 +103,7 @@ contract DeleteOutput is SafeBuilder {
calls[0] = IMulticall3.Call3({ calls[0] = IMulticall3.Call3({
target: oracle, target: oracle,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(L2OutputOracle.deleteL2Outputs, (index))
L2OutputOracle.deleteL2Outputs,
(index)
)
}); });
return abi.encodeCall(IMulticall3.aggregate3, (calls)); return abi.encodeCall(IMulticall3.aggregate3, (calls));
......
...@@ -21,12 +21,10 @@ import { ProxyAdmin } from "../../src/universal/ProxyAdmin.sol"; ...@@ -21,12 +21,10 @@ import { ProxyAdmin } from "../../src/universal/ProxyAdmin.sol";
/// for the most simple user experience when using automation and no indexer. /// for the most simple user experience when using automation and no indexer.
/// Run the command without the `--broadcast` flag and it will print a tenderly URL. /// Run the command without the `--broadcast` flag and it will print a tenderly URL.
abstract contract SafeBuilder is EnhancedScript, GlobalConstants { abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// State // // State //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @notice Interface for multicall3. /// @notice Interface for multicall3.
IMulticall3 internal constant multicall = IMulticall3(MULTICALL3_ADDRESS); IMulticall3 internal constant multicall = IMulticall3(MULTICALL3_ADDRESS);
...@@ -38,10 +36,10 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -38,10 +36,10 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @notice Follow up assertions to ensure that the script ran to completion. /// @notice Follow up assertions to ensure that the script ran to completion.
function _postCheck() internal virtual view; function _postCheck() internal view virtual;
/// @notice Creates the calldata /// @notice Creates the calldata
function buildCalldata(address _proxyAdmin) internal virtual view returns (bytes memory); function buildCalldata(address _proxyAdmin) internal view virtual returns (bytes memory);
/// @notice Internal helper function to compute the safe transaction hash. /// @notice Internal helper function to compute the safe transaction hash.
function computeSafeTransactionHash(address _safe, address _proxyAdmin) public virtual returns (bytes32) { function computeSafeTransactionHash(address _safe, address _proxyAdmin) public virtual returns (bytes32) {
...@@ -119,11 +117,7 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -119,11 +117,7 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
// Send a transaction to approve the hash // Send a transaction to approve the hash
safe.approveHash(hash); safe.approveHash(hash);
logSimulationLink({ logSimulationLink({ _to: address(safe), _from: msg.sender, _data: abi.encodeCall(safe.approveHash, (hash)) });
_to: address(safe),
_from: msg.sender,
_data: abi.encodeCall(safe.approveHash, (hash))
});
uint256 threshold = safe.getThreshold(); uint256 threshold = safe.getThreshold();
address[] memory owners = safe.getOwners(); address[] memory owners = safe.getOwners();
...@@ -169,7 +163,7 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -169,7 +163,7 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
payable(address(0)), payable(address(0)),
signatures signatures
) )
) )
}); });
require(success, "call not successful"); require(success, "call not successful");
...@@ -206,4 +200,3 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -206,4 +200,3 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
return signatures; return signatures;
} }
} }
...@@ -28,31 +28,26 @@ contract EASUpgrader is SafeBuilder, Deployer { ...@@ -28,31 +28,26 @@ contract EASUpgrader is SafeBuilder, Deployer {
mapping(uint256 => ContractSet) internal proxies; mapping(uint256 => ContractSet) internal proxies;
/// @notice The expected versions for the contracts to be upgraded to. /// @notice The expected versions for the contracts to be upgraded to.
string constant internal EAS_Version = "1.0.0"; string internal constant EAS_Version = "1.0.0";
string constant internal SchemaRegistry_Version = "1.0.0"; string internal constant SchemaRegistry_Version = "1.0.0";
/// @notice Place the contract addresses in storage so they can be used when building calldata. /// @notice Place the contract addresses in storage so they can be used when building calldata.
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
implementations[OP_GOERLI] = ContractSet({ implementations[OP_GOERLI] =
EAS: getAddress("EAS"), ContractSet({ EAS: getAddress("EAS"), SchemaRegistry: getAddress("SchemaRegistry") });
SchemaRegistry: getAddress("SchemaRegistry")
});
proxies[OP_GOERLI] = ContractSet({ proxies[OP_GOERLI] = ContractSet({ EAS: Predeploys.EAS, SchemaRegistry: Predeploys.SCHEMA_REGISTRY });
EAS: Predeploys.EAS,
SchemaRegistry: Predeploys.SCHEMA_REGISTRY
});
} }
/// @notice /// @notice
function name() public override pure returns (string memory) { function name() public pure override returns (string memory) {
return "EASUpgrader"; return "EASUpgrader";
} }
/// @notice Follow up assertions to ensure that the script ran to completion. /// @notice Follow up assertions to ensure that the script ran to completion.
function _postCheck() internal override view { function _postCheck() internal view override {
ContractSet memory prox = getProxies(); ContractSet memory prox = getProxies();
require(_versionHash(prox.EAS) == keccak256(bytes(EAS_Version)), "EAS"); require(_versionHash(prox.EAS) == keccak256(bytes(EAS_Version)), "EAS");
require(_versionHash(prox.SchemaRegistry) == keccak256(bytes(SchemaRegistry_Version)), "SchemaRegistry"); require(_versionHash(prox.SchemaRegistry) == keccak256(bytes(SchemaRegistry_Version)), "SchemaRegistry");
...@@ -65,7 +60,7 @@ contract EASUpgrader is SafeBuilder, Deployer { ...@@ -65,7 +60,7 @@ contract EASUpgrader is SafeBuilder, Deployer {
/// @notice Test coverage of the logic. Should only run on goerli but other chains /// @notice Test coverage of the logic. Should only run on goerli but other chains
/// could be added. /// could be added.
function test_script_succeeds() skipWhenNotForking external { function test_script_succeeds() external skipWhenNotForking {
address _safe; address _safe;
address _proxyAdmin; address _proxyAdmin;
...@@ -96,7 +91,7 @@ contract EASUpgrader is SafeBuilder, Deployer { ...@@ -96,7 +91,7 @@ contract EASUpgrader is SafeBuilder, Deployer {
/// @notice Builds the calldata that the multisig needs to make for the upgrade to happen. /// @notice Builds the calldata that the multisig needs to make for the upgrade to happen.
/// A total of 9 calls are made to the proxy admin to upgrade the implementations /// A total of 9 calls are made to the proxy admin to upgrade the implementations
/// of the predeploys. /// of the predeploys.
function buildCalldata(address _proxyAdmin) internal override view returns (bytes memory) { function buildCalldata(address _proxyAdmin) internal view override returns (bytes memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](2); IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](2);
ContractSet memory impl = getImplementations(); ContractSet memory impl = getImplementations();
...@@ -106,20 +101,14 @@ contract EASUpgrader is SafeBuilder, Deployer { ...@@ -106,20 +101,14 @@ contract EASUpgrader is SafeBuilder, Deployer {
calls[0] = IMulticall3.Call3({ calls[0] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.EAS), impl.EAS))
ProxyAdmin.upgrade,
(payable(prox.EAS), impl.EAS)
)
}); });
// Upgrade SchemaRegistry // Upgrade SchemaRegistry
calls[1] = IMulticall3.Call3({ calls[1] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.SchemaRegistry), impl.SchemaRegistry))
ProxyAdmin.upgrade,
(payable(prox.SchemaRegistry), impl.SchemaRegistry)
)
}); });
return abi.encodeCall(IMulticall3.aggregate3, (calls)); return abi.encodeCall(IMulticall3.aggregate3, (calls));
......
...@@ -15,7 +15,6 @@ import { Semver } from "../../src/universal/Semver.sol"; ...@@ -15,7 +15,6 @@ import { Semver } from "../../src/universal/Semver.sol";
/// @title PostSherlockL1 /// @title PostSherlockL1
/// @notice Upgrade script for upgrading the L1 contracts after the sherlock audit. /// @notice Upgrade script for upgrading the L1 contracts after the sherlock audit.
contract PostSherlockL1 is SafeBuilder { contract PostSherlockL1 is SafeBuilder {
/// @notice Address of the ProxyAdmin, passed in via constructor of `run`. /// @notice Address of the ProxyAdmin, passed in via constructor of `run`.
ProxyAdmin internal PROXY_ADMIN; ProxyAdmin internal PROXY_ADMIN;
...@@ -38,13 +37,13 @@ contract PostSherlockL1 is SafeBuilder { ...@@ -38,13 +37,13 @@ contract PostSherlockL1 is SafeBuilder {
mapping(uint256 => ContractSet) internal proxies; mapping(uint256 => ContractSet) internal proxies;
/// @notice The expected versions for the contracts to be upgraded to. /// @notice The expected versions for the contracts to be upgraded to.
string constant internal L1CrossDomainMessenger_Version = "1.4.0"; string internal constant L1CrossDomainMessenger_Version = "1.4.0";
string constant internal L1StandardBridge_Version = "1.1.0"; string internal constant L1StandardBridge_Version = "1.1.0";
string constant internal L2OutputOracle_Version = "1.3.0"; string internal constant L2OutputOracle_Version = "1.3.0";
string constant internal OptimismMintableERC20Factory_Version = "1.1.0"; string internal constant OptimismMintableERC20Factory_Version = "1.1.0";
string constant internal OptimismPortal_Version = "1.6.0"; string internal constant OptimismPortal_Version = "1.6.0";
string constant internal SystemConfig_Version = "1.3.0"; string internal constant SystemConfig_Version = "1.3.0";
string constant internal L1ERC721Bridge_Version = "1.1.1"; string internal constant L1ERC721Bridge_Version = "1.1.1";
/// @notice Place the contract addresses in storage so they can be used when building calldata. /// @notice Place the contract addresses in storage so they can be used when building calldata.
function setUp() external { function setUp() external {
...@@ -70,12 +69,18 @@ contract PostSherlockL1 is SafeBuilder { ...@@ -70,12 +69,18 @@ contract PostSherlockL1 is SafeBuilder {
} }
/// @notice Follow up assertions to ensure that the script ran to completion. /// @notice Follow up assertions to ensure that the script ran to completion.
function _postCheck() internal override view { function _postCheck() internal view override {
ContractSet memory prox = getProxies(); ContractSet memory prox = getProxies();
require(_versionHash(prox.L1CrossDomainMessenger) == keccak256(bytes(L1CrossDomainMessenger_Version)), "L1CrossDomainMessenger"); require(
_versionHash(prox.L1CrossDomainMessenger) == keccak256(bytes(L1CrossDomainMessenger_Version)),
"L1CrossDomainMessenger"
);
require(_versionHash(prox.L1StandardBridge) == keccak256(bytes(L1StandardBridge_Version)), "L1StandardBridge"); require(_versionHash(prox.L1StandardBridge) == keccak256(bytes(L1StandardBridge_Version)), "L1StandardBridge");
require(_versionHash(prox.L2OutputOracle) == keccak256(bytes(L2OutputOracle_Version)), "L2OutputOracle"); require(_versionHash(prox.L2OutputOracle) == keccak256(bytes(L2OutputOracle_Version)), "L2OutputOracle");
require(_versionHash(prox.OptimismMintableERC20Factory) == keccak256(bytes(OptimismMintableERC20Factory_Version)), "OptimismMintableERC20Factory"); require(
_versionHash(prox.OptimismMintableERC20Factory) == keccak256(bytes(OptimismMintableERC20Factory_Version)),
"OptimismMintableERC20Factory"
);
require(_versionHash(prox.OptimismPortal) == keccak256(bytes(OptimismPortal_Version)), "OptimismPortal"); require(_versionHash(prox.OptimismPortal) == keccak256(bytes(OptimismPortal_Version)), "OptimismPortal");
require(_versionHash(prox.SystemConfig) == keccak256(bytes(SystemConfig_Version)), "SystemConfig"); require(_versionHash(prox.SystemConfig) == keccak256(bytes(SystemConfig_Version)), "SystemConfig");
require(_versionHash(prox.L1ERC721Bridge) == keccak256(bytes(L1ERC721Bridge_Version)), "L1ERC721Bridge"); require(_versionHash(prox.L1ERC721Bridge) == keccak256(bytes(L1ERC721Bridge_Version)), "L1ERC721Bridge");
...@@ -86,18 +91,41 @@ contract PostSherlockL1 is SafeBuilder { ...@@ -86,18 +91,41 @@ contract PostSherlockL1 is SafeBuilder {
// Check that the codehashes of all implementations match the proxies set implementations. // Check that the codehashes of all implementations match the proxies set implementations.
ContractSet memory impl = getImplementations(); ContractSet memory impl = getImplementations();
require(PROXY_ADMIN.getProxyImplementation(prox.L1CrossDomainMessenger).codehash == impl.L1CrossDomainMessenger.codehash, "L1CrossDomainMessenger codehash"); require(
require(PROXY_ADMIN.getProxyImplementation(prox.L1StandardBridge).codehash == impl.L1StandardBridge.codehash, "L1StandardBridge codehash"); PROXY_ADMIN.getProxyImplementation(prox.L1CrossDomainMessenger).codehash
require(PROXY_ADMIN.getProxyImplementation(prox.L2OutputOracle).codehash == impl.L2OutputOracle.codehash, "L2OutputOracle codehash"); == impl.L1CrossDomainMessenger.codehash,
require(PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC20Factory).codehash == impl.OptimismMintableERC20Factory.codehash, "OptimismMintableERC20Factory codehash"); "L1CrossDomainMessenger codehash"
require(PROXY_ADMIN.getProxyImplementation(prox.OptimismPortal).codehash == impl.OptimismPortal.codehash, "OptimismPortal codehash"); );
require(PROXY_ADMIN.getProxyImplementation(prox.SystemConfig).codehash == impl.SystemConfig.codehash, "SystemConfig codehash"); require(
require(PROXY_ADMIN.getProxyImplementation(prox.L1ERC721Bridge).codehash == impl.L1ERC721Bridge.codehash, "L1ERC721Bridge codehash"); PROXY_ADMIN.getProxyImplementation(prox.L1StandardBridge).codehash == impl.L1StandardBridge.codehash,
"L1StandardBridge codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.L2OutputOracle).codehash == impl.L2OutputOracle.codehash,
"L2OutputOracle codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC20Factory).codehash
== impl.OptimismMintableERC20Factory.codehash,
"OptimismMintableERC20Factory codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.OptimismPortal).codehash == impl.OptimismPortal.codehash,
"OptimismPortal codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.SystemConfig).codehash == impl.SystemConfig.codehash,
"SystemConfig codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.L1ERC721Bridge).codehash == impl.L1ERC721Bridge.codehash,
"L1ERC721Bridge codehash"
);
} }
/// @notice Test coverage of the logic. Should only run on goerli but other chains /// @notice Test coverage of the logic. Should only run on goerli but other chains
/// could be added. /// could be added.
function test_script_succeeds() skipWhenNotForking external { function test_script_succeeds() external skipWhenNotForking {
address _safe; address _safe;
address _proxyAdmin; address _proxyAdmin;
...@@ -130,7 +158,7 @@ contract PostSherlockL1 is SafeBuilder { ...@@ -130,7 +158,7 @@ contract PostSherlockL1 is SafeBuilder {
/// @notice Builds the calldata that the multisig needs to make for the upgrade to happen. /// @notice Builds the calldata that the multisig needs to make for the upgrade to happen.
/// A total of 8 calls are made, 7 upgrade implementations and 1 sets the resource /// A total of 8 calls are made, 7 upgrade implementations and 1 sets the resource
/// config to the default value in the SystemConfig contract. /// config to the default value in the SystemConfig contract.
function buildCalldata(address _proxyAdmin) internal override view returns (bytes memory) { function buildCalldata(address _proxyAdmin) internal view override returns (bytes memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](8); IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](8);
ContractSet memory impl = getImplementations(); ContractSet memory impl = getImplementations();
...@@ -141,29 +169,22 @@ contract PostSherlockL1 is SafeBuilder { ...@@ -141,29 +169,22 @@ contract PostSherlockL1 is SafeBuilder {
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(
ProxyAdmin.upgrade, ProxyAdmin.upgrade, (payable(prox.L1CrossDomainMessenger), impl.L1CrossDomainMessenger)
(payable(prox.L1CrossDomainMessenger), impl.L1CrossDomainMessenger) )
)
}); });
// Upgrade the L1StandardBridge // Upgrade the L1StandardBridge
calls[1] = IMulticall3.Call3({ calls[1] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1StandardBridge), impl.L1StandardBridge))
ProxyAdmin.upgrade,
(payable(prox.L1StandardBridge), impl.L1StandardBridge)
)
}); });
// Upgrade the L2OutputOracle // Upgrade the L2OutputOracle
calls[2] = IMulticall3.Call3({ calls[2] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2OutputOracle), impl.L2OutputOracle))
ProxyAdmin.upgrade,
(payable(prox.L2OutputOracle), impl.L2OutputOracle)
)
}); });
// Upgrade the OptimismMintableERC20Factory // Upgrade the OptimismMintableERC20Factory
...@@ -171,39 +192,29 @@ contract PostSherlockL1 is SafeBuilder { ...@@ -171,39 +192,29 @@ contract PostSherlockL1 is SafeBuilder {
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(
ProxyAdmin.upgrade, ProxyAdmin.upgrade, (payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory)
(payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory) )
)
}); });
// Upgrade the OptimismPortal // Upgrade the OptimismPortal
calls[4] = IMulticall3.Call3({ calls[4] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.OptimismPortal), impl.OptimismPortal))
ProxyAdmin.upgrade,
(payable(prox.OptimismPortal), impl.OptimismPortal)
)
}); });
// Upgrade the SystemConfig // Upgrade the SystemConfig
calls[5] = IMulticall3.Call3({ calls[5] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.SystemConfig), impl.SystemConfig))
ProxyAdmin.upgrade,
(payable(prox.SystemConfig), impl.SystemConfig)
)
}); });
// Upgrade the L1ERC721Bridge // Upgrade the L1ERC721Bridge
calls[6] = IMulticall3.Call3({ calls[6] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1ERC721Bridge), impl.L1ERC721Bridge))
ProxyAdmin.upgrade,
(payable(prox.L1ERC721Bridge), impl.L1ERC721Bridge)
)
}); });
// Set the default resource config // Set the default resource config
......
...@@ -37,17 +37,17 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -37,17 +37,17 @@ contract PostSherlockL2 is SafeBuilder {
mapping(uint256 => ContractSet) internal proxies; mapping(uint256 => ContractSet) internal proxies;
/// @notice The expected versions for the contracts to be upgraded to. /// @notice The expected versions for the contracts to be upgraded to.
string constant internal BaseFeeVault_Version = "1.1.0"; string internal constant BaseFeeVault_Version = "1.1.0";
string constant internal GasPriceOracle_Version = "1.0.0"; string internal constant GasPriceOracle_Version = "1.0.0";
string constant internal L1Block_Version = "1.0.0"; string internal constant L1Block_Version = "1.0.0";
string constant internal L1FeeVault_Version = "1.1.0"; string internal constant L1FeeVault_Version = "1.1.0";
string constant internal L2CrossDomainMessenger_Version = "1.4.0"; string internal constant L2CrossDomainMessenger_Version = "1.4.0";
string constant internal L2ERC721Bridge_Version = "1.1.0"; string internal constant L2ERC721Bridge_Version = "1.1.0";
string constant internal L2StandardBridge_Version = "1.1.0"; string internal constant L2StandardBridge_Version = "1.1.0";
string constant internal L2ToL1MessagePasser_Version = "1.0.0"; string internal constant L2ToL1MessagePasser_Version = "1.0.0";
string constant internal SequencerFeeVault_Version = "1.1.0"; string internal constant SequencerFeeVault_Version = "1.1.0";
string constant internal OptimismMintableERC20Factory_Version = "1.1.0"; string internal constant OptimismMintableERC20Factory_Version = "1.1.0";
string constant internal OptimismMintableERC721Factory_Version = "1.2.0"; string internal constant OptimismMintableERC721Factory_Version = "1.2.0";
/// @notice Place the contract addresses in storage so they can be used when building calldata. /// @notice Place the contract addresses in storage so they can be used when building calldata.
function setUp() external { function setUp() external {
...@@ -81,19 +81,33 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -81,19 +81,33 @@ contract PostSherlockL2 is SafeBuilder {
} }
/// @notice Follow up assertions to ensure that the script ran to completion. /// @notice Follow up assertions to ensure that the script ran to completion.
function _postCheck() internal override view { function _postCheck() internal view override {
ContractSet memory prox = getProxies(); ContractSet memory prox = getProxies();
require(_versionHash(prox.BaseFeeVault) == keccak256(bytes(BaseFeeVault_Version)), "BaseFeeVault"); require(_versionHash(prox.BaseFeeVault) == keccak256(bytes(BaseFeeVault_Version)), "BaseFeeVault");
require(_versionHash(prox.GasPriceOracle) == keccak256(bytes(GasPriceOracle_Version)), "GasPriceOracle"); require(_versionHash(prox.GasPriceOracle) == keccak256(bytes(GasPriceOracle_Version)), "GasPriceOracle");
require(_versionHash(prox.L1Block) == keccak256(bytes(L1Block_Version)), "L1Block"); require(_versionHash(prox.L1Block) == keccak256(bytes(L1Block_Version)), "L1Block");
require(_versionHash(prox.L1FeeVault) == keccak256(bytes(L1FeeVault_Version)), "L1FeeVault"); require(_versionHash(prox.L1FeeVault) == keccak256(bytes(L1FeeVault_Version)), "L1FeeVault");
require(_versionHash(prox.L2CrossDomainMessenger) == keccak256(bytes(L2CrossDomainMessenger_Version)), "L2CrossDomainMessenger"); require(
_versionHash(prox.L2CrossDomainMessenger) == keccak256(bytes(L2CrossDomainMessenger_Version)),
"L2CrossDomainMessenger"
);
require(_versionHash(prox.L2ERC721Bridge) == keccak256(bytes(L2ERC721Bridge_Version)), "L2ERC721Bridge"); require(_versionHash(prox.L2ERC721Bridge) == keccak256(bytes(L2ERC721Bridge_Version)), "L2ERC721Bridge");
require(_versionHash(prox.L2StandardBridge) == keccak256(bytes(L2StandardBridge_Version)), "L2StandardBridge"); require(_versionHash(prox.L2StandardBridge) == keccak256(bytes(L2StandardBridge_Version)), "L2StandardBridge");
require(_versionHash(prox.L2ToL1MessagePasser) == keccak256(bytes(L2ToL1MessagePasser_Version)), "L2ToL1MessagePasser"); require(
require(_versionHash(prox.SequencerFeeVault) == keccak256(bytes(SequencerFeeVault_Version)), "SequencerFeeVault"); _versionHash(prox.L2ToL1MessagePasser) == keccak256(bytes(L2ToL1MessagePasser_Version)),
require(_versionHash(prox.OptimismMintableERC20Factory) == keccak256(bytes(OptimismMintableERC20Factory_Version)), "OptimismMintableERC20Factory"); "L2ToL1MessagePasser"
require(_versionHash(prox.OptimismMintableERC721Factory) == keccak256(bytes(OptimismMintableERC721Factory_Version)), "OptimismMintableERC721Factory"); );
require(
_versionHash(prox.SequencerFeeVault) == keccak256(bytes(SequencerFeeVault_Version)), "SequencerFeeVault"
);
require(
_versionHash(prox.OptimismMintableERC20Factory) == keccak256(bytes(OptimismMintableERC20Factory_Version)),
"OptimismMintableERC20Factory"
);
require(
_versionHash(prox.OptimismMintableERC721Factory) == keccak256(bytes(OptimismMintableERC721Factory_Version)),
"OptimismMintableERC721Factory"
);
// Check that the codehashes of all implementations match the proxies set implementations. // Check that the codehashes of all implementations match the proxies set implementations.
ContractSet memory impl = getImplementations(); ContractSet memory impl = getImplementations();
...@@ -101,18 +115,29 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -101,18 +115,29 @@ contract PostSherlockL2 is SafeBuilder {
require(PROXY_ADMIN.getProxyImplementation(prox.GasPriceOracle).codehash == impl.GasPriceOracle.codehash); require(PROXY_ADMIN.getProxyImplementation(prox.GasPriceOracle).codehash == impl.GasPriceOracle.codehash);
require(PROXY_ADMIN.getProxyImplementation(prox.L1Block).codehash == impl.L1Block.codehash); require(PROXY_ADMIN.getProxyImplementation(prox.L1Block).codehash == impl.L1Block.codehash);
require(PROXY_ADMIN.getProxyImplementation(prox.L1FeeVault).codehash == impl.L1FeeVault.codehash); require(PROXY_ADMIN.getProxyImplementation(prox.L1FeeVault).codehash == impl.L1FeeVault.codehash);
require(PROXY_ADMIN.getProxyImplementation(prox.L2CrossDomainMessenger).codehash == impl.L2CrossDomainMessenger.codehash); require(
PROXY_ADMIN.getProxyImplementation(prox.L2CrossDomainMessenger).codehash
== impl.L2CrossDomainMessenger.codehash
);
require(PROXY_ADMIN.getProxyImplementation(prox.L2ERC721Bridge).codehash == impl.L2ERC721Bridge.codehash); require(PROXY_ADMIN.getProxyImplementation(prox.L2ERC721Bridge).codehash == impl.L2ERC721Bridge.codehash);
require(PROXY_ADMIN.getProxyImplementation(prox.L2StandardBridge).codehash == impl.L2StandardBridge.codehash); require(PROXY_ADMIN.getProxyImplementation(prox.L2StandardBridge).codehash == impl.L2StandardBridge.codehash);
require(PROXY_ADMIN.getProxyImplementation(prox.L2ToL1MessagePasser).codehash == impl.L2ToL1MessagePasser.codehash); require(
PROXY_ADMIN.getProxyImplementation(prox.L2ToL1MessagePasser).codehash == impl.L2ToL1MessagePasser.codehash
);
require(PROXY_ADMIN.getProxyImplementation(prox.SequencerFeeVault).codehash == impl.SequencerFeeVault.codehash); require(PROXY_ADMIN.getProxyImplementation(prox.SequencerFeeVault).codehash == impl.SequencerFeeVault.codehash);
require(PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC20Factory).codehash == impl.OptimismMintableERC20Factory.codehash); require(
require(PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC721Factory).codehash == impl.OptimismMintableERC721Factory.codehash); PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC20Factory).codehash
== impl.OptimismMintableERC20Factory.codehash
);
require(
PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC721Factory).codehash
== impl.OptimismMintableERC721Factory.codehash
);
} }
/// @notice Test coverage of the logic. Should only run on goerli but other chains /// @notice Test coverage of the logic. Should only run on goerli but other chains
/// could be added. /// could be added.
function test_script_succeeds() skipWhenNotForking external { function test_script_succeeds() external skipWhenNotForking {
address _safe; address _safe;
address _proxyAdmin; address _proxyAdmin;
...@@ -143,7 +168,7 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -143,7 +168,7 @@ contract PostSherlockL2 is SafeBuilder {
/// @notice Builds the calldata that the multisig needs to make for the upgrade to happen. /// @notice Builds the calldata that the multisig needs to make for the upgrade to happen.
/// A total of 9 calls are made to the proxy admin to upgrade the implementations /// A total of 9 calls are made to the proxy admin to upgrade the implementations
/// of the predeploys. /// of the predeploys.
function buildCalldata(address _proxyAdmin) internal override view returns (bytes memory) { function buildCalldata(address _proxyAdmin) internal view override returns (bytes memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](11); IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](11);
ContractSet memory impl = getImplementations(); ContractSet memory impl = getImplementations();
...@@ -153,40 +178,28 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -153,40 +178,28 @@ contract PostSherlockL2 is SafeBuilder {
calls[0] = IMulticall3.Call3({ calls[0] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.BaseFeeVault), impl.BaseFeeVault))
ProxyAdmin.upgrade,
(payable(prox.BaseFeeVault), impl.BaseFeeVault)
)
}); });
// Upgrade the GasPriceOracle // Upgrade the GasPriceOracle
calls[1] = IMulticall3.Call3({ calls[1] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.GasPriceOracle), impl.GasPriceOracle))
ProxyAdmin.upgrade,
(payable(prox.GasPriceOracle), impl.GasPriceOracle)
)
}); });
// Upgrade the L1Block predeploy // Upgrade the L1Block predeploy
calls[2] = IMulticall3.Call3({ calls[2] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1Block), impl.L1Block))
ProxyAdmin.upgrade,
(payable(prox.L1Block), impl.L1Block)
)
}); });
// Upgrade the L1FeeVault // Upgrade the L1FeeVault
calls[3] = IMulticall3.Call3({ calls[3] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1FeeVault), impl.L1FeeVault))
ProxyAdmin.upgrade,
(payable(prox.L1FeeVault), impl.L1FeeVault)
)
}); });
// Upgrade the L2CrossDomainMessenger // Upgrade the L2CrossDomainMessenger
...@@ -194,49 +207,36 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -194,49 +207,36 @@ contract PostSherlockL2 is SafeBuilder {
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(
ProxyAdmin.upgrade, ProxyAdmin.upgrade, (payable(prox.L2CrossDomainMessenger), impl.L2CrossDomainMessenger)
(payable(prox.L2CrossDomainMessenger), impl.L2CrossDomainMessenger) )
)
}); });
// Upgrade the L2ERC721Bridge // Upgrade the L2ERC721Bridge
calls[5] = IMulticall3.Call3({ calls[5] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2ERC721Bridge), impl.L2ERC721Bridge))
ProxyAdmin.upgrade,
(payable(prox.L2ERC721Bridge), impl.L2ERC721Bridge)
)
}); });
// Upgrade the L2StandardBridge // Upgrade the L2StandardBridge
calls[6] = IMulticall3.Call3({ calls[6] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2StandardBridge), impl.L2StandardBridge))
ProxyAdmin.upgrade,
(payable(prox.L2StandardBridge), impl.L2StandardBridge)
)
}); });
// Upgrade the L2ToL1MessagePasser // Upgrade the L2ToL1MessagePasser
calls[7] = IMulticall3.Call3({ calls[7] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2ToL1MessagePasser), impl.L2ToL1MessagePasser))
ProxyAdmin.upgrade,
(payable(prox.L2ToL1MessagePasser), impl.L2ToL1MessagePasser)
)
}); });
// Upgrade the SequencerFeeVault // Upgrade the SequencerFeeVault
calls[8] = IMulticall3.Call3({ calls[8] = IMulticall3.Call3({
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.SequencerFeeVault), impl.SequencerFeeVault))
ProxyAdmin.upgrade,
(payable(prox.SequencerFeeVault), impl.SequencerFeeVault)
)
}); });
// Upgrade the OptimismMintableERC20Factory // Upgrade the OptimismMintableERC20Factory
...@@ -244,9 +244,8 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -244,9 +244,8 @@ contract PostSherlockL2 is SafeBuilder {
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(
ProxyAdmin.upgrade, ProxyAdmin.upgrade, (payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory)
(payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory) )
)
}); });
// Upgrade the OptimismMintableERC721Factory // Upgrade the OptimismMintableERC721Factory
...@@ -254,9 +253,8 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -254,9 +253,8 @@ contract PostSherlockL2 is SafeBuilder {
target: _proxyAdmin, target: _proxyAdmin,
allowFailure: false, allowFailure: false,
callData: abi.encodeCall( callData: abi.encodeCall(
ProxyAdmin.upgrade, ProxyAdmin.upgrade, (payable(prox.OptimismMintableERC721Factory), impl.OptimismMintableERC721Factory)
(payable(prox.OptimismMintableERC721Factory), impl.OptimismMintableERC721Factory) )
)
}); });
return abi.encodeCall(IMulticall3.aggregate3, (calls)); return abi.encodeCall(IMulticall3.aggregate3, (calls));
......
...@@ -85,8 +85,7 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -85,8 +85,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
uint256[MAX_GAP - 3] private __gap; uint256[MAX_GAP - 3] private __gap;
/// @dev Creates a new EAS instance. /// @dev Creates a new EAS instance.
constructor() Semver(1, 0, 1) EIP712Verifier("EAS", "1.0.1") { constructor() Semver(1, 0, 1) EIP712Verifier("EAS", "1.0.1") { }
}
/// @inheritdoc IEAS /// @inheritdoc IEAS
function getSchemaRegistry() external pure returns (ISchemaRegistry) { function getSchemaRegistry() external pure returns (ISchemaRegistry) {
...@@ -101,9 +100,11 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -101,9 +100,11 @@ contract EAS is IEAS, Semver, EIP712Verifier {
} }
/// @inheritdoc IEAS /// @inheritdoc IEAS
function attestByDelegation( function attestByDelegation(DelegatedAttestationRequest calldata delegatedRequest)
DelegatedAttestationRequest calldata delegatedRequest external
) external payable returns (bytes32) { payable
returns (bytes32)
{
_verifyAttest(delegatedRequest); _verifyAttest(delegatedRequest);
AttestationRequestData[] memory data = new AttestationRequestData[](1); AttestationRequestData[] memory data = new AttestationRequestData[](1);
...@@ -112,7 +113,11 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -112,7 +113,11 @@ contract EAS is IEAS, Semver, EIP712Verifier {
} }
/// @inheritdoc IEAS /// @inheritdoc IEAS
function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory) { function multiAttest(MultiAttestationRequest[] calldata multiRequests)
external
payable
returns (bytes32[] memory)
{
// Since a multi-attest call is going to make multiple attestations for multiple schemas, we'd need to collect // Since a multi-attest call is going to make multiple attestations for multiple schemas, we'd need to collect
// all the returned UIDs into a single list. // all the returned UIDs into a single list.
bytes32[][] memory totalUids = new bytes32[][](multiRequests.length); bytes32[][] memory totalUids = new bytes32[][](multiRequests.length);
...@@ -122,7 +127,7 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -122,7 +127,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
// from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless // from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless
// some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be // some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be
// possible to send too much ETH anyway. // possible to send too much ETH anyway.
uint availableValue = msg.value; uint256 availableValue = msg.value;
for (uint256 i = 0; i < multiRequests.length; i = uncheckedInc(i)) { for (uint256 i = 0; i < multiRequests.length; i = uncheckedInc(i)) {
// The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there // The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there
...@@ -135,13 +140,8 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -135,13 +140,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
// Process the current batch of attestations. // Process the current batch of attestations.
MultiAttestationRequest calldata multiRequest = multiRequests[i]; MultiAttestationRequest calldata multiRequest = multiRequests[i];
AttestationsResult memory res = _attest( AttestationsResult memory res =
multiRequest.schema, _attest(multiRequest.schema, multiRequest.data, msg.sender, availableValue, last);
multiRequest.data,
msg.sender,
availableValue,
last
);
// Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch. // Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch.
availableValue -= res.usedValue; availableValue -= res.usedValue;
...@@ -158,9 +158,11 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -158,9 +158,11 @@ contract EAS is IEAS, Semver, EIP712Verifier {
} }
/// @inheritdoc IEAS /// @inheritdoc IEAS
function multiAttestByDelegation( function multiAttestByDelegation(MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests)
MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests external
) external payable returns (bytes32[] memory) { payable
returns (bytes32[] memory)
{
// Since a multi-attest call is going to make multiple attestations for multiple schemas, we'd need to collect // Since a multi-attest call is going to make multiple attestations for multiple schemas, we'd need to collect
// all the returned UIDs into a single list. // all the returned UIDs into a single list.
bytes32[][] memory totalUids = new bytes32[][](multiDelegatedRequests.length); bytes32[][] memory totalUids = new bytes32[][](multiDelegatedRequests.length);
...@@ -170,7 +172,7 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -170,7 +172,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
// from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless // from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless
// some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be // some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be
// possible to send too much ETH anyway. // possible to send too much ETH anyway.
uint availableValue = msg.value; uint256 availableValue = msg.value;
for (uint256 i = 0; i < multiDelegatedRequests.length; i = uncheckedInc(i)) { for (uint256 i = 0; i < multiDelegatedRequests.length; i = uncheckedInc(i)) {
// The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there // The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there
...@@ -189,7 +191,8 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -189,7 +191,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
revert InvalidLength(); revert InvalidLength();
} }
// Verify EIP712 signatures. Please note that the signatures are assumed to be signed with increasing nonces. // Verify EIP712 signatures. Please note that the signatures are assumed to be signed with increasing
// nonces.
for (uint256 j = 0; j < data.length; j = uncheckedInc(j)) { for (uint256 j = 0; j < data.length; j = uncheckedInc(j)) {
_verifyAttest( _verifyAttest(
DelegatedAttestationRequest({ DelegatedAttestationRequest({
...@@ -202,13 +205,8 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -202,13 +205,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
} }
// Process the current batch of attestations. // Process the current batch of attestations.
AttestationsResult memory res = _attest( AttestationsResult memory res =
multiDelegatedRequest.schema, _attest(multiDelegatedRequest.schema, data, multiDelegatedRequest.attester, availableValue, last);
data,
multiDelegatedRequest.attester,
availableValue,
last
);
// Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch. // Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch.
availableValue -= res.usedValue; availableValue -= res.usedValue;
...@@ -248,7 +246,7 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -248,7 +246,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
// from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless // from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless
// some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be // some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be
// possible to send too much ETH anyway. // possible to send too much ETH anyway.
uint availableValue = msg.value; uint256 availableValue = msg.value;
for (uint256 i = 0; i < multiRequests.length; i = uncheckedInc(i)) { for (uint256 i = 0; i < multiRequests.length; i = uncheckedInc(i)) {
// The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there // The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there
...@@ -267,14 +265,15 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -267,14 +265,15 @@ contract EAS is IEAS, Semver, EIP712Verifier {
} }
/// @inheritdoc IEAS /// @inheritdoc IEAS
function multiRevokeByDelegation( function multiRevokeByDelegation(MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests)
MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests external
) external payable { payable
{
// We are keeping track of the total available ETH amount that can be sent to resolvers and will keep deducting // We are keeping track of the total available ETH amount that can be sent to resolvers and will keep deducting
// from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless // from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless
// some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be // some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be
// possible to send too much ETH anyway. // possible to send too much ETH anyway.
uint availableValue = msg.value; uint256 availableValue = msg.value;
for (uint256 i = 0; i < multiDelegatedRequests.length; i = uncheckedInc(i)) { for (uint256 i = 0; i < multiDelegatedRequests.length; i = uncheckedInc(i)) {
// The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there // The last batch is handled slightly differently: if the total available ETH wasn't spent in full and there
...@@ -293,7 +292,8 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -293,7 +292,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
revert InvalidLength(); revert InvalidLength();
} }
// Verify EIP712 signatures. Please note that the signatures are assumed to be signed with increasing nonces. // Verify EIP712 signatures. Please note that the signatures are assumed to be signed with increasing
// nonces.
for (uint256 j = 0; j < data.length; j = uncheckedInc(j)) { for (uint256 j = 0; j < data.length; j = uncheckedInc(j)) {
_verifyRevoke( _verifyRevoke(
DelegatedRevocationRequest({ DelegatedRevocationRequest({
...@@ -306,13 +306,8 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -306,13 +306,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
} }
// Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch. // Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch.
availableValue -= _revoke( availableValue -=
multiDelegatedRequest.schema, _revoke(multiDelegatedRequest.schema, data, multiDelegatedRequest.revoker, availableValue, last);
data,
multiDelegatedRequest.revoker,
availableValue,
last
);
} }
} }
...@@ -387,7 +382,10 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -387,7 +382,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
address attester, address attester,
uint256 availableValue, uint256 availableValue,
bool last bool last
) private returns (AttestationsResult memory) { )
private
returns (AttestationsResult memory)
{
uint256 length = data.length; uint256 length = data.length;
AttestationsResult memory res; AttestationsResult memory res;
...@@ -478,7 +476,10 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -478,7 +476,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
address revoker, address revoker,
uint256 availableValue, uint256 availableValue,
bool last bool last
) private returns (uint256) { )
private
returns (uint256)
{
// Ensure that a non-existing schema ID wasn't passed by accident. // Ensure that a non-existing schema ID wasn't passed by accident.
SchemaRecord memory schemaRecord = _schemaRegistry.getSchema(schema); SchemaRecord memory schemaRecord = _schemaRegistry.getSchema(schema);
if (schemaRecord.uid == EMPTY_UID) { if (schemaRecord.uid == EMPTY_UID) {
...@@ -509,7 +510,8 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -509,7 +510,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
revert AccessDenied(); revert AccessDenied();
} }
// Please note that also checking of the schema itself is revocable is unnecessary, since it's not possible to // Please note that also checking of the schema itself is revocable is unnecessary, since it's not possible
// to
// make revocable attestations to an irrevocable schema. // make revocable attestations to an irrevocable schema.
if (!attestation.revocable) { if (!attestation.revocable) {
revert Irrevocable(); revert Irrevocable();
...@@ -545,7 +547,10 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -545,7 +547,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
bool isRevocation, bool isRevocation,
uint256 availableValue, uint256 availableValue,
bool last bool last
) private returns (uint256) { )
private
returns (uint256)
{
ISchemaResolver resolver = schemaRecord.resolver; ISchemaResolver resolver = schemaRecord.resolver;
if (address(resolver) == address(0)) { if (address(resolver) == address(0)) {
// Ensure that we don't accept payments if there is no resolver. // Ensure that we don't accept payments if there is no resolver.
...@@ -601,7 +606,10 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -601,7 +606,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
bool isRevocation, bool isRevocation,
uint256 availableValue, uint256 availableValue,
bool last bool last
) private returns (uint256) { )
private
returns (uint256)
{
uint256 length = attestations.length; uint256 length = attestations.length;
if (length == 1) { if (length == 1) {
return _resolveAttestation(schemaRecord, attestations[0], values[0], isRevocation, availableValue, last); return _resolveAttestation(schemaRecord, attestations[0], values[0], isRevocation, availableValue, last);
...@@ -661,20 +669,19 @@ contract EAS is IEAS, Semver, EIP712Verifier { ...@@ -661,20 +669,19 @@ contract EAS is IEAS, Semver, EIP712Verifier {
/// @param bump A bump value to use in case of a UID conflict. /// @param bump A bump value to use in case of a UID conflict.
/// @return Attestation UID. /// @return Attestation UID.
function _getUID(Attestation memory attestation, uint32 bump) private pure returns (bytes32) { function _getUID(Attestation memory attestation, uint32 bump) private pure returns (bytes32) {
return return keccak256(
keccak256( abi.encodePacked(
abi.encodePacked( attestation.schema,
attestation.schema, attestation.recipient,
attestation.recipient, attestation.attester,
attestation.attester, attestation.time,
attestation.time, attestation.expirationTime,
attestation.expirationTime, attestation.revocable,
attestation.revocable, attestation.refUID,
attestation.refUID, attestation.data,
attestation.data, bump
bump )
) );
);
} }
/// @dev Refunds remaining ETH amount to the attester. /// @dev Refunds remaining ETH amount to the attester.
......
...@@ -11,7 +11,8 @@ struct AttestationRequestData { ...@@ -11,7 +11,8 @@ struct AttestationRequestData {
bool revocable; // Whether the attestation is revocable. bool revocable; // Whether the attestation is revocable.
bytes32 refUID; // The UID of the related attestation. bytes32 refUID; // The UID of the related attestation.
bytes data; // Custom attestation data. bytes data; // Custom attestation data.
uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors. uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user
// errors.
} }
/// @dev A struct representing the full arguments of the attestation request. /// @dev A struct representing the full arguments of the attestation request.
...@@ -38,14 +39,16 @@ struct MultiAttestationRequest { ...@@ -38,14 +39,16 @@ struct MultiAttestationRequest {
struct MultiDelegatedAttestationRequest { struct MultiDelegatedAttestationRequest {
bytes32 schema; // The unique identifier of the schema. bytes32 schema; // The unique identifier of the schema.
AttestationRequestData[] data; // The arguments of the attestation requests. AttestationRequestData[] data; // The arguments of the attestation requests.
EIP712Signature[] signatures; // The EIP712 signatures data. Please note that the signatures are assumed to be signed with increasing nonces. EIP712Signature[] signatures; // The EIP712 signatures data. Please note that the signatures are assumed to be
// signed with increasing nonces.
address attester; // The attesting account. address attester; // The attesting account.
} }
/// @dev A struct representing the arguments of the revocation request. /// @dev A struct representing the arguments of the revocation request.
struct RevocationRequestData { struct RevocationRequestData {
bytes32 uid; // The UID of the attestation to revoke. bytes32 uid; // The UID of the attestation to revoke.
uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors. uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user
// errors.
} }
/// @dev A struct representing the full arguments of the revocation request. /// @dev A struct representing the full arguments of the revocation request.
...@@ -72,7 +75,8 @@ struct MultiRevocationRequest { ...@@ -72,7 +75,8 @@ struct MultiRevocationRequest {
struct MultiDelegatedRevocationRequest { struct MultiDelegatedRevocationRequest {
bytes32 schema; // The unique identifier of the schema. bytes32 schema; // The unique identifier of the schema.
RevocationRequestData[] data; // The arguments of the revocation requests. RevocationRequestData[] data; // The arguments of the revocation requests.
EIP712Signature[] signatures; // The EIP712 signatures data. Please note that the signatures are assumed to be signed with increasing nonces. EIP712Signature[] signatures; // The EIP712 signatures data. Please note that the signatures are assumed to be
// signed with increasing nonces.
address revoker; // The revoking account. address revoker; // The revoking account.
} }
...@@ -152,9 +156,10 @@ interface IEAS { ...@@ -152,9 +156,10 @@ interface IEAS {
/// ///
/// @param delegatedRequest The arguments of the delegated attestation request. /// @param delegatedRequest The arguments of the delegated attestation request.
/// @return The UID of the new attestation. /// @return The UID of the new attestation.
function attestByDelegation( function attestByDelegation(DelegatedAttestationRequest calldata delegatedRequest)
DelegatedAttestationRequest calldata delegatedRequest external
) external payable returns (bytes32); payable
returns (bytes32);
/// @notice Attests to multiple schemas. /// @notice Attests to multiple schemas.
/// ///
...@@ -194,7 +199,10 @@ interface IEAS { ...@@ -194,7 +199,10 @@ interface IEAS {
/// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct /// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct
/// schema ids to benefit from the best batching optimization. /// schema ids to benefit from the best batching optimization.
/// @return The UIDs of the new attestations. /// @return The UIDs of the new attestations.
function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory); function multiAttest(MultiAttestationRequest[] calldata multiRequests)
external
payable
returns (bytes32[] memory);
/// @notice Attests to multiple schemas using via provided EIP712 signatures. /// @notice Attests to multiple schemas using via provided EIP712 signatures.
/// ///
...@@ -234,9 +242,10 @@ interface IEAS { ...@@ -234,9 +242,10 @@ interface IEAS {
/// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be /// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be
/// grouped by distinct schema ids to benefit from the best batching optimization. /// grouped by distinct schema ids to benefit from the best batching optimization.
/// @return The UIDs of the new attestations. /// @return The UIDs of the new attestations.
function multiAttestByDelegation( function multiAttestByDelegation(MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests)
MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests external
) external payable returns (bytes32[] memory); payable
returns (bytes32[] memory);
/// @notice Revokes an existing attestation to a specific schema. /// @notice Revokes an existing attestation to a specific schema.
/// ///
...@@ -328,11 +337,12 @@ interface IEAS { ...@@ -328,11 +337,12 @@ interface IEAS {
/// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992'
/// }]) /// }])
/// ///
/// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests should be /// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests
/// should be
/// grouped by distinct schema ids to benefit from the best batching optimization. /// grouped by distinct schema ids to benefit from the best batching optimization.
function multiRevokeByDelegation( function multiRevokeByDelegation(MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests)
MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests external
) external payable; payable;
/// @notice Timestamps the specified bytes32 data. /// @notice Timestamps the specified bytes32 data.
/// @param data The data to timestamp. /// @param data The data to timestamp.
......
...@@ -22,16 +22,12 @@ contract SchemaRegistry is ISchemaRegistry, Semver { ...@@ -22,16 +22,12 @@ contract SchemaRegistry is ISchemaRegistry, Semver {
uint256[MAX_GAP - 1] private __gap; uint256[MAX_GAP - 1] private __gap;
/// @dev Creates a new SchemaRegistry instance. /// @dev Creates a new SchemaRegistry instance.
constructor() Semver(1, 0, 1) {} constructor() Semver(1, 0, 1) { }
/// @inheritdoc ISchemaRegistry /// @inheritdoc ISchemaRegistry
function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32) { function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32) {
SchemaRecord memory schemaRecord = SchemaRecord({ SchemaRecord memory schemaRecord =
uid: EMPTY_UID, SchemaRecord({ uid: EMPTY_UID, schema: schema, resolver: resolver, revocable: revocable });
schema: schema,
resolver: resolver,
revocable: revocable
});
bytes32 uid = _getUID(schemaRecord); bytes32 uid = _getUID(schemaRecord);
if (_registry[uid].uid != EMPTY_UID) { if (_registry[uid].uid != EMPTY_UID) {
......
...@@ -20,7 +20,8 @@ import { EIP712Signature, InvalidSignature, MAX_GAP, stringToBytes32, bytes32ToS ...@@ -20,7 +20,8 @@ import { EIP712Signature, InvalidSignature, MAX_GAP, stringToBytes32, bytes32ToS
/// @notice The EIP712 typed signatures verifier for EAS delegated attestations. /// @notice The EIP712 typed signatures verifier for EAS delegated attestations.
abstract contract EIP712Verifier is EIP712 { abstract contract EIP712Verifier is EIP712 {
// The hash of the data type used to relay calls to the attest function. It's the value of // The hash of the data type used to relay calls to the attest function. It's the value of
// keccak256("Attest(bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32 refUID,bytes data,uint256 nonce)"). // keccak256("Attest(bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32 refUID,bytes
// data,uint256 nonce)").
bytes32 private constant ATTEST_TYPEHASH = 0xdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de61; bytes32 private constant ATTEST_TYPEHASH = 0xdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de61;
// The hash of the data type used to relay calls to the revoke function. It's the value of // The hash of the data type used to relay calls to the revoke function. It's the value of
......
...@@ -22,7 +22,10 @@ interface ISchemaResolver { ...@@ -22,7 +22,10 @@ interface ISchemaResolver {
function multiAttest( function multiAttest(
Attestation[] calldata attestations, Attestation[] calldata attestations,
uint256[] calldata values uint256[] calldata values
) external payable returns (bool); )
external
payable
returns (bool);
/// @notice Processes an attestation revocation and verifies if it can be revoked. /// @notice Processes an attestation revocation and verifies if it can be revoked.
/// @param attestation The existing attestation to be revoked. /// @param attestation The existing attestation to be revoked.
...@@ -36,5 +39,8 @@ interface ISchemaResolver { ...@@ -36,5 +39,8 @@ interface ISchemaResolver {
function multiRevoke( function multiRevoke(
Attestation[] calldata attestations, Attestation[] calldata attestations,
uint256[] calldata values uint256[] calldata values
) external payable returns (bool); )
external
payable
returns (bool);
} }
...@@ -56,7 +56,12 @@ abstract contract SchemaResolver is ISchemaResolver, Semver { ...@@ -56,7 +56,12 @@ abstract contract SchemaResolver is ISchemaResolver, Semver {
function multiAttest( function multiAttest(
Attestation[] calldata attestations, Attestation[] calldata attestations,
uint256[] calldata values uint256[] calldata values
) external payable onlyEAS returns (bool) { )
external
payable
onlyEAS
returns (bool)
{
uint256 length = attestations.length; uint256 length = attestations.length;
// We are keeping track of the remaining ETH amount that can be sent to resolvers and will keep deducting // We are keeping track of the remaining ETH amount that can be sent to resolvers and will keep deducting
...@@ -95,7 +100,12 @@ abstract contract SchemaResolver is ISchemaResolver, Semver { ...@@ -95,7 +100,12 @@ abstract contract SchemaResolver is ISchemaResolver, Semver {
function multiRevoke( function multiRevoke(
Attestation[] calldata attestations, Attestation[] calldata attestations,
uint256[] calldata values uint256[] calldata values
) external payable onlyEAS returns (bool) { )
external
payable
onlyEAS
returns (bool)
{
uint256 length = attestations.length; uint256 length = attestations.length;
// We are keeping track of the remaining ETH amount that can be sent to resolvers and will keep deducting // We are keeping track of the remaining ETH amount that can be sent to resolvers and will keep deducting
...@@ -128,8 +138,10 @@ abstract contract SchemaResolver is ISchemaResolver, Semver { ...@@ -128,8 +138,10 @@ abstract contract SchemaResolver is ISchemaResolver, Semver {
/// @notice A resolver callback that should be implemented by child contracts. /// @notice A resolver callback that should be implemented by child contracts.
/// @param attestation The new attestation. /// @param attestation The new attestation.
/// @param value An explicit ETH amount that was sent to the resolver. Please note that this value is verified in /// @param value An explicit ETH amount that was sent to the resolver. Please note that this value is verified in
/// both attest() and multiAttest() callbacks EAS-only callbacks and that in case of multi attestations, it'll /// both attest() and multiAttest() callbacks EAS-only callbacks and that in case of multi attestations,
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the attestations /// it'll
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the
/// attestations
/// in the batch. /// in the batch.
/// @return Whether the attestation is valid. /// @return Whether the attestation is valid.
function onAttest(Attestation calldata attestation, uint256 value) internal virtual returns (bool); function onAttest(Attestation calldata attestation, uint256 value) internal virtual returns (bool);
...@@ -137,8 +149,10 @@ abstract contract SchemaResolver is ISchemaResolver, Semver { ...@@ -137,8 +149,10 @@ abstract contract SchemaResolver is ISchemaResolver, Semver {
/// @notice Processes an attestation revocation and verifies if it can be revoked. /// @notice Processes an attestation revocation and verifies if it can be revoked.
/// @param attestation The existing attestation to be revoked. /// @param attestation The existing attestation to be revoked.
/// @param value An explicit ETH amount that was sent to the resolver. Please note that this value is verified in /// @param value An explicit ETH amount that was sent to the resolver. Please note that this value is verified in
/// both revoke() and multiRevoke() callbacks EAS-only callbacks and that in case of multi attestations, it'll /// both revoke() and multiRevoke() callbacks EAS-only callbacks and that in case of multi attestations,
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the attestations /// it'll
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the
/// attestations
/// in the batch. /// in the batch.
/// @return Whether the attestation can be revoked. /// @return Whether the attestation can be revoked.
function onRevoke(Attestation calldata attestation, uint256 value) internal virtual returns (bool); function onRevoke(Attestation calldata attestation, uint256 value) internal virtual returns (bool);
......
...@@ -37,12 +37,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, Semver { ...@@ -37,12 +37,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, Semver {
} }
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
function _sendMessage( function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override {
address _to,
uint64 _gasLimit,
uint256 _value,
bytes memory _data
) internal override {
PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data); PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);
} }
......
...@@ -46,7 +46,10 @@ contract L1ERC721Bridge is ERC721Bridge, Semver { ...@@ -46,7 +46,10 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
address _to, address _to,
uint256 _tokenId, uint256 _tokenId,
bytes calldata _extraData bytes calldata _extraData
) external onlyOtherBridge { )
external
onlyOtherBridge
{
require(_localToken != address(this), "L1ERC721Bridge: local token cannot be self"); require(_localToken != address(this), "L1ERC721Bridge: local token cannot be self");
// Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge. // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.
...@@ -76,18 +79,15 @@ contract L1ERC721Bridge is ERC721Bridge, Semver { ...@@ -76,18 +79,15 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
uint256 _tokenId, uint256 _tokenId,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) internal override { )
internal
override
{
require(_remoteToken != address(0), "L1ERC721Bridge: remote token cannot be address(0)"); require(_remoteToken != address(0), "L1ERC721Bridge: remote token cannot be address(0)");
// Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId) // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
L2ERC721Bridge.finalizeBridgeERC721.selector, L2ERC721Bridge.finalizeBridgeERC721.selector, _remoteToken, _localToken, _from, _to, _tokenId, _extraData
_remoteToken,
_localToken,
_from,
_to,
_tokenId,
_extraData
); );
// Lock token into bridge // Lock token into bridge
......
...@@ -23,12 +23,7 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -23,12 +23,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param to Address of the recipient on L2. /// @param to Address of the recipient on L2.
/// @param amount Amount of ETH deposited. /// @param amount Amount of ETH deposited.
/// @param extraData Extra data attached to the deposit. /// @param extraData Extra data attached to the deposit.
event ETHDepositInitiated( event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
/// @custom:legacy /// @custom:legacy
/// @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized. /// @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.
...@@ -36,12 +31,7 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -36,12 +31,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param to Address of the recipient on L1. /// @param to Address of the recipient on L1.
/// @param amount Amount of ETH withdrawn. /// @param amount Amount of ETH withdrawn.
/// @param extraData Extra data attached to the withdrawal. /// @param extraData Extra data attached to the withdrawal.
event ETHWithdrawalFinalized( event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
/// @custom:legacy /// @custom:legacy
/// @notice Emitted whenever an ERC20 deposit is initiated. /// @notice Emitted whenever an ERC20 deposit is initiated.
...@@ -79,10 +69,7 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -79,10 +69,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @custom:semver 1.2.0 /// @custom:semver 1.2.0
/// @notice Constructs the L1StandardBridge contract. /// @notice Constructs the L1StandardBridge contract.
constructor() constructor() Semver(1, 2, 0) StandardBridge(StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE))) {
Semver(1, 2, 0)
StandardBridge(StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)))
{
initialize({ _messenger: CrossDomainMessenger(address(0)) }); initialize({ _messenger: CrossDomainMessenger(address(0)) });
} }
...@@ -130,11 +117,7 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -130,11 +117,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param _extraData Optional data to forward to L2. /// @param _extraData Optional data to forward to L2.
/// Data supplied here will not be used to execute any code on L2 and is /// Data supplied here will not be used to execute any code on L2 and is
/// only emitted as extra data for the convenience of off-chain tooling. /// only emitted as extra data for the convenience of off-chain tooling.
function depositETHTo( function depositETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) external payable {
address _to,
uint32 _minGasLimit,
bytes calldata _extraData
) external payable {
_initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData); _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);
} }
...@@ -153,16 +136,12 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -153,16 +136,12 @@ contract L1StandardBridge is StandardBridge, Semver {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) external virtual onlyEOA { )
_initiateERC20Deposit( external
_l1Token, virtual
_l2Token, onlyEOA
msg.sender, {
msg.sender, _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
_amount,
_minGasLimit,
_extraData
);
} }
/// @custom:legacy /// @custom:legacy
...@@ -182,16 +161,11 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -182,16 +161,11 @@ contract L1StandardBridge is StandardBridge, Semver {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) external virtual { )
_initiateERC20Deposit( external
_l1Token, virtual
_l2Token, {
msg.sender, _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);
_to,
_amount,
_minGasLimit,
_extraData
);
} }
/// @custom:legacy /// @custom:legacy
...@@ -205,7 +179,10 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -205,7 +179,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes calldata _extraData bytes calldata _extraData
) external payable { )
external
payable
{
finalizeBridgeETH(_from, _to, _amount, _extraData); finalizeBridgeETH(_from, _to, _amount, _extraData);
} }
...@@ -224,7 +201,9 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -224,7 +201,9 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes calldata _extraData bytes calldata _extraData
) external { )
external
{
finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData); finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);
} }
...@@ -240,12 +219,7 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -240,12 +219,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param _to Address of the recipient on L2. /// @param _to Address of the recipient on L2.
/// @param _minGasLimit Minimum gas limit for the deposit message on L2. /// @param _minGasLimit Minimum gas limit for the deposit message on L2.
/// @param _extraData Optional data to forward to L2. /// @param _extraData Optional data to forward to L2.
function _initiateETHDeposit( function _initiateETHDeposit(address _from, address _to, uint32 _minGasLimit, bytes memory _extraData) internal {
address _from,
address _to,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
_initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData); _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);
} }
...@@ -265,7 +239,9 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -265,7 +239,9 @@ contract L1StandardBridge is StandardBridge, Semver {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes memory _extraData bytes memory _extraData
) internal { )
internal
{
_initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData); _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);
} }
...@@ -277,7 +253,10 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -277,7 +253,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
internal
override
{
emit ETHDepositInitiated(_from, _to, _amount, _extraData); emit ETHDepositInitiated(_from, _to, _amount, _extraData);
super._emitETHBridgeInitiated(_from, _to, _amount, _extraData); super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);
} }
...@@ -290,7 +269,10 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -290,7 +269,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
internal
override
{
emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData); emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);
super._emitETHBridgeFinalized(_from, _to, _amount, _extraData); super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);
} }
...@@ -305,7 +287,10 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -305,7 +287,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
internal
override
{
emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData); emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData); super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
} }
...@@ -320,7 +305,10 @@ contract L1StandardBridge is StandardBridge, Semver { ...@@ -320,7 +305,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
internal
override
{
emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData); emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData); super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
} }
......
...@@ -54,10 +54,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -54,10 +54,7 @@ contract L2OutputOracle is Initializable, Semver {
/// @param l2BlockNumber The L2 block number of the output root. /// @param l2BlockNumber The L2 block number of the output root.
/// @param l1Timestamp The L1 timestamp when proposed. /// @param l1Timestamp The L1 timestamp when proposed.
event OutputProposed( event OutputProposed(
bytes32 indexed outputRoot, bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp
uint256 indexed l2OutputIndex,
uint256 indexed l2BlockNumber,
uint256 l1Timestamp
); );
/// @notice Emitted when outputs are deleted. /// @notice Emitted when outputs are deleted.
...@@ -75,23 +72,17 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -75,23 +72,17 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _submissionInterval, uint256 _submissionInterval,
uint256 _l2BlockTime, uint256 _l2BlockTime,
uint256 _finalizationPeriodSeconds uint256 _finalizationPeriodSeconds
) Semver(1, 4, 0) { )
Semver(1, 4, 0)
{
require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0"); require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0");
require( require(_submissionInterval > 0, "L2OutputOracle: submission interval must be greater than 0");
_submissionInterval > 0,
"L2OutputOracle: submission interval must be greater than 0"
);
SUBMISSION_INTERVAL = _submissionInterval; SUBMISSION_INTERVAL = _submissionInterval;
L2_BLOCK_TIME = _l2BlockTime; L2_BLOCK_TIME = _l2BlockTime;
FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds; FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
initialize({ initialize({ _startingBlockNumber: 0, _startingTimestamp: 0, _proposer: address(0), _challenger: address(0) });
_startingBlockNumber: 0,
_startingTimestamp: 0,
_proposer: address(0),
_challenger: address(0)
});
} }
/// @notice Initializer. /// @notice Initializer.
...@@ -104,7 +95,10 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -104,7 +95,10 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _startingTimestamp, uint256 _startingTimestamp,
address _proposer, address _proposer,
address _challenger address _challenger
) public reinitializer(2) { )
public
reinitializer(2)
{
require( require(
_startingTimestamp <= block.timestamp, _startingTimestamp <= block.timestamp,
"L2OutputOracle: starting L2 timestamp must be less than current time" "L2OutputOracle: starting L2 timestamp must be less than current time"
...@@ -151,15 +145,11 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -151,15 +145,11 @@ contract L2OutputOracle is Initializable, Semver {
/// All outputs after this output will also be deleted. /// All outputs after this output will also be deleted.
// solhint-disable-next-line ordering // solhint-disable-next-line ordering
function deleteL2Outputs(uint256 _l2OutputIndex) external { function deleteL2Outputs(uint256 _l2OutputIndex) external {
require( require(msg.sender == challenger, "L2OutputOracle: only the challenger address can delete outputs");
msg.sender == challenger,
"L2OutputOracle: only the challenger address can delete outputs"
);
// Make sure we're not *increasing* the length of the array. // Make sure we're not *increasing* the length of the array.
require( require(
_l2OutputIndex < l2Outputs.length, _l2OutputIndex < l2Outputs.length, "L2OutputOracle: cannot delete outputs after the latest output index"
"L2OutputOracle: cannot delete outputs after the latest output index"
); );
// Do not allow deleting any outputs that have already been finalized. // Do not allow deleting any outputs that have already been finalized.
...@@ -190,11 +180,11 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -190,11 +180,11 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _l2BlockNumber, uint256 _l2BlockNumber,
bytes32 _l1BlockHash, bytes32 _l1BlockHash,
uint256 _l1BlockNumber uint256 _l1BlockNumber
) external payable { )
require( external
msg.sender == proposer, payable
"L2OutputOracle: only the proposer address can propose new outputs" {
); require(msg.sender == proposer, "L2OutputOracle: only the proposer address can propose new outputs");
require( require(
_l2BlockNumber == nextBlockNumber(), _l2BlockNumber == nextBlockNumber(),
...@@ -206,10 +196,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -206,10 +196,7 @@ contract L2OutputOracle is Initializable, Semver {
"L2OutputOracle: cannot propose L2 output in the future" "L2OutputOracle: cannot propose L2 output in the future"
); );
require( require(_outputRoot != bytes32(0), "L2OutputOracle: L2 output proposal cannot be the zero hash");
_outputRoot != bytes32(0),
"L2OutputOracle: L2 output proposal cannot be the zero hash"
);
if (_l1BlockHash != bytes32(0)) { if (_l1BlockHash != bytes32(0)) {
// This check allows the proposer to propose an output based on a given L1 block, // This check allows the proposer to propose an output based on a given L1 block,
...@@ -240,11 +227,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -240,11 +227,7 @@ contract L2OutputOracle is Initializable, Semver {
/// @notice Returns an output by index. Needed to return a struct instead of a tuple. /// @notice Returns an output by index. Needed to return a struct instead of a tuple.
/// @param _l2OutputIndex Index of the output to return. /// @param _l2OutputIndex Index of the output to return.
/// @return The output at the given index. /// @return The output at the given index.
function getL2Output(uint256 _l2OutputIndex) function getL2Output(uint256 _l2OutputIndex) external view returns (Types.OutputProposal memory) {
external
view
returns (Types.OutputProposal memory)
{
return l2Outputs[_l2OutputIndex]; return l2Outputs[_l2OutputIndex];
} }
...@@ -261,10 +244,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -261,10 +244,7 @@ contract L2OutputOracle is Initializable, Semver {
); );
// Make sure there's at least one output proposed. // Make sure there's at least one output proposed.
require( require(l2Outputs.length > 0, "L2OutputOracle: cannot get output as no outputs have been proposed yet");
l2Outputs.length > 0,
"L2OutputOracle: cannot get output as no outputs have been proposed yet"
);
// Find the output via binary search, guaranteed to exist. // Find the output via binary search, guaranteed to exist.
uint256 lo = 0; uint256 lo = 0;
...@@ -286,11 +266,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -286,11 +266,7 @@ contract L2OutputOracle is Initializable, Semver {
/// block. /// block.
/// @param _l2BlockNumber L2 block number to find a checkpoint for. /// @param _l2BlockNumber L2 block number to find a checkpoint for.
/// @return First checkpoint that commits to the given L2 block number. /// @return First checkpoint that commits to the given L2 block number.
function getL2OutputAfter(uint256 _l2BlockNumber) function getL2OutputAfter(uint256 _l2BlockNumber) external view returns (Types.OutputProposal memory) {
external
view
returns (Types.OutputProposal memory)
{
return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)]; return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];
} }
...@@ -312,10 +288,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -312,10 +288,7 @@ contract L2OutputOracle is Initializable, Semver {
/// block number. /// block number.
/// @return Latest submitted L2 block number. /// @return Latest submitted L2 block number.
function latestBlockNumber() public view returns (uint256) { function latestBlockNumber() public view returns (uint256) {
return return l2Outputs.length == 0 ? startingBlockNumber : l2Outputs[l2Outputs.length - 1].l2BlockNumber;
l2Outputs.length == 0
? startingBlockNumber
: l2Outputs[l2Outputs.length - 1].l2BlockNumber;
} }
/// @notice Computes the block number of the next L2 block that needs to be checkpointed. /// @notice Computes the block number of the next L2 block that needs to be checkpointed.
......
...@@ -70,22 +70,13 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -70,22 +70,13 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
/// @param to Address that the deposit transaction is directed to. /// @param to Address that the deposit transaction is directed to.
/// @param version Version of this deposit transaction event. /// @param version Version of this deposit transaction event.
/// @param opaqueData ABI encoded deposit data to be parsed off-chain. /// @param opaqueData ABI encoded deposit data to be parsed off-chain.
event TransactionDeposited( event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
address indexed from,
address indexed to,
uint256 indexed version,
bytes opaqueData
);
/// @notice Emitted when a withdrawal transaction is proven. /// @notice Emitted when a withdrawal transaction is proven.
/// @param withdrawalHash Hash of the withdrawal transaction. /// @param withdrawalHash Hash of the withdrawal transaction.
/// @param from Address that triggered the withdrawal transaction. /// @param from Address that triggered the withdrawal transaction.
/// @param to Address that the withdrawal transaction is directed to. /// @param to Address that the withdrawal transaction is directed to.
event WithdrawalProven( event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to);
bytes32 indexed withdrawalHash,
address indexed from,
address indexed to
);
/// @notice Emitted when a withdrawal transaction is finalized. /// @notice Emitted when a withdrawal transaction is finalized.
/// @param withdrawalHash Hash of the withdrawal transaction. /// @param withdrawalHash Hash of the withdrawal transaction.
...@@ -127,7 +118,10 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -127,7 +118,10 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
address _guardian, address _guardian,
SystemConfig _systemConfig, SystemConfig _systemConfig,
bool _paused bool _paused
) public reinitializer(2) { )
public
reinitializer(2)
{
l2Sender = Constants.DEFAULT_L2_SENDER; l2Sender = Constants.DEFAULT_L2_SENDER;
l2Oracle = _l2Oracle; l2Oracle = _l2Oracle;
systemConfig = _systemConfig; systemConfig = _systemConfig;
...@@ -199,12 +193,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -199,12 +193,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
/// Used internally by the ResourceMetering contract. /// Used internally by the ResourceMetering contract.
/// The SystemConfig is the source of truth for the resource config. /// The SystemConfig is the source of truth for the resource config.
/// @return ResourceMetering ResourceConfig /// @return ResourceMetering ResourceConfig
function _resourceConfig() function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory) {
internal
view
override
returns (ResourceMetering.ResourceConfig memory)
{
return systemConfig.resourceConfig(); return systemConfig.resourceConfig();
} }
...@@ -218,14 +207,14 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -218,14 +207,14 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
uint256 _l2OutputIndex, uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof, Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof bytes[] calldata _withdrawalProof
) external whenNotPaused { )
external
whenNotPaused
{
// Prevent users from creating a deposit transaction where this address is the message // Prevent users from creating a deposit transaction where this address is the message
// sender on L2. Because this is checked here, we do not need to check again in // sender on L2. Because this is checked here, we do not need to check again in
// `finalizeWithdrawalTransaction`. // `finalizeWithdrawalTransaction`.
require( require(_tx.target != address(this), "OptimismPortal: you cannot send messages to the portal contract");
_tx.target != address(this),
"OptimismPortal: you cannot send messages to the portal contract"
);
// Get the output root and load onto the stack to prevent multiple mloads. This will // Get the output root and load onto the stack to prevent multiple mloads. This will
// revert if there is no output root for the given block number. // revert if there is no output root for the given block number.
...@@ -233,8 +222,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -233,8 +222,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// Verify that the output root can be generated with the elements in the proof. // Verify that the output root can be generated with the elements in the proof.
require( require(
outputRoot == Hashing.hashOutputRootProof(_outputRootProof), outputRoot == Hashing.hashOutputRootProof(_outputRootProof), "OptimismPortal: invalid output root proof"
"OptimismPortal: invalid output root proof"
); );
// Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier. // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.
...@@ -248,9 +236,8 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -248,9 +236,8 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// to re-prove their withdrawal only in the case that the output root for their specified // to re-prove their withdrawal only in the case that the output root for their specified
// output index has been updated. // output index has been updated.
require( require(
provenWithdrawal.timestamp == 0 || provenWithdrawal.timestamp == 0
l2Oracle.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot != || l2Oracle.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot != provenWithdrawal.outputRoot,
provenWithdrawal.outputRoot,
"OptimismPortal: withdrawal hash has already been proven" "OptimismPortal: withdrawal hash has already been proven"
); );
...@@ -270,10 +257,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -270,10 +257,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// be relayed on L1. // be relayed on L1.
require( require(
SecureMerkleTrie.verifyInclusionProof( SecureMerkleTrie.verifyInclusionProof(
abi.encode(storageKey), abi.encode(storageKey), hex"01", _withdrawalProof, _outputRootProof.messagePasserStorageRoot
hex"01",
_withdrawalProof,
_outputRootProof.messagePasserStorageRoot
), ),
"OptimismPortal: invalid withdrawal inclusion proof" "OptimismPortal: invalid withdrawal inclusion proof"
); );
...@@ -293,16 +277,12 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -293,16 +277,12 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
/// @notice Finalizes a withdrawal transaction. /// @notice Finalizes a withdrawal transaction.
/// @param _tx Withdrawal transaction to finalize. /// @param _tx Withdrawal transaction to finalize.
function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external whenNotPaused {
external
whenNotPaused
{
// Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other
// than the default value when a withdrawal transaction is being finalized. This check is // than the default value when a withdrawal transaction is being finalized. This check is
// a defacto reentrancy guard. // a defacto reentrancy guard.
require( require(
l2Sender == Constants.DEFAULT_L2_SENDER, l2Sender == Constants.DEFAULT_L2_SENDER, "OptimismPortal: can only trigger one withdrawal per transaction"
"OptimismPortal: can only trigger one withdrawal per transaction"
); );
// Grab the proven withdrawal from the `provenWithdrawals` map. // Grab the proven withdrawal from the `provenWithdrawals` map.
...@@ -312,10 +292,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -312,10 +292,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// A withdrawal can only be finalized if it has been proven. We know that a withdrawal has // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has
// been proven at least once when its timestamp is non-zero. Unproven withdrawals will have // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have
// a timestamp of zero. // a timestamp of zero.
require( require(provenWithdrawal.timestamp != 0, "OptimismPortal: withdrawal has not been proven yet");
provenWithdrawal.timestamp != 0,
"OptimismPortal: withdrawal has not been proven yet"
);
// As a sanity check, we make sure that the proven withdrawal's timestamp is greater than // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than
// starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of
...@@ -353,10 +330,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -353,10 +330,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
); );
// Check that this withdrawal has not already been finalized, this is replay protection. // Check that this withdrawal has not already been finalized, this is replay protection.
require( require(finalizedWithdrawals[withdrawalHash] == false, "OptimismPortal: withdrawal has already been finalized");
finalizedWithdrawals[withdrawalHash] == false,
"OptimismPortal: withdrawal has already been finalized"
);
// Mark the withdrawal as finalized so it can't be replayed. // Mark the withdrawal as finalized so it can't be replayed.
finalizedWithdrawals[withdrawalHash] = true; finalizedWithdrawals[withdrawalHash] = true;
...@@ -403,22 +377,20 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -403,22 +377,20 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
uint64 _gasLimit, uint64 _gasLimit,
bool _isCreation, bool _isCreation,
bytes memory _data bytes memory _data
) public payable metered(_gasLimit) { )
public
payable
metered(_gasLimit)
{
// Just to be safe, make sure that people specify address(0) as the target when doing // Just to be safe, make sure that people specify address(0) as the target when doing
// contract creations. // contract creations.
if (_isCreation) { if (_isCreation) {
require( require(_to == address(0), "OptimismPortal: must send to address(0) when creating a contract");
_to == address(0),
"OptimismPortal: must send to address(0) when creating a contract"
);
} }
// Prevent depositing transactions that have too small of a gas limit. Users should pay // Prevent depositing transactions that have too small of a gas limit. Users should pay
// more for more resource usage. // more for more resource usage.
require( require(_gasLimit >= minimumGasLimit(uint64(_data.length)), "OptimismPortal: gas limit too small");
_gasLimit >= minimumGasLimit(uint64(_data.length)),
"OptimismPortal: gas limit too small"
);
// Prevent the creation of deposit transactions that have too much calldata. This gives an // Prevent the creation of deposit transactions that have too much calldata. This gives an
// upper limit on the size of unsafe blocks over the p2p network. 120kb is chosen to ensure // upper limit on the size of unsafe blocks over the p2p network. 120kb is chosen to ensure
...@@ -435,13 +407,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -435,13 +407,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// Compute the opaque data that will be emitted as part of the TransactionDeposited event. // Compute the opaque data that will be emitted as part of the TransactionDeposited event.
// We use opaque data so that we can update the TransactionDeposited event in the future // We use opaque data so that we can update the TransactionDeposited event in the future
// without breaking the current interface. // without breaking the current interface.
bytes memory opaqueData = abi.encodePacked( bytes memory opaqueData = abi.encodePacked(msg.value, _value, _gasLimit, _isCreation, _data);
msg.value,
_value,
_gasLimit,
_isCreation,
_data
);
// Emit a TransactionDeposited event so that the rollup node can derive a deposit // Emit a TransactionDeposited event so that the rollup node can derive a deposit
// transaction for this deposit. // transaction for this deposit.
......
...@@ -76,16 +76,16 @@ abstract contract ResourceMetering is Initializable { ...@@ -76,16 +76,16 @@ abstract contract ResourceMetering is Initializable {
uint256 blockDiff = block.number - params.prevBlockNum; uint256 blockDiff = block.number - params.prevBlockNum;
ResourceConfig memory config = _resourceConfig(); ResourceConfig memory config = _resourceConfig();
int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) / int256 targetResourceLimit =
int256(uint256(config.elasticityMultiplier)); int256(uint256(config.maxResourceLimit)) / int256(uint256(config.elasticityMultiplier));
if (blockDiff > 0) { if (blockDiff > 0) {
// Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate
// at which deposits can be created and therefore limit the potential for deposits to // at which deposits can be created and therefore limit the potential for deposits to
// spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes. // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.
int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit; int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;
int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) / int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta)
(targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator))); / (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));
// Update base fee by adding the base fee delta and clamp the resulting value between // Update base fee by adding the base fee delta and clamp the resulting value between
// min and max. // min and max.
...@@ -155,10 +155,6 @@ abstract contract ResourceMetering is Initializable { ...@@ -155,10 +155,6 @@ abstract contract ResourceMetering is Initializable {
/// child contract. /// child contract.
// solhint-disable-next-line func-name-mixedcase // solhint-disable-next-line func-name-mixedcase
function __ResourceMetering_init() internal onlyInitializing { function __ResourceMetering_init() internal onlyInitializing {
params = ResourceParams({ params = ResourceParams({ prevBaseFee: 1 gwei, prevBoughtGas: 0, prevBlockNum: uint64(block.number) });
prevBaseFee: 1 gwei,
prevBoughtGas: 0,
prevBlockNum: uint64(block.number)
});
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Semver } from "../universal/Semver.sol"; import { Semver } from "../universal/Semver.sol";
import { ResourceMetering } from "./ResourceMetering.sol"; import { ResourceMetering } from "./ResourceMetering.sol";
...@@ -54,28 +52,23 @@ contract SystemConfig is OwnableUpgradeable, Semver { ...@@ -54,28 +52,23 @@ contract SystemConfig is OwnableUpgradeable, Semver {
bytes32(uint256(keccak256("systemconfig.l1crossdomainmessenger")) - 1); bytes32(uint256(keccak256("systemconfig.l1crossdomainmessenger")) - 1);
/// @notice Storage slot that the L1ERC721Bridge address is stored at. /// @notice Storage slot that the L1ERC721Bridge address is stored at.
bytes32 public constant L1_ERC_721_BRIDGE_SLOT = bytes32 public constant L1_ERC_721_BRIDGE_SLOT = bytes32(uint256(keccak256("systemconfig.l1erc721bridge")) - 1);
bytes32(uint256(keccak256("systemconfig.l1erc721bridge")) - 1);
/// @notice Storage slot that the L1StandardBridge address is stored at. /// @notice Storage slot that the L1StandardBridge address is stored at.
bytes32 public constant L1_STANDARD_BRIDGE_SLOT = bytes32 public constant L1_STANDARD_BRIDGE_SLOT = bytes32(uint256(keccak256("systemconfig.l1standardbridge")) - 1);
bytes32(uint256(keccak256("systemconfig.l1standardbridge")) - 1);
/// @notice Storage slot that the L2OutputOracle address is stored at. /// @notice Storage slot that the L2OutputOracle address is stored at.
bytes32 public constant L2_OUTPUT_ORACLE_SLOT = bytes32 public constant L2_OUTPUT_ORACLE_SLOT = bytes32(uint256(keccak256("systemconfig.l2outputoracle")) - 1);
bytes32(uint256(keccak256("systemconfig.l2outputoracle")) - 1);
/// @notice Storage slot that the OptimismPortal address is stored at. /// @notice Storage slot that the OptimismPortal address is stored at.
bytes32 public constant OPTIMISM_PORTAL_SLOT = bytes32 public constant OPTIMISM_PORTAL_SLOT = bytes32(uint256(keccak256("systemconfig.optimismportal")) - 1);
bytes32(uint256(keccak256("systemconfig.optimismportal")) - 1);
/// @notice Storage slot that the OptimismMintableERC20Factory address is stored at. /// @notice Storage slot that the OptimismMintableERC20Factory address is stored at.
bytes32 public constant OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT = bytes32 public constant OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT =
bytes32(uint256(keccak256("systemconfig.optimismmintableerc20factory")) - 1); bytes32(uint256(keccak256("systemconfig.optimismmintableerc20factory")) - 1);
/// @notice Storage slot that the batch inbox address is stored at. /// @notice Storage slot that the batch inbox address is stored at.
bytes32 public constant BATCH_INBOX_SLOT = bytes32 public constant BATCH_INBOX_SLOT = bytes32(uint256(keccak256("systemconfig.batchinbox")) - 1);
bytes32(uint256(keccak256("systemconfig.batchinbox")) - 1);
/// @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation. /// @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.
uint256 public overhead; uint256 public overhead;
...@@ -165,7 +158,10 @@ contract SystemConfig is OwnableUpgradeable, Semver { ...@@ -165,7 +158,10 @@ contract SystemConfig is OwnableUpgradeable, Semver {
uint256 _startBlock, uint256 _startBlock,
address _batchInbox, address _batchInbox,
SystemConfig.Addresses memory _addresses SystemConfig.Addresses memory _addresses
) public reinitializer(2) { )
public
reinitializer(2)
{
__Ownable_init(); __Ownable_init();
transferOwnership(_owner); transferOwnership(_owner);
...@@ -346,29 +342,19 @@ contract SystemConfig is OwnableUpgradeable, Semver { ...@@ -346,29 +342,19 @@ contract SystemConfig is OwnableUpgradeable, Semver {
function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal { function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {
// Min base fee must be less than or equal to max base fee. // Min base fee must be less than or equal to max base fee.
require( require(
_config.minimumBaseFee <= _config.maximumBaseFee, _config.minimumBaseFee <= _config.maximumBaseFee, "SystemConfig: min base fee must be less than max base"
"SystemConfig: min base fee must be less than max base"
); );
// Base fee change denominator must be greater than 1. // Base fee change denominator must be greater than 1.
require( require(_config.baseFeeMaxChangeDenominator > 1, "SystemConfig: denominator must be larger than 1");
_config.baseFeeMaxChangeDenominator > 1,
"SystemConfig: denominator must be larger than 1"
);
// Max resource limit plus system tx gas must be less than or equal to the L2 gas limit. // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.
// The gas limit must be increased before these values can be increased. // The gas limit must be increased before these values can be increased.
require( require(_config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit, "SystemConfig: gas limit too low");
_config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,
"SystemConfig: gas limit too low"
);
// Elasticity multiplier must be greater than 0. // Elasticity multiplier must be greater than 0.
require( require(_config.elasticityMultiplier > 0, "SystemConfig: elasticity multiplier cannot be 0");
_config.elasticityMultiplier > 0,
"SystemConfig: elasticity multiplier cannot be 0"
);
// No precision loss when computing target resource limit. // No precision loss when computing target resource limit.
require( require(
((_config.maxResourceLimit / _config.elasticityMultiplier) * ((_config.maxResourceLimit / _config.elasticityMultiplier) * _config.elasticityMultiplier)
_config.elasticityMultiplier) == _config.maxResourceLimit, == _config.maxResourceLimit,
"SystemConfig: precision loss with target resource limit" "SystemConfig: precision loss with target resource limit"
); );
......
...@@ -18,5 +18,8 @@ contract BaseFeeVault is FeeVault, Semver { ...@@ -18,5 +18,8 @@ contract BaseFeeVault is FeeVault, Semver {
address _recipient, address _recipient,
uint256 _minWithdrawalAmount, uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork WithdrawalNetwork _withdrawalNetwork
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 3, 0) {} )
FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
Semver(1, 3, 0)
{ }
} }
...@@ -14,8 +14,7 @@ abstract contract CrossDomainOwnable is Ownable { ...@@ -14,8 +14,7 @@ abstract contract CrossDomainOwnable is Ownable {
/// `msg.sender` is the owner of the contract. /// `msg.sender` is the owner of the contract.
function _checkOwner() internal view override { function _checkOwner() internal view override {
require( require(
owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender), owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender), "CrossDomainOwnable: caller is not the owner"
"CrossDomainOwnable: caller is not the owner"
); );
} }
} }
...@@ -15,18 +15,10 @@ abstract contract CrossDomainOwnable2 is Ownable { ...@@ -15,18 +15,10 @@ abstract contract CrossDomainOwnable2 is Ownable {
/// `xDomainMessageSender` is the owner of the contract. This value is set to the caller /// `xDomainMessageSender` is the owner of the contract. This value is set to the caller
/// of the L1CrossDomainMessenger. /// of the L1CrossDomainMessenger.
function _checkOwner() internal view override { function _checkOwner() internal view override {
L2CrossDomainMessenger messenger = L2CrossDomainMessenger( L2CrossDomainMessenger messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
Predeploys.L2_CROSS_DOMAIN_MESSENGER
);
require( require(msg.sender == address(messenger), "CrossDomainOwnable2: caller is not the messenger");
msg.sender == address(messenger),
"CrossDomainOwnable2: caller is not the messenger"
);
require( require(owner() == messenger.xDomainMessageSender(), "CrossDomainOwnable2: caller is not the owner");
owner() == messenger.xDomainMessageSender(),
"CrossDomainOwnable2: caller is not the owner"
);
} }
} }
...@@ -20,11 +20,7 @@ abstract contract CrossDomainOwnable3 is Ownable { ...@@ -20,11 +20,7 @@ abstract contract CrossDomainOwnable3 is Ownable {
/// @param previousOwner The previous owner of the contract. /// @param previousOwner The previous owner of the contract.
/// @param newOwner The new owner of the contract. /// @param newOwner The new owner of the contract.
/// @param isLocal Configures the `isLocal` contract variable. /// @param isLocal Configures the `isLocal` contract variable.
event OwnershipTransferred( event OwnershipTransferred(address indexed previousOwner, address indexed newOwner, bool isLocal);
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
/// @notice Allows for ownership to be transferred with specifying the locality. /// @notice Allows for ownership to be transferred with specifying the locality.
/// @param _owner The new owner of the contract. /// @param _owner The new owner of the contract.
...@@ -46,19 +42,11 @@ abstract contract CrossDomainOwnable3 is Ownable { ...@@ -46,19 +42,11 @@ abstract contract CrossDomainOwnable3 is Ownable {
if (isLocal) { if (isLocal) {
require(owner() == msg.sender, "CrossDomainOwnable3: caller is not the owner"); require(owner() == msg.sender, "CrossDomainOwnable3: caller is not the owner");
} else { } else {
L2CrossDomainMessenger messenger = L2CrossDomainMessenger( L2CrossDomainMessenger messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
Predeploys.L2_CROSS_DOMAIN_MESSENGER
);
require( require(msg.sender == address(messenger), "CrossDomainOwnable3: caller is not the messenger");
msg.sender == address(messenger),
"CrossDomainOwnable3: caller is not the messenger"
);
require( require(owner() == messenger.xDomainMessageSender(), "CrossDomainOwnable3: caller is not the owner");
owner() == messenger.xDomainMessageSender(),
"CrossDomainOwnable3: caller is not the owner"
);
} }
} }
} }
...@@ -25,7 +25,7 @@ contract GasPriceOracle is Semver { ...@@ -25,7 +25,7 @@ contract GasPriceOracle is Semver {
/// @custom:semver 1.0.1 /// @custom:semver 1.0.1
/// @notice Constructs the GasPriceOracle contract. /// @notice Constructs the GasPriceOracle contract.
constructor() Semver(1, 0, 1) {} constructor() Semver(1, 0, 1) { }
/// @notice Computes the L1 portion of the fee based on the size of the rlp encoded input /// @notice Computes the L1 portion of the fee based on the size of the rlp encoded input
/// transaction, the current L1 base fee, and the various dynamic parameters. /// transaction, the current L1 base fee, and the various dynamic parameters.
...@@ -34,7 +34,7 @@ contract GasPriceOracle is Semver { ...@@ -34,7 +34,7 @@ contract GasPriceOracle is Semver {
function getL1Fee(bytes memory _data) external view returns (uint256) { function getL1Fee(bytes memory _data) external view returns (uint256) {
uint256 l1GasUsed = getL1GasUsed(_data); uint256 l1GasUsed = getL1GasUsed(_data);
uint256 l1Fee = l1GasUsed * l1BaseFee(); uint256 l1Fee = l1GasUsed * l1BaseFee();
uint256 divisor = 10**DECIMALS; uint256 divisor = 10 ** DECIMALS;
uint256 unscaled = l1Fee * scalar(); uint256 unscaled = l1Fee * scalar();
uint256 scaled = unscaled / divisor; uint256 scaled = unscaled / divisor;
return scaled; return scaled;
......
...@@ -40,7 +40,7 @@ contract L1Block is Semver { ...@@ -40,7 +40,7 @@ contract L1Block is Semver {
/// @custom:semver 1.0.1 /// @custom:semver 1.0.1
/// @notice Constructs the L1Block contract. /// @notice Constructs the L1Block contract.
constructor() Semver(1, 0, 1) {} constructor() Semver(1, 0, 1) { }
/// @notice Updates the L1 block values. /// @notice Updates the L1 block values.
/// @param _number L1 blocknumber. /// @param _number L1 blocknumber.
...@@ -60,11 +60,10 @@ contract L1Block is Semver { ...@@ -60,11 +60,10 @@ contract L1Block is Semver {
bytes32 _batcherHash, bytes32 _batcherHash,
uint256 _l1FeeOverhead, uint256 _l1FeeOverhead,
uint256 _l1FeeScalar uint256 _l1FeeScalar
) external { )
require( external
msg.sender == DEPOSITOR_ACCOUNT, {
"L1Block: only the depositor account can set L1 block values" require(msg.sender == DEPOSITOR_ACCOUNT, "L1Block: only the depositor account can set L1 block values");
);
number = _number; number = _number;
timestamp = _timestamp; timestamp = _timestamp;
......
...@@ -18,5 +18,8 @@ contract L1FeeVault is FeeVault, Semver { ...@@ -18,5 +18,8 @@ contract L1FeeVault is FeeVault, Semver {
address _recipient, address _recipient,
uint256 _minWithdrawalAmount, uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork WithdrawalNetwork _withdrawalNetwork
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 3, 0) {} )
FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
Semver(1, 3, 0)
{ }
} }
...@@ -17,10 +17,7 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, Semver { ...@@ -17,10 +17,7 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, Semver {
/// @custom:semver 1.5.0 /// @custom:semver 1.5.0
/// @notice Constructs the L2CrossDomainMessenger contract. /// @notice Constructs the L2CrossDomainMessenger contract.
/// @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract. /// @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.
constructor(address _l1CrossDomainMessenger) constructor(address _l1CrossDomainMessenger) Semver(1, 5, 0) CrossDomainMessenger(_l1CrossDomainMessenger) {
Semver(1, 5, 0)
CrossDomainMessenger(_l1CrossDomainMessenger)
{
initialize(); initialize();
} }
...@@ -38,15 +35,10 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, Semver { ...@@ -38,15 +35,10 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, Semver {
} }
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
function _sendMessage( function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override {
address _to, L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: _value }(
uint64 _gasLimit, _to, _gasLimit, _data
uint256 _value, );
bytes memory _data
) internal override {
L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{
value: _value
}(_to, _gasLimit, _data);
} }
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
......
...@@ -48,7 +48,10 @@ contract L2ERC721Bridge is ERC721Bridge, Semver { ...@@ -48,7 +48,10 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
address _to, address _to,
uint256 _tokenId, uint256 _tokenId,
bytes calldata _extraData bytes calldata _extraData
) external onlyOtherBridge { )
external
onlyOtherBridge
{
require(_localToken != address(this), "L2ERC721Bridge: local token cannot be self"); require(_localToken != address(this), "L2ERC721Bridge: local token cannot be self");
// Note that supportsInterface makes a callback to the _localToken address which is user // Note that supportsInterface makes a callback to the _localToken address which is user
...@@ -80,7 +83,10 @@ contract L2ERC721Bridge is ERC721Bridge, Semver { ...@@ -80,7 +83,10 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
uint256 _tokenId, uint256 _tokenId,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) internal override { )
internal
override
{
require(_remoteToken != address(0), "L2ERC721Bridge: remote token cannot be address(0)"); require(_remoteToken != address(0), "L2ERC721Bridge: remote token cannot be address(0)");
// Check that the withdrawal is being initiated by the NFT owner // Check that the withdrawal is being initiated by the NFT owner
...@@ -92,10 +98,7 @@ contract L2ERC721Bridge is ERC721Bridge, Semver { ...@@ -92,10 +98,7 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
// Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId) // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)
// slither-disable-next-line reentrancy-events // slither-disable-next-line reentrancy-events
address remoteToken = IOptimismMintableERC721(_localToken).remoteToken(); address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();
require( require(remoteToken == _remoteToken, "L2ERC721Bridge: remote token does not match given value");
remoteToken == _remoteToken,
"L2ERC721Bridge: remote token does not match given value"
);
// When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2 // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2
// usage // usage
...@@ -103,13 +106,7 @@ contract L2ERC721Bridge is ERC721Bridge, Semver { ...@@ -103,13 +106,7 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
IOptimismMintableERC721(_localToken).burn(_from, _tokenId); IOptimismMintableERC721(_localToken).burn(_from, _tokenId);
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
L1ERC721Bridge.finalizeBridgeERC721.selector, L1ERC721Bridge.finalizeBridgeERC721.selector, remoteToken, _localToken, _from, _to, _tokenId, _extraData
remoteToken,
_localToken,
_from,
_to,
_tokenId,
_extraData
); );
// Send message to L1 bridge // Send message to L1 bridge
......
...@@ -60,20 +60,13 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -60,20 +60,13 @@ contract L2StandardBridge is StandardBridge, Semver {
/// @notice Initializer /// @notice Initializer
function initialize() public reinitializer(2) { function initialize() public reinitializer(2) {
__StandardBridge_init({ __StandardBridge_init({ _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) });
_messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)
});
} }
/// @notice Allows EOAs to bridge ETH by sending directly to the bridge. /// @notice Allows EOAs to bridge ETH by sending directly to the bridge.
receive() external payable override onlyEOA { receive() external payable override onlyEOA {
_initiateWithdrawal( _initiateWithdrawal(
Predeploys.LEGACY_ERC20_ETH, Predeploys.LEGACY_ERC20_ETH, msg.sender, msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, bytes("")
msg.sender,
msg.sender,
msg.value,
RECEIVE_DEFAULT_GAS_LIMIT,
bytes("")
); );
} }
...@@ -90,7 +83,12 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -90,7 +83,12 @@ contract L2StandardBridge is StandardBridge, Semver {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) external payable virtual onlyEOA { )
external
payable
virtual
onlyEOA
{
_initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData); _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
} }
...@@ -113,7 +111,11 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -113,7 +111,11 @@ contract L2StandardBridge is StandardBridge, Semver {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) external payable virtual { )
external
payable
virtual
{
_initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData); _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);
} }
...@@ -133,7 +135,11 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -133,7 +135,11 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes calldata _extraData bytes calldata _extraData
) external payable virtual { )
external
payable
virtual
{
if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) { if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {
finalizeBridgeETH(_from, _to, _amount, _extraData); finalizeBridgeETH(_from, _to, _amount, _extraData);
} else { } else {
...@@ -163,7 +169,9 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -163,7 +169,9 @@ contract L2StandardBridge is StandardBridge, Semver {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes memory _extraData bytes memory _extraData
) internal { )
internal
{
if (_l2Token == Predeploys.LEGACY_ERC20_ETH) { if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {
_initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData); _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);
} else { } else {
...@@ -180,15 +188,11 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -180,15 +188,11 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
emit WithdrawalInitiated( internal
address(0), override
Predeploys.LEGACY_ERC20_ETH, {
_from, emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, _from, _to, _amount, _extraData);
_to,
_amount,
_extraData
);
super._emitETHBridgeInitiated(_from, _to, _amount, _extraData); super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);
} }
...@@ -200,15 +204,11 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -200,15 +204,11 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
emit DepositFinalized( internal
address(0), override
Predeploys.LEGACY_ERC20_ETH, {
_from, emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, _from, _to, _amount, _extraData);
_to,
_amount,
_extraData
);
super._emitETHBridgeFinalized(_from, _to, _amount, _extraData); super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);
} }
...@@ -222,7 +222,10 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -222,7 +222,10 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
internal
override
{
emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData); emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData); super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
} }
...@@ -237,7 +240,10 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -237,7 +240,10 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal override { )
internal
override
{
emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData); emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData); super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
} }
......
...@@ -50,7 +50,7 @@ contract L2ToL1MessagePasser is Semver { ...@@ -50,7 +50,7 @@ contract L2ToL1MessagePasser is Semver {
/// @custom:semver 1.0.1 /// @custom:semver 1.0.1
/// @notice Constructs the L2ToL1MessagePasser contract. /// @notice Constructs the L2ToL1MessagePasser contract.
constructor() Semver(1, 0, 1) {} constructor() Semver(1, 0, 1) { }
/// @notice Allows users to withdraw ETH by sending directly to this contract. /// @notice Allows users to withdraw ETH by sending directly to this contract.
receive() external payable { receive() external payable {
...@@ -71,11 +71,7 @@ contract L2ToL1MessagePasser is Semver { ...@@ -71,11 +71,7 @@ contract L2ToL1MessagePasser is Semver {
/// @param _target Address to call on L1 execution. /// @param _target Address to call on L1 execution.
/// @param _gasLimit Minimum gas limit for executing the message on L1. /// @param _gasLimit Minimum gas limit for executing the message on L1.
/// @param _data Data to forward to L1 target. /// @param _data Data to forward to L1 target.
function initiateWithdrawal( function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) public payable {
address _target,
uint256 _gasLimit,
bytes memory _data
) public payable {
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
nonce: messageNonce(), nonce: messageNonce(),
...@@ -89,15 +85,7 @@ contract L2ToL1MessagePasser is Semver { ...@@ -89,15 +85,7 @@ contract L2ToL1MessagePasser is Semver {
sentMessages[withdrawalHash] = true; sentMessages[withdrawalHash] = true;
emit MessagePassed( emit MessagePassed(messageNonce(), msg.sender, _target, msg.value, _gasLimit, _data, withdrawalHash);
messageNonce(),
msg.sender,
_target,
msg.value,
_gasLimit,
_data,
withdrawalHash
);
unchecked { unchecked {
++msgNonce; ++msgNonce;
......
...@@ -19,7 +19,10 @@ contract SequencerFeeVault is FeeVault, Semver { ...@@ -19,7 +19,10 @@ contract SequencerFeeVault is FeeVault, Semver {
address _recipient, address _recipient,
uint256 _minWithdrawalAmount, uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork WithdrawalNetwork _withdrawalNetwork
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 3, 0) {} )
FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
Semver(1, 3, 0)
{ }
/// @custom:legacy /// @custom:legacy
/// @notice Legacy getter for the recipient address. /// @notice Legacy getter for the recipient address.
......
...@@ -20,7 +20,6 @@ import { PreimageKeyLib } from "./PreimageKeyLib.sol"; ...@@ -20,7 +20,6 @@ import { PreimageKeyLib } from "./PreimageKeyLib.sol";
/// @dev https://github.com/golang/go/blob/master/src/syscall/zerrors_linux_mips.go /// @dev https://github.com/golang/go/blob/master/src/syscall/zerrors_linux_mips.go
/// MIPS linux kernel errors used by Go runtime /// MIPS linux kernel errors used by Go runtime
contract MIPS { contract MIPS {
/// @notice Stores the VM state. /// @notice Stores the VM state.
/// Total state size: 32 + 32 + 6 * 4 + 1 + 1 + 8 + 32 * 4 = 226 bytes /// Total state size: 32 + 32 + 6 * 4 + 1 + 1 + 8 + 32 * 4 = 226 bytes
/// If nextPC != pc + 4, then the VM is executing a branch/jump delay slot. /// If nextPC != pc + 4, then the VM is executing a branch/jump delay slot.
...@@ -40,7 +39,7 @@ contract MIPS { ...@@ -40,7 +39,7 @@ contract MIPS {
} }
/// @notice Start of the data segment. /// @notice Start of the data segment.
uint32 constant public BRK_START = 0x40000000; uint32 public constant BRK_START = 0x40000000;
uint32 constant FD_STDIN = 0; uint32 constant FD_STDIN = 0;
uint32 constant FD_STDOUT = 1; uint32 constant FD_STDOUT = 1;
...@@ -90,23 +89,21 @@ contract MIPS { ...@@ -90,23 +89,21 @@ contract MIPS {
let to := start let to := start
// Copy state to free memory // Copy state to free memory
from, to := copyMem(from, to, 32) // memRoot from, to := copyMem(from, to, 32) // memRoot
from, to := copyMem(from, to, 32) // preimageKey from, to := copyMem(from, to, 32) // preimageKey
from, to := copyMem(from, to, 4) // preimageOffset from, to := copyMem(from, to, 4) // preimageOffset
from, to := copyMem(from, to, 4) // pc from, to := copyMem(from, to, 4) // pc
from, to := copyMem(from, to, 4) // nextPC from, to := copyMem(from, to, 4) // nextPC
from, to := copyMem(from, to, 4) // lo from, to := copyMem(from, to, 4) // lo
from, to := copyMem(from, to, 4) // hi from, to := copyMem(from, to, 4) // hi
from, to := copyMem(from, to, 4) // heap from, to := copyMem(from, to, 4) // heap
from, to := copyMem(from, to, 1) // exitCode from, to := copyMem(from, to, 1) // exitCode
from, to := copyMem(from, to, 1) // exited from, to := copyMem(from, to, 1) // exited
from, to := copyMem(from, to, 8) // step from, to := copyMem(from, to, 8) // step
from := add(from, 32) // offset to registers from := add(from, 32) // offset to registers
// Copy registers // Copy registers
for { let i := 0 } lt(i, 32) { i := add(i, 1) } { for { let i := 0 } lt(i, 32) { i := add(i, 1) } { from, to := copyMem(from, to, 4) }
from, to := copyMem(from, to, 4)
}
// Clean up end of memory // Clean up end of memory
mstore(to, 0) mstore(to, 0)
...@@ -141,8 +138,9 @@ contract MIPS { ...@@ -141,8 +138,9 @@ contract MIPS {
// mmap: Allocates a page from the heap. // mmap: Allocates a page from the heap.
if (syscall_no == 4090) { if (syscall_no == 4090) {
uint32 sz = a1; uint32 sz = a1;
if (sz&4095 != 0) { // adjust size to align with page size if (sz & 4095 != 0) {
sz += 4096 - (sz&4095); // adjust size to align with page size
sz += 4096 - (sz & 4095);
} }
if (a0 == 0) { if (a0 == 0) {
v0 = state.heap; v0 = state.heap;
...@@ -191,9 +189,11 @@ contract MIPS { ...@@ -191,9 +189,11 @@ contract MIPS {
if lt(space, datLen) { datLen := space } // if less space than data, shorten data if lt(space, datLen) { datLen := space } // if less space than data, shorten data
if lt(a2, datLen) { datLen := a2 } // if requested to read less, read less if lt(a2, datLen) { datLen := a2 } // if requested to read less, read less
dat := shr(sub(256, mul(datLen, 8)), dat) // right-align data dat := shr(sub(256, mul(datLen, 8)), dat) // right-align data
dat := shl(mul(sub(sub(4, datLen), alignment), 8), dat) // position data to insert into memory word dat := shl(mul(sub(sub(4, datLen), alignment), 8), dat) // position data to insert into memory
// word
let mask := sub(shl(mul(sub(4, alignment), 8), 1), 1) // mask all bytes after start let mask := sub(shl(mul(sub(4, alignment), 8), 1), 1) // mask all bytes after start
let suffixMask := sub(shl(mul(sub(sub(4, alignment), datLen), 8), 1), 1) // mask of all bytes starting from end, maybe none let suffixMask := sub(shl(mul(sub(sub(4, alignment), datLen), 8), 1), 1) // mask of all bytes
// starting from end, maybe none
mask := and(mask, not(suffixMask)) // reduce mask to just cover the data we insert mask := and(mask, not(suffixMask)) // reduce mask to just cover the data we insert
mem := or(and(mem, not(mask)), dat) // clear masked part of original memory, and insert data mem := or(and(mem, not(mask)), dat) // clear masked part of original memory, and insert data
} }
...@@ -208,8 +208,7 @@ contract MIPS { ...@@ -208,8 +208,7 @@ contract MIPS {
// Don't read into memory, just say we read it all // Don't read into memory, just say we read it all
// The result is ignored anyway // The result is ignored anyway
v0 = a2; v0 = a2;
} } else {
else {
v0 = 0xFFffFFff; v0 = 0xFFffFFff;
v1 = EBADF; v1 = EBADF;
} }
...@@ -242,17 +241,18 @@ contract MIPS { ...@@ -242,17 +241,18 @@ contract MIPS {
state.preimageKey = key; state.preimageKey = key;
state.preimageOffset = 0; // reset offset, to read new pre-image data from the start state.preimageOffset = 0; // reset offset, to read new pre-image data from the start
v0 = a2; v0 = a2;
} } else {
else {
v0 = 0xFFffFFff; v0 = 0xFFffFFff;
v1 = EBADF; v1 = EBADF;
} }
} }
// fcntl: Like linux fcntl syscall, but only supports minimal file-descriptor control commands, // fcntl: Like linux fcntl syscall, but only supports minimal file-descriptor control commands,
// to retrieve the file-descriptor R/W flags. // to retrieve the file-descriptor R/W flags.
else if (syscall_no == 4055) { // fcntl else if (syscall_no == 4055) {
// fcntl
// args: a0 = fd, a1 = cmd // args: a0 = fd, a1 = cmd
if (a1 == 3) { // F_GETFL: get file descriptor flags if (a1 == 3) {
// F_GETFL: get file descriptor flags
if (a0 == FD_STDIN || a0 == FD_PREIMAGE_READ || a0 == FD_HINT_READ) { if (a0 == FD_STDIN || a0 == FD_PREIMAGE_READ || a0 == FD_HINT_READ) {
v0 = 0; // O_RDONLY v0 = 0; // O_RDONLY
} else if (a0 == FD_STDOUT || a0 == FD_STDERR || a0 == FD_PREIMAGE_WRITE || a0 == FD_HINT_WRITE) { } else if (a0 == FD_STDOUT || a0 == FD_STDERR || a0 == FD_PREIMAGE_WRITE || a0 == FD_HINT_WRITE) {
...@@ -295,7 +295,7 @@ contract MIPS { ...@@ -295,7 +295,7 @@ contract MIPS {
bool shouldBranch = false; bool shouldBranch = false;
if (state.nextPC != state.pc+4) { if (state.nextPC != state.pc + 4) {
revert("branch in delay slot"); revert("branch in delay slot");
} }
...@@ -428,7 +428,7 @@ contract MIPS { ...@@ -428,7 +428,7 @@ contract MIPS {
state := 0x80 state := 0x80
} }
if (state.nextPC != state.pc+4) { if (state.nextPC != state.pc + 4) {
revert("jump in delay slot"); revert("jump in delay slot");
} }
...@@ -486,7 +486,9 @@ contract MIPS { ...@@ -486,7 +486,9 @@ contract MIPS {
// And the leaf value itself needs to be encoded as well. And proof.offset == 388 // And the leaf value itself needs to be encoded as well. And proof.offset == 388
offset_ = 388 + (uint256(_proofIndex) * (28 * 32)); offset_ = 388 + (uint256(_proofIndex) * (28 * 32));
uint256 s = 0; uint256 s = 0;
assembly { s := calldatasize() } assembly {
s := calldatasize()
}
require(s >= (offset_ + 28 * 32), "check that there is enough calldata"); require(s >= (offset_ + 28 * 32), "check that there is enough calldata");
return offset_; return offset_;
} }
...@@ -503,9 +505,7 @@ contract MIPS { ...@@ -503,9 +505,7 @@ contract MIPS {
assembly { assembly {
// Validate the address alignement. // Validate the address alignement.
if and(_addr, 3) { if and(_addr, 3) { revert(0, 0) }
revert(0, 0)
}
// Load the leaf value. // Load the leaf value.
let leaf := calldataload(offset) let leaf := calldataload(offset)
...@@ -526,11 +526,8 @@ contract MIPS { ...@@ -526,11 +526,8 @@ contract MIPS {
let sibling := calldataload(offset) let sibling := calldataload(offset)
offset := add(offset, 32) offset := add(offset, 32)
switch and(shr(i, path), 1) switch and(shr(i, path), 1)
case 0 { case 0 { node := hashPair(node, sibling) }
node := hashPair(node, sibling) case 1 { node := hashPair(sibling, node) }
} case 1 {
node := hashPair(sibling, node)
}
} }
// Load the memory root from the first field of state. // Load the memory root from the first field of state.
...@@ -562,9 +559,7 @@ contract MIPS { ...@@ -562,9 +559,7 @@ contract MIPS {
assembly { assembly {
// Validate the address alignement. // Validate the address alignement.
if and(_addr, 3) { if and(_addr, 3) { revert(0, 0) }
revert(0, 0)
}
// Load the leaf value. // Load the leaf value.
let leaf := calldataload(offset) let leaf := calldataload(offset)
...@@ -589,11 +584,8 @@ contract MIPS { ...@@ -589,11 +584,8 @@ contract MIPS {
let sibling := calldataload(offset) let sibling := calldataload(offset)
offset := add(offset, 32) offset := add(offset, 32)
switch and(shr(i, path), 1) switch and(shr(i, path), 1)
case 0 { case 0 { node := hashPair(node, sibling) }
node := hashPair(node, sibling) case 1 { node := hashPair(sibling, node) }
} case 1 {
node := hashPair(sibling, node)
}
} }
// Store the new memory root in the first field of state. // Store the new memory root in the first field of state.
...@@ -610,17 +602,21 @@ contract MIPS { ...@@ -610,17 +602,21 @@ contract MIPS {
// Packed calldata is ~6 times smaller than state size // Packed calldata is ~6 times smaller than state size
assembly { assembly {
if iszero(eq(state, 0x80)) { // expected state mem offset check if iszero(eq(state, 0x80)) {
revert(0,0) // expected state mem offset check
revert(0, 0)
} }
if iszero(eq(mload(0x40), mul(32, 48))) { // expected memory check if iszero(eq(mload(0x40), mul(32, 48))) {
revert(0,0) // expected memory check
revert(0, 0)
} }
if iszero(eq(stateData.offset, 100)) { // 32*3+4=100 expected state data offset if iszero(eq(stateData.offset, 100)) {
revert(0,0) // 32*3+4=100 expected state data offset
revert(0, 0)
} }
if iszero(eq(proof.offset, 388)) { // 100+32+256=388 expected proof offset if iszero(eq(proof.offset, 388)) {
revert(0,0) // 100+32+256=388 expected proof offset
revert(0, 0)
} }
function putField(callOffset, memOffset, size) -> callOffsetOut, memOffsetOut { function putField(callOffset, memOffset, size) -> callOffsetOut, memOffsetOut {
...@@ -632,26 +628,24 @@ contract MIPS { ...@@ -632,26 +628,24 @@ contract MIPS {
} }
// Unpack state from calldata into memory // Unpack state from calldata into memory
let c := stateData.offset // calldata offset let c := stateData.offset // calldata offset
let m := 0x80 // mem offset let m := 0x80 // mem offset
c, m := putField(c, m, 32) // memRoot c, m := putField(c, m, 32) // memRoot
c, m := putField(c, m, 32) // preimageKey c, m := putField(c, m, 32) // preimageKey
c, m := putField(c, m, 4) // preimageOffset c, m := putField(c, m, 4) // preimageOffset
c, m := putField(c, m, 4) // pc c, m := putField(c, m, 4) // pc
c, m := putField(c, m, 4) // nextPC c, m := putField(c, m, 4) // nextPC
c, m := putField(c, m, 4) // lo c, m := putField(c, m, 4) // lo
c, m := putField(c, m, 4) // hi c, m := putField(c, m, 4) // hi
c, m := putField(c, m, 4) // heap c, m := putField(c, m, 4) // heap
c, m := putField(c, m, 1) // exitCode c, m := putField(c, m, 1) // exitCode
c, m := putField(c, m, 1) // exited c, m := putField(c, m, 1) // exited
c, m := putField(c, m, 8) // step c, m := putField(c, m, 8) // step
// Unpack register calldata into memory // Unpack register calldata into memory
mstore(m, add(m, 32)) // offset to registers mstore(m, add(m, 32)) // offset to registers
m := add(m, 32) m := add(m, 32)
for { let i := 0 } lt(i, 32) { i := add(i, 1) } { for { let i := 0 } lt(i, 32) { i := add(i, 1) } { c, m := putField(c, m, 4) }
c, m := putField(c, m, 4)
}
} }
// Don't change state once exited // Don't change state once exited
...@@ -713,7 +707,7 @@ contract MIPS { ...@@ -713,7 +707,7 @@ contract MIPS {
uint32 mem; uint32 mem;
if (opcode >= 0x20) { if (opcode >= 0x20) {
// M[R[rs]+SignExtImm] // M[R[rs]+SignExtImm]
rs += SE(insn&0xFFFF, 16); rs += SE(insn & 0xFFFF, 16);
uint32 addr = rs & 0xFFFFFFFC; uint32 addr = rs & 0xFFFFFFFC;
mem = readMem(addr, 1); mem = readMem(addr, 1);
if (opcode >= 0x28 && opcode != 0x30) { if (opcode >= 0x28 && opcode != 0x30) {
...@@ -729,14 +723,17 @@ contract MIPS { ...@@ -729,14 +723,17 @@ contract MIPS {
uint32 func = insn & 0x3f; // 6-bits uint32 func = insn & 0x3f; // 6-bits
if (opcode == 0 && func >= 8 && func < 0x1c) { if (opcode == 0 && func >= 8 && func < 0x1c) {
if (func == 8 || func == 9) { // jr/jalr if (func == 8 || func == 9) {
// jr/jalr
return handleJump(func == 8 ? 0 : rdReg, rs); return handleJump(func == 8 ? 0 : rdReg, rs);
} }
if (func == 0xa) { // movz if (func == 0xa) {
// movz
return handleRd(rdReg, rs, rt == 0); return handleRd(rdReg, rs, rt == 0);
} }
if (func == 0xb) { // movn if (func == 0xb) {
// movn
return handleRd(rdReg, rs, rt != 0); return handleRd(rdReg, rs, rt != 0);
} }
...@@ -770,7 +767,7 @@ contract MIPS { ...@@ -770,7 +767,7 @@ contract MIPS {
/// @notice Execute an instruction. /// @notice Execute an instruction.
function execute(uint32 insn, uint32 rs, uint32 rt, uint32 mem) internal pure returns (uint32) { function execute(uint32 insn, uint32 rs, uint32 rt, uint32 mem) internal pure returns (uint32) {
unchecked { unchecked {
uint32 opcode = insn >> 26; // 6-bits uint32 opcode = insn >> 26; // 6-bits
uint32 func = insn & 0x3f; // 6-bits uint32 func = insn & 0x3f; // 6-bits
// TODO(CLI-4136): deref the immed into a register // TODO(CLI-4136): deref the immed into a register
...@@ -778,13 +775,19 @@ contract MIPS { ...@@ -778,13 +775,19 @@ contract MIPS {
// transform ArithLogI // transform ArithLogI
// TODO(CLI-4136): replace with table // TODO(CLI-4136): replace with table
if (opcode >= 8 && opcode < 0xF) { if (opcode >= 8 && opcode < 0xF) {
if (opcode == 8) { func = 0x20; } // addi if (opcode == 8) func = 0x20; // addi
else if (opcode == 9) { func = 0x21; } // addiu
else if (opcode == 0xa) { func = 0x2a; } // slti else if (opcode == 9) func = 0x21; // addiu
else if (opcode == 0xb) { func = 0x2B; } // sltiu
else if (opcode == 0xc) { func = 0x24; } // andi else if (opcode == 0xa) func = 0x2a; // slti
else if (opcode == 0xd) { func = 0x25; } // ori
else if (opcode == 0xe) { func = 0x26; } // xori else if (opcode == 0xb) func = 0x2B; // sltiu
else if (opcode == 0xc) func = 0x24; // andi
else if (opcode == 0xd) func = 0x25; // ori
else if (opcode == 0xe) func = 0x26; // xori
opcode = 0; opcode = 0;
} }
...@@ -854,7 +857,7 @@ contract MIPS { ...@@ -854,7 +857,7 @@ contract MIPS {
} }
// sltu: Set to 1 if less than unsigned // sltu: Set to 1 if less than unsigned
else if (func == 0x2B) { else if (func == 0x2B) {
return rs<rt ? 1 : 0; return rs < rt ? 1 : 0;
} }
} }
// lui: Load Upper Immediate // lui: Load Upper Immediate
...@@ -873,15 +876,14 @@ contract MIPS { ...@@ -873,15 +876,14 @@ contract MIPS {
rs = ~rs; rs = ~rs;
} }
uint32 i = 0; uint32 i = 0;
while (rs&0x80000000 != 0) { while (rs & 0x80000000 != 0) {
i++; i++;
rs <<= 1; rs <<= 1;
} }
return i; return i;
} }
} }
} } else if (opcode < 0x28) {
else if (opcode < 0x28) {
// lb // lb
if (opcode == 0x20) { if (opcode == 0x20) {
return SE((mem >> (24 - (rs & 3) * 8)) & 0xFF, 8); return SE((mem >> (24 - (rs & 3) * 8)) & 0xFF, 8);
......
...@@ -16,11 +16,7 @@ contract PreimageOracle is IPreimageOracle { ...@@ -16,11 +16,7 @@ contract PreimageOracle is IPreimageOracle {
mapping(bytes32 => mapping(uint256 => bool)) public preimagePartOk; mapping(bytes32 => mapping(uint256 => bool)) public preimagePartOk;
/// @inheritdoc IPreimageOracle /// @inheritdoc IPreimageOracle
function readPreimage(bytes32 _key, uint256 _offset) function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_) {
external
view
returns (bytes32 dat_, uint256 datLen_)
{
require(preimagePartOk[_key][_offset], "pre-image must exist"); require(preimagePartOk[_key][_offset], "pre-image must exist");
// Calculate the length of the pre-image data // Calculate the length of the pre-image data
...@@ -40,12 +36,7 @@ contract PreimageOracle is IPreimageOracle { ...@@ -40,12 +36,7 @@ contract PreimageOracle is IPreimageOracle {
/// and restrict local pre-image insertion to the dispute-managing contract. /// and restrict local pre-image insertion to the dispute-managing contract.
/// For now we permit anyone to write any pre-image unchecked, to make testing easy. /// For now we permit anyone to write any pre-image unchecked, to make testing easy.
/// This method is DANGEROUS. And NOT FOR PRODUCTION. /// This method is DANGEROUS. And NOT FOR PRODUCTION.
function cheat( function cheat(uint256 partOffset, bytes32 key, bytes32 part, uint256 size) external {
uint256 partOffset,
bytes32 key,
bytes32 part,
uint256 size
) external {
preimagePartOk[key][partOffset] = true; preimagePartOk[key][partOffset] = true;
preimageParts[key][partOffset] = part; preimageParts[key][partOffset] = part;
preimageLengths[key] = size; preimageLengths[key] = size;
...@@ -57,7 +48,10 @@ contract PreimageOracle is IPreimageOracle { ...@@ -57,7 +48,10 @@ contract PreimageOracle is IPreimageOracle {
bytes32 _word, bytes32 _word,
uint256 _size, uint256 _size,
uint256 _partOffset uint256 _partOffset
) external returns (bytes32 key_) { )
external
returns (bytes32 key_)
{
// Compute the localized key from the given local identifier. // Compute the localized key from the given local identifier.
key_ = PreimageKeyLib.localizeIdent(_ident); key_ = PreimageKeyLib.localizeIdent(_ident);
......
...@@ -9,10 +9,7 @@ interface IPreimageOracle { ...@@ -9,10 +9,7 @@ interface IPreimageOracle {
/// @param _offset The offset of the preimage to read. /// @param _offset The offset of the preimage to read.
/// @return dat_ The preimage data. /// @return dat_ The preimage data.
/// @return datLen_ The length of the preimage data. /// @return datLen_ The length of the preimage data.
function readPreimage(bytes32 _key, uint256 _offset) function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_);
external
view
returns (bytes32 dat_, uint256 datLen_);
/// @notice Loads of local data part into the preimage oracle. /// @notice Loads of local data part into the preimage oracle.
/// @param _ident The identifier of the local data. /// @param _ident The identifier of the local data.
...@@ -38,7 +35,9 @@ interface IPreimageOracle { ...@@ -38,7 +35,9 @@ interface IPreimageOracle {
bytes32 _word, bytes32 _word,
uint256 _size, uint256 _size,
uint256 _partOffset uint256 _partOffset
) external returns (bytes32 key_); )
external
returns (bytes32 key_);
/// @notice Prepares a preimage to be read by keccak256 key, starting at /// @notice Prepares a preimage to be read by keccak256 key, starting at
/// the given offset and up to 32 bytes (clipped at preimage length, if out of data). /// the given offset and up to 32 bytes (clipped at preimage length, if out of data).
......
...@@ -14,11 +14,7 @@ contract BlockOracle { ...@@ -14,11 +14,7 @@ contract BlockOracle {
} }
/// @notice Emitted when a block is checkpointed. /// @notice Emitted when a block is checkpointed.
event Checkpoint( event Checkpoint(uint256 indexed blockNumber, Hash indexed blockHash, Timestamp indexed childTimestamp);
uint256 indexed blockNumber,
Hash indexed blockHash,
Timestamp indexed childTimestamp
);
/// @notice Maps block numbers to block hashes and timestamps /// @notice Maps block numbers to block hashes and timestamps
mapping(uint256 => BlockInfo) internal blocks; mapping(uint256 => BlockInfo) internal blocks;
......
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol"; import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol";
import { import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Semver } from "src/universal/Semver.sol"; import { Semver } from "src/universal/Semver.sol";
import { IDisputeGame } from "./interfaces/IDisputeGame.sol"; import { IDisputeGame } from "./interfaces/IDisputeGame.sol";
...@@ -58,7 +56,11 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver { ...@@ -58,7 +56,11 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
GameType _gameType, GameType _gameType,
Claim _rootClaim, Claim _rootClaim,
bytes calldata _extraData bytes calldata _extraData
) external view returns (IDisputeGame proxy_, uint256 timestamp_) { )
external
view
returns (IDisputeGame proxy_, uint256 timestamp_)
{
Hash uuid = getGameUUID(_gameType, _rootClaim, _extraData); Hash uuid = getGameUUID(_gameType, _rootClaim, _extraData);
GameId slot = _disputeGames[uuid]; GameId slot = _disputeGames[uuid];
(address addr, uint256 timestamp) = _unpackSlot(slot); (address addr, uint256 timestamp) = _unpackSlot(slot);
...@@ -67,11 +69,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver { ...@@ -67,11 +69,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
} }
/// @inheritdoc IDisputeGameFactory /// @inheritdoc IDisputeGameFactory
function gameAtIndex(uint256 _index) function gameAtIndex(uint256 _index) external view returns (IDisputeGame proxy_, uint256 timestamp_) {
external
view
returns (IDisputeGame proxy_, uint256 timestamp_)
{
GameId slot = _disputeGameList[_index]; GameId slot = _disputeGameList[_index];
(address addr, uint256 timestamp) = _unpackSlot(slot); (address addr, uint256 timestamp) = _unpackSlot(slot);
proxy_ = IDisputeGame(addr); proxy_ = IDisputeGame(addr);
...@@ -83,7 +81,10 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver { ...@@ -83,7 +81,10 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
GameType gameType, GameType gameType,
Claim rootClaim, Claim rootClaim,
bytes calldata extraData bytes calldata extraData
) external returns (IDisputeGame proxy) { )
external
returns (IDisputeGame proxy)
{
// Grab the implementation contract for the given `GameType`. // Grab the implementation contract for the given `GameType`.
IDisputeGame impl = gameImpls[gameType]; IDisputeGame impl = gameImpls[gameType];
...@@ -109,11 +110,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver { ...@@ -109,11 +110,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
} }
/// @inheritdoc IDisputeGameFactory /// @inheritdoc IDisputeGameFactory
function getGameUUID( function getGameUUID(GameType gameType, Claim rootClaim, bytes memory extraData) public pure returns (Hash _uuid) {
GameType gameType,
Claim rootClaim,
bytes memory extraData
) public pure returns (Hash _uuid) {
assembly { assembly {
// Grab the offsets of the other memory locations we will need to temporarily overwrite. // Grab the offsets of the other memory locations we will need to temporarily overwrite.
let gameTypeOffset := sub(extraData, 0x60) let gameTypeOffset := sub(extraData, 0x60)
......
...@@ -94,7 +94,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -94,7 +94,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
IBigStepper _vm, IBigStepper _vm,
L2OutputOracle _l2oo, L2OutputOracle _l2oo,
BlockOracle _blockOracle BlockOracle _blockOracle
) Semver(0, 0, 7) { )
Semver(0, 0, 7)
{
GAME_TYPE = _gameType; GAME_TYPE = _gameType;
ABSOLUTE_PRESTATE = _absolutePrestate; ABSOLUTE_PRESTATE = _absolutePrestate;
MAX_GAME_DEPTH = _maxGameDepth; MAX_GAME_DEPTH = _maxGameDepth;
...@@ -109,12 +111,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -109,12 +111,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// @inheritdoc IFaultDisputeGame /// @inheritdoc IFaultDisputeGame
function step( function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external {
uint256 _claimIndex,
bool _isAttack,
bytes calldata _stateData,
bytes calldata _proof
) external {
// INVARIANT: Steps cannot be made unless the game is currently in progress. // INVARIANT: Steps cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
...@@ -139,10 +136,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -139,10 +136,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// the game state. // the game state.
preStateClaim = stepPos.indexAtDepth() == 0 preStateClaim = stepPos.indexAtDepth() == 0
? ABSOLUTE_PRESTATE ? ABSOLUTE_PRESTATE
: findTraceAncestor( : findTraceAncestor(Position.wrap(Position.unwrap(parentPos) - 1), parent.parentIndex).claim;
Position.wrap(Position.unwrap(parentPos) - 1),
parent.parentIndex
).claim;
// For all attacks, the poststate is the parent claim. // For all attacks, the poststate is the parent claim.
postState = parent; postState = parent;
...@@ -150,10 +144,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -150,10 +144,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// If the step is a defense, the poststate exists elsewhere in the game state, // If the step is a defense, the poststate exists elsewhere in the game state,
// and the parent claim is the expected pre-state. // and the parent claim is the expected pre-state.
preStateClaim = parent.claim; preStateClaim = parent.claim;
postState = findTraceAncestor( postState = findTraceAncestor(Position.wrap(Position.unwrap(parentPos) + 1), parent.parentIndex);
Position.wrap(Position.unwrap(parentPos) + 1),
parent.parentIndex
);
} }
// INVARIANT: The prestate is always invalid if the passed `_stateData` is not the // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the
...@@ -185,11 +176,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -185,11 +176,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @param _challengeIndex The index of the claim being moved against. /// @param _challengeIndex The index of the claim being moved against.
/// @param _claim The claim at the next logical position in the game. /// @param _claim The claim at the next logical position in the game.
/// @param _isAttack Whether or not the move is an attack or defense. /// @param _isAttack Whether or not the move is an attack or defense.
function move( function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable {
uint256 _challengeIndex,
Claim _claim,
bool _isAttack
) public payable {
// INVARIANT: Moves cannot be made unless the game is currently in progress. // INVARIANT: Moves cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
...@@ -225,11 +212,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -225,11 +212,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
Duration nextDuration = Duration.wrap( Duration nextDuration = Duration.wrap(
uint64( uint64(
// First, fetch the duration of the grandparent claim. // First, fetch the duration of the grandparent claim.
Duration.unwrap(grandparentClock.duration()) + Duration.unwrap(grandparentClock.duration())
// Second, add the difference between the current block timestamp and the // Second, add the difference between the current block timestamp and the
// parent's clock timestamp. // parent's clock timestamp.
block.timestamp - + block.timestamp - Timestamp.unwrap(parent.clock.timestamp())
Timestamp.unwrap(parent.clock.timestamp())
) )
); );
...@@ -362,7 +348,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -362,7 +348,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// The most recent claim is always a dangling, non-bottom node so we start with that // The most recent claim is always a dangling, non-bottom node so we start with that
uint256 leftMostIndex = claimData.length - 1; uint256 leftMostIndex = claimData.length - 1;
uint256 leftMostTraceIndex = type(uint128).max; uint256 leftMostTraceIndex = type(uint128).max;
for (uint256 i = leftMostIndex; i < type(uint64).max; ) { for (uint256 i = leftMostIndex; i < type(uint64).max;) {
// Fetch the claim at the current index. // Fetch the claim at the current index.
ClaimData storage claim = claimData[i]; ClaimData storage claim = claimData[i];
...@@ -396,13 +382,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -396,13 +382,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// claim, it is uncountered, and we check if 3.5 days has passed since its // claim, it is uncountered, and we check if 3.5 days has passed since its
// creation. // creation.
uint256 parentIndex = leftMostUncontested.parentIndex; uint256 parentIndex = leftMostUncontested.parentIndex;
Clock opposingClock = parentIndex == type(uint32).max Clock opposingClock = parentIndex == type(uint32).max ? leftMostUncontested.clock : claimData[parentIndex].clock;
? leftMostUncontested.clock
: claimData[parentIndex].clock;
if ( if (
Duration.unwrap(opposingClock.duration()) + Duration.unwrap(opposingClock.duration()) + (block.timestamp - Timestamp.unwrap(opposingClock.timestamp()))
(block.timestamp - Timestamp.unwrap(opposingClock.timestamp())) <= <= Duration.unwrap(GAME_DURATION) >> 1
Duration.unwrap(GAME_DURATION) >> 1
) { ) {
revert ClockNotExpired(); revert ClockNotExpired();
} }
...@@ -410,8 +393,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -410,8 +393,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// If the left-most dangling node is at an even depth, the defender wins. // If the left-most dangling node is at an even depth, the defender wins.
// Otherwise, the challenger wins and the root claim is deemed invalid. // Otherwise, the challenger wins and the root claim is deemed invalid.
if ( if (
// slither-disable-next-line weak-prng leftMostUncontested
leftMostUncontested.position.depth() % 2 == 0 && leftMostTraceIndex != type(uint128).max .position
// slither-disable-next-line weak-prng
.depth() % 2 == 0 && leftMostTraceIndex != type(uint128).max
) { ) {
status_ = GameStatus.DEFENDER_WINS; status_ = GameStatus.DEFENDER_WINS;
} else { } else {
...@@ -435,15 +420,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -435,15 +420,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
} }
/// @inheritdoc IDisputeGame /// @inheritdoc IDisputeGame
function gameData() function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_) {
external
view
returns (
GameType gameType_,
Claim rootClaim_,
bytes memory extraData_
)
{
gameType_ = gameType(); gameType_ = gameType();
rootClaim_ = rootClaim(); rootClaim_ = rootClaim();
extraData_ = extraData(); extraData_ = extraData();
...@@ -543,11 +520,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -543,11 +520,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`. /// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`.
// TODO(clabby): Can we form a relationship between the trace path and the position to avoid // TODO(clabby): Can we form a relationship between the trace path and the position to avoid
// looping? // looping?
function findTraceAncestor(Position _pos, uint256 _start) function findTraceAncestor(Position _pos, uint256 _start) internal view returns (ClaimData storage ancestor_) {
internal
view
returns (ClaimData storage ancestor_)
{
// Grab the trace ancestor's expected position. // Grab the trace ancestor's expected position.
Position preStateTraceAncestor = _pos.traceAncestor(); Position preStateTraceAncestor = _pos.traceAncestor();
......
...@@ -30,9 +30,7 @@ interface IBigStepper { ...@@ -30,9 +30,7 @@ interface IBigStepper {
/// @param _stateData The preimage of the prestate hash. /// @param _stateData The preimage of the prestate hash.
/// @param _proof A proof for the inclusion of the prestate's memory in the merkle tree. /// @param _proof A proof for the inclusion of the prestate's memory in the merkle tree.
/// @return postState_ The poststate hash after the instruction step. /// @return postState_ The poststate hash after the instruction step.
function step(bytes calldata _stateData, bytes calldata _proof) function step(bytes calldata _stateData, bytes calldata _proof) external returns (bytes32 postState_);
external
returns (bytes32 postState_);
/// @notice Returns the preimage oracle used by the stepper. /// @notice Returns the preimage oracle used by the stepper.
function oracle() external view returns (IPreimageOracle oracle_); function oracle() external view returns (IPreimageOracle oracle_);
......
...@@ -30,11 +30,7 @@ interface IBondManager { ...@@ -30,11 +30,7 @@ interface IBondManager {
/// @param _bondOwner is the address that owns the bond. /// @param _bondOwner is the address that owns the bond.
/// @param _minClaimHold is the minimum amount of time the owner /// @param _minClaimHold is the minimum amount of time the owner
/// must wait before reclaiming their bond. /// must wait before reclaiming their bond.
function post( function post(bytes32 _bondId, address _bondOwner, uint128 _minClaimHold) external payable;
bytes32 _bondId,
address _bondOwner,
uint128 _minClaimHold
) external payable;
/// @notice Seizes the bond with the given id. /// @notice Seizes the bond with the given id.
/// @dev This function will revert if there is no bond at the given id. /// @dev This function will revert if there is no bond at the given id.
......
...@@ -56,12 +56,5 @@ interface IDisputeGame is IInitializable { ...@@ -56,12 +56,5 @@ interface IDisputeGame is IInitializable {
/// @return gameType_ The type of proof system being used. /// @return gameType_ The type of proof system being used.
/// @return rootClaim_ The root claim of the DisputeGame. /// @return rootClaim_ The root claim of the DisputeGame.
/// @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 gameData() function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_);
external
view
returns (
GameType gameType_,
Claim rootClaim_,
bytes memory extraData_
);
} }
...@@ -12,11 +12,7 @@ interface IDisputeGameFactory { ...@@ -12,11 +12,7 @@ interface IDisputeGameFactory {
/// @param disputeProxy The address of the dispute game proxy /// @param disputeProxy The address of the dispute game proxy
/// @param gameType The type of the dispute game proxy's implementation /// @param gameType The type of the dispute game proxy's implementation
/// @param rootClaim The root claim of the dispute game /// @param rootClaim The root claim of the dispute game
event DisputeGameCreated( event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);
address indexed disputeProxy,
GameType indexed gameType,
Claim indexed rootClaim
);
/// @notice Emitted when a new game implementation added to the factory /// @notice Emitted when a new game implementation added to the factory
/// @param impl The implementation contract for the given `GameType`. /// @param impl The implementation contract for the given `GameType`.
...@@ -40,7 +36,10 @@ interface IDisputeGameFactory { ...@@ -40,7 +36,10 @@ interface IDisputeGameFactory {
GameType gameType, GameType gameType,
Claim rootClaim, Claim rootClaim,
bytes calldata extraData bytes calldata extraData
) external view returns (IDisputeGame _proxy, uint256 _timestamp); )
external
view
returns (IDisputeGame _proxy, uint256 _timestamp);
/// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp /// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp
/// at the given index. Each created dispute game increments the underlying index. /// at the given index. Each created dispute game increments the underlying index.
...@@ -48,10 +47,7 @@ interface IDisputeGameFactory { ...@@ -48,10 +47,7 @@ interface IDisputeGameFactory {
/// @return _proxy The clone of the `DisputeGame` created with the given parameters. /// @return _proxy The clone of the `DisputeGame` created with the given parameters.
/// Returns `address(0)` if nonexistent. /// Returns `address(0)` if nonexistent.
/// @return _timestamp The timestamp of the creation of the dispute game. /// @return _timestamp The timestamp of the creation of the dispute game.
function gameAtIndex(uint256 _index) function gameAtIndex(uint256 _index) external view returns (IDisputeGame _proxy, uint256 _timestamp);
external
view
returns (IDisputeGame _proxy, uint256 _timestamp);
/// @notice `gameImpls` is a mapping that maps `GameType`s to their respective /// @notice `gameImpls` is a mapping that maps `GameType`s to their respective
/// `IDisputeGame` implementations. /// `IDisputeGame` implementations.
...@@ -69,7 +65,9 @@ interface IDisputeGameFactory { ...@@ -69,7 +65,9 @@ interface IDisputeGameFactory {
GameType gameType, GameType gameType,
Claim rootClaim, Claim rootClaim,
bytes calldata extraData bytes calldata extraData
) external returns (IDisputeGame proxy); )
external
returns (IDisputeGame proxy);
/// @notice Sets the implementation contract for a specific `GameType`. /// @notice Sets the implementation contract for a specific `GameType`.
/// @dev May only be called by the `owner`. /// @dev May only be called by the `owner`.
...@@ -88,5 +86,8 @@ interface IDisputeGameFactory { ...@@ -88,5 +86,8 @@ interface IDisputeGameFactory {
GameType gameType, GameType gameType,
Claim rootClaim, Claim rootClaim,
bytes memory extraData bytes memory extraData
) external pure returns (Hash _uuid); )
external
pure
returns (Hash _uuid);
} }
...@@ -66,12 +66,7 @@ interface IFaultDisputeGame is IDisputeGame { ...@@ -66,12 +66,7 @@ interface IFaultDisputeGame is IDisputeGame {
/// the move is a defense. If the step is an attack on the first instruction, it is /// the move is a defense. If the step is an attack on the first instruction, it is
/// the absolute prestate of the fault proof VM. /// the absolute prestate of the fault proof VM.
/// @param _proof Proof to access memory nodes in the VM's merkle state tree. /// @param _proof Proof to access memory nodes in the VM's merkle state tree.
function step( function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external;
uint256 _claimIndex,
bool _isAttack,
bytes calldata _stateData,
bytes calldata _proof
) external;
/// @notice Posts the requested local data to the VM's `PreimageOralce`. /// @notice Posts the requested local data to the VM's `PreimageOralce`.
/// @param _ident The local identifier of the data to post. /// @param _ident The local identifier of the data to post.
......
...@@ -6,7 +6,6 @@ import "src/libraries/DisputeTypes.sol"; ...@@ -6,7 +6,6 @@ import "src/libraries/DisputeTypes.sol";
/// @title Hashing /// @title Hashing
/// @notice This library contains all of the hashing utilities used in the Cannon contracts. /// @notice This library contains all of the hashing utilities used in the Cannon contracts.
library LibHashing { library LibHashing {
/// @notice Hashes a claim and a position together. /// @notice Hashes a claim and a position together.
/// @param _claim A Claim type. /// @param _claim A Claim type.
/// @param _position The position of `claim`. /// @param _position The position of `claim`.
......
...@@ -6,7 +6,6 @@ import "src/libraries/DisputeTypes.sol"; ...@@ -6,7 +6,6 @@ import "src/libraries/DisputeTypes.sol";
/// @title LibPosition /// @title LibPosition
/// @notice This library contains helper functions for working with the `Position` type. /// @notice This library contains helper functions for working with the `Position` type.
library LibPosition { library LibPosition {
/// @notice Computes a generalized index (2^{depth} + indexAtDepth). /// @notice Computes a generalized index (2^{depth} + indexAtDepth).
/// @param _depth The depth of the position. /// @param _depth The depth of the position.
/// @param _indexAtDepth The index at the depth of the position. /// @param _indexAtDepth The index at the depth of the position.
...@@ -36,13 +35,14 @@ library LibPosition { ...@@ -36,13 +35,14 @@ library LibPosition {
_position := or(_position, shr(8, _position)) _position := or(_position, shr(8, _position))
_position := or(_position, shr(16, _position)) _position := or(_position, shr(16, _position))
depth_ := or( depth_ :=
depth_, or(
byte( depth_,
shr(251, mul(_position, shl(224, 0x07c4acdd))), byte(
0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f shr(251, mul(_position, shl(224, 0x07c4acdd))),
0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f
)
) )
)
} }
} }
...@@ -93,10 +93,7 @@ library LibPosition { ...@@ -93,10 +93,7 @@ library LibPosition {
/// @param _position The position to get the relative deepest, right most gindex of. /// @param _position The position to get the relative deepest, right most gindex of.
/// @param _maxDepth The maximum depth of the game. /// @param _maxDepth The maximum depth of the game.
/// @return rightIndex_ The deepest, right most gindex relative to the `position`. /// @return rightIndex_ The deepest, right most gindex relative to the `position`.
function rightIndex( function rightIndex(Position _position, uint256 _maxDepth) internal pure returns (Position rightIndex_) {
Position _position,
uint256 _maxDepth
) internal pure returns (Position rightIndex_) {
uint256 msb = depth(_position); uint256 msb = depth(_position);
assembly { assembly {
let remaining := sub(_maxDepth, msb) let remaining := sub(_maxDepth, msb)
...@@ -110,17 +107,11 @@ library LibPosition { ...@@ -110,17 +107,11 @@ library LibPosition {
/// @param _position The position to get the relative trace index of. /// @param _position The position to get the relative trace index of.
/// @param _maxDepth The maximum depth of the game. /// @param _maxDepth The maximum depth of the game.
/// @return traceIndex_ The trace index relative to the `position`. /// @return traceIndex_ The trace index relative to the `position`.
function traceIndex( function traceIndex(Position _position, uint256 _maxDepth) internal pure returns (uint256 traceIndex_) {
Position _position,
uint256 _maxDepth
) internal pure returns (uint256 traceIndex_) {
uint256 msb = depth(_position); uint256 msb = depth(_position);
assembly { assembly {
let remaining := sub(_maxDepth, msb) let remaining := sub(_maxDepth, msb)
traceIndex_ := sub( traceIndex_ := sub(or(shl(remaining, _position), sub(shl(remaining, 1), 1)), shl(_maxDepth, 1))
or(shl(remaining, _position), sub(shl(remaining, 1), 1)),
shl(_maxDepth, 1)
)
} }
} }
......
...@@ -14,7 +14,7 @@ import "@openzeppelin/contracts/access/Ownable.sol"; ...@@ -14,7 +14,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";
/// inflation schedule. /// inflation schedule.
contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable { contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
/// @notice Constructs the GovernanceToken contract. /// @notice Constructs the GovernanceToken contract.
constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") {} constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") { }
/// @notice Allows the owner to mint tokens. /// @notice Allows the owner to mint tokens.
/// @param _account The account receiving minted tokens. /// @param _account The account receiving minted tokens.
...@@ -27,11 +27,7 @@ contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable { ...@@ -27,11 +27,7 @@ contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
/// @param from The account sending tokens. /// @param from The account sending tokens.
/// @param to The account receiving tokens. /// @param to The account receiving tokens.
/// @param amount The amount of tokens being transfered. /// @param amount The amount of tokens being transfered.
function _afterTokenTransfer( function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) {
address from,
address to,
uint256 amount
) internal override(ERC20, ERC20Votes) {
super._afterTokenTransfer(from, to, amount); super._afterTokenTransfer(from, to, amount);
} }
......
...@@ -41,10 +41,7 @@ contract MintManager is Ownable { ...@@ -41,10 +41,7 @@ contract MintManager is Ownable {
/// @param _amount The amount of tokens to mint. /// @param _amount The amount of tokens to mint.
function mint(address _account, uint256 _amount) public onlyOwner { function mint(address _account, uint256 _amount) public onlyOwner {
if (mintPermittedAfter > 0) { if (mintPermittedAfter > 0) {
require( require(mintPermittedAfter <= block.timestamp, "MintManager: minting not permitted yet");
mintPermittedAfter <= block.timestamp,
"MintManager: minting not permitted yet"
);
require( require(
_amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR, _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,
...@@ -59,10 +56,7 @@ contract MintManager is Ownable { ...@@ -59,10 +56,7 @@ contract MintManager is Ownable {
/// @notice Upgrade the owner of the governance token to a new MintManager. /// @notice Upgrade the owner of the governance token to a new MintManager.
/// @param _newMintManager The MintManager to upgrade to. /// @param _newMintManager The MintManager to upgrade to.
function upgrade(address _newMintManager) public onlyOwner { function upgrade(address _newMintManager) public onlyOwner {
require( require(_newMintManager != address(0), "MintManager: mint manager cannot be the zero address");
_newMintManager != address(0),
"MintManager: mint manager cannot be the zero address"
);
governanceToken.transferOwnership(_newMintManager); governanceToken.transferOwnership(_newMintManager);
} }
......
...@@ -36,15 +36,12 @@ contract DeployerWhitelist is Semver { ...@@ -36,15 +36,12 @@ contract DeployerWhitelist is Semver {
/// @notice Blocks functions to anyone except the contract owner. /// @notice Blocks functions to anyone except the contract owner.
modifier onlyOwner() { modifier onlyOwner() {
require( require(msg.sender == owner, "DeployerWhitelist: function can only be called by the owner of this contract");
msg.sender == owner,
"DeployerWhitelist: function can only be called by the owner of this contract"
);
_; _;
} }
/// @custom:semver 1.0.1 /// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {} constructor() Semver(1, 0, 1) { }
/// @notice Adds or removes an address from the deployment whitelist. /// @notice Adds or removes an address from the deployment whitelist.
/// @param _deployer Address to update permissions for. /// @param _deployer Address to update permissions for.
...@@ -60,10 +57,7 @@ contract DeployerWhitelist is Semver { ...@@ -60,10 +57,7 @@ contract DeployerWhitelist is Semver {
// Prevent users from setting the whitelist owner to address(0) except via // Prevent users from setting the whitelist owner to address(0) except via
// enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to
// any other address that doesn't have a corresponding knowable private key. // any other address that doesn't have a corresponding knowable private key.
require( require(_owner != address(0), "DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment");
_owner != address(0),
"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment"
);
emit OwnerChanged(owner, _owner); emit OwnerChanged(owner, _owner);
owner = _owner; owner = _owner;
......
...@@ -15,7 +15,7 @@ import { Semver } from "../universal/Semver.sol"; ...@@ -15,7 +15,7 @@ import { Semver } from "../universal/Semver.sol";
/// contract instead. /// contract instead.
contract L1BlockNumber is Semver { contract L1BlockNumber is Semver {
/// @custom:semver 1.0.1 /// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {} constructor() Semver(1, 0, 1) { }
/// @notice Returns the L1 block number. /// @notice Returns the L1 block number.
receive() external payable { receive() external payable {
......
...@@ -22,12 +22,10 @@ contract L1ChugSplashProxy { ...@@ -22,12 +22,10 @@ contract L1ChugSplashProxy {
bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3; bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;
/// @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) /// @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
bytes32 internal constant IMPLEMENTATION_KEY = bytes32 internal constant IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/// @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) /// @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
bytes32 internal constant OWNER_KEY = bytes32 internal constant OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/// @notice Blocks a function from being called when the parent signals that the system should /// @notice Blocks a function from being called when the parent signals that the system should
/// be paused via an isUpgrading function. /// be paused via an isUpgrading function.
...@@ -37,9 +35,8 @@ contract L1ChugSplashProxy { ...@@ -37,9 +35,8 @@ contract L1ChugSplashProxy {
// We do a low-level call because there's no guarantee that the owner actually *is* an // We do a low-level call because there's no guarantee that the owner actually *is* an
// L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and
// it turns out that it isn't the right type of contract. // it turns out that it isn't the right type of contract.
(bool success, bytes memory returndata) = owner.staticcall( (bool success, bytes memory returndata) =
abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector) owner.staticcall(abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector));
);
// If the call was unsuccessful then we assume that there's no "isUpgrading" method and we // If the call was unsuccessful then we assume that there's no "isUpgrading" method and we
// can just continue as normal. We also expect that the return value is exactly 32 bytes // can just continue as normal. We also expect that the return value is exactly 32 bytes
...@@ -195,9 +192,7 @@ contract L1ChugSplashProxy { ...@@ -195,9 +192,7 @@ contract L1ChugSplashProxy {
returndatacopy(0x0, 0x0, returndatasize()) returndatacopy(0x0, 0x0, returndatasize())
// Success == 0 means a revert. We'll revert too and pass the data up. // Success == 0 means a revert. We'll revert too and pass the data up.
if iszero(success) { if iszero(success) { revert(0x0, returndatasize()) }
revert(0x0, returndatasize())
}
// Otherwise we'll just return and pass the data up. // Otherwise we'll just return and pass the data up.
return(0x0, returndatasize()) return(0x0, returndatasize())
......
...@@ -14,9 +14,7 @@ import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol"; ...@@ -14,9 +14,7 @@ import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/// disabled as part of the EVM equivalence upgrade. /// disabled as part of the EVM equivalence upgrade.
contract LegacyERC20ETH is OptimismMintableERC20 { contract LegacyERC20ETH is OptimismMintableERC20 {
/// @notice Initializes the contract as an Optimism Mintable ERC20. /// @notice Initializes the contract as an Optimism Mintable ERC20.
constructor() constructor() OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH") { }
OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH")
{}
/// @notice Returns the ETH balance of the target account. Overrides the base behavior of the /// @notice Returns the ETH balance of the target account. Overrides the base behavior of the
/// contract to preserve the invariant that the balance within this contract always /// contract to preserve the invariant that the balance within this contract always
...@@ -53,11 +51,7 @@ contract LegacyERC20ETH is OptimismMintableERC20 { ...@@ -53,11 +51,7 @@ contract LegacyERC20ETH is OptimismMintableERC20 {
/// @custom:blocked /// @custom:blocked
/// @notice Transfers funds from some sender account. /// @notice Transfers funds from some sender account.
function transferFrom( function transferFrom(address, address, uint256) public virtual override returns (bool) {
address,
address,
uint256
) public virtual override returns (bool) {
revert("LegacyERC20ETH: transferFrom is disabled"); revert("LegacyERC20ETH: transferFrom is disabled");
} }
......
...@@ -14,7 +14,7 @@ contract LegacyMessagePasser is Semver { ...@@ -14,7 +14,7 @@ contract LegacyMessagePasser is Semver {
mapping(bytes32 => bool) public sentMessages; mapping(bytes32 => bool) public sentMessages;
/// @custom:semver 1.0.1 /// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {} constructor() Semver(1, 0, 1) { }
/// @notice Passes a message to L1. /// @notice Passes a message to L1.
/// @param _message Message to pass to L1. /// @param _message Message to pass to L1.
......
...@@ -29,7 +29,9 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 { ...@@ -29,7 +29,9 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
address _l1Token, address _l1Token,
string memory _name, string memory _name,
string memory _symbol string memory _symbol
) ERC20(_name, _symbol) { )
ERC20(_name, _symbol)
{
l1Token = _l1Token; l1Token = _l1Token;
l2Bridge = _l2Bridge; l2Bridge = _l2Bridge;
} }
...@@ -43,9 +45,8 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 { ...@@ -43,9 +45,8 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
/// @notice EIP165 implementation. /// @notice EIP165 implementation.
function supportsInterface(bytes4 _interfaceId) public pure returns (bool) { function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165 bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^ bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^ ILegacyMintableERC20.mint.selector
ILegacyMintableERC20.mint.selector ^ ^ ILegacyMintableERC20.burn.selector;
ILegacyMintableERC20.burn.selector;
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface; return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
} }
......
...@@ -32,9 +32,7 @@ contract ResolvedDelegateProxy { ...@@ -32,9 +32,7 @@ contract ResolvedDelegateProxy {
/// @notice Fallback, performs a delegatecall to the resolved implementation address. /// @notice Fallback, performs a delegatecall to the resolved implementation address.
// solhint-disable-next-line no-complex-fallback // solhint-disable-next-line no-complex-fallback
fallback() external payable { fallback() external payable {
address target = addressManager[address(this)].getAddress( address target = addressManager[address(this)].getAddress((implementationName[address(this)]));
(implementationName[address(this)])
);
require(target != address(0), "ResolvedDelegateProxy: target address must be initialized"); require(target != address(0), "ResolvedDelegateProxy: target address must be initialized");
......
...@@ -12,11 +12,7 @@ library Arithmetic { ...@@ -12,11 +12,7 @@ library Arithmetic {
/// @param _min The minimum value. /// @param _min The minimum value.
/// @param _max The maximum value. /// @param _max The maximum value.
/// @return The clamped value. /// @return The clamped value.
function clamp( function clamp(int256 _value, int256 _min, int256 _max) internal pure returns (int256) {
int256 _value,
int256 _min,
int256 _max
) internal pure returns (int256) {
return SignedMath.min(SignedMath.max(_value, _min), _max); return SignedMath.min(SignedMath.max(_value, _min), _max);
} }
...@@ -26,13 +22,7 @@ library Arithmetic { ...@@ -26,13 +22,7 @@ library Arithmetic {
/// @param _denominator Fractional denominator. /// @param _denominator Fractional denominator.
/// @param _exponent Power function exponent. /// @param _exponent Power function exponent.
/// @return Result of c * (1 - 1/d)^exp. /// @return Result of c * (1 - 1/d)^exp.
function cdexp( function cdexp(int256 _coefficient, int256 _denominator, int256 _exponent) internal pure returns (int256) {
int256 _coefficient, return (_coefficient * (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;
int256 _denominator,
int256 _exponent
) internal pure returns (int256) {
return
(_coefficient *
(FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;
} }
} }
...@@ -12,11 +12,7 @@ library Bytes { ...@@ -12,11 +12,7 @@ library Bytes {
/// @param _start Starting index of the slice. /// @param _start Starting index of the slice.
/// @param _length Length of the slice. /// @param _length Length of the slice.
/// @return Slice of the input byte array. /// @return Slice of the input byte array.
function slice( function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {
bytes memory _bytes,
uint256 _start,
uint256 _length
) internal pure returns (bytes memory) {
unchecked { unchecked {
require(_length + 31 >= _length, "slice_overflow"); require(_length + 31 >= _length, "slice_overflow");
require(_start + _length >= _start, "slice_overflow"); require(_start + _length >= _start, "slice_overflow");
...@@ -56,9 +52,7 @@ library Bytes { ...@@ -56,9 +52,7 @@ library Bytes {
} lt(mc, end) { } lt(mc, end) {
mc := add(mc, 0x20) mc := add(mc, 0x20)
cc := add(cc, 0x20) cc := add(cc, 0x20)
} { } { mstore(mc, mload(cc)) }
mstore(mc, mload(cc))
}
mstore(tempBytes, _length) mstore(tempBytes, _length)
...@@ -125,11 +119,7 @@ library Bytes { ...@@ -125,11 +119,7 @@ library Bytes {
let nibblesStart := add(_nibbles, 0x20) let nibblesStart := add(_nibbles, 0x20)
// Loop through each byte in the input array // Loop through each byte in the input array
for { for { let i := 0x00 } lt(i, bytesLength) { i := add(i, 0x01) } {
let i := 0x00
} lt(i, bytesLength) {
i := add(i, 0x01)
} {
// Get the starting offset of the next 2 bytes in the nibbles array // Get the starting offset of the next 2 bytes in the nibbles array
let offset := add(nibblesStart, shl(0x01, i)) let offset := add(nibblesStart, shl(0x01, i))
// Load the byte at the current index within the `_bytes` array // Load the byte at the current index within the `_bytes` array
......
...@@ -46,11 +46,7 @@ contract Clone { ...@@ -46,11 +46,7 @@ contract Clone {
/// @param argOffset The offset of the arg in the packed data /// @param argOffset The offset of the arg in the packed data
/// @param arrLen Number of elements in the array /// @param arrLen Number of elements in the array
/// @return arr The array /// @return arr The array
function _getArgUint256Array(uint256 argOffset, uint64 arrLen) function _getArgUint256Array(uint256 argOffset, uint64 arrLen) internal pure returns (uint256[] memory arr) {
internal
pure
returns (uint256[] memory arr)
{
uint256 offset = _getImmutableArgsOffset() + argOffset; uint256 offset = _getImmutableArgsOffset() + argOffset;
arr = new uint256[](arrLen); arr = new uint256[](arrLen);
...@@ -63,11 +59,7 @@ contract Clone { ...@@ -63,11 +59,7 @@ contract Clone {
/// @param argOffset The offset of the arg in the packed data /// @param argOffset The offset of the arg in the packed data
/// @param arrLen Number of elements in the array /// @param arrLen Number of elements in the array
/// @return arr The array /// @return arr The array
function _getArgDynBytes(uint256 argOffset, uint64 arrLen) function _getArgDynBytes(uint256 argOffset, uint64 arrLen) internal pure returns (bytes memory arr) {
internal
pure
returns (bytes memory arr)
{
uint256 offset = _getImmutableArgsOffset() + argOffset; uint256 offset = _getImmutableArgsOffset() + argOffset;
arr = new bytes(arrLen); arr = new bytes(arrLen);
......
...@@ -23,11 +23,7 @@ library Constants { ...@@ -23,11 +23,7 @@ library Constants {
/// @notice Returns the default values for the ResourceConfig. These are the recommended values /// @notice Returns the default values for the ResourceConfig. These are the recommended values
/// for a production network. /// for a production network.
function DEFAULT_RESOURCE_CONFIG() function DEFAULT_RESOURCE_CONFIG() internal pure returns (ResourceMetering.ResourceConfig memory) {
internal
pure
returns (ResourceMetering.ResourceConfig memory)
{
ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({
maxResourceLimit: 20_000_000, maxResourceLimit: 20_000_000,
elasticityMultiplier: 10, elasticityMultiplier: 10,
......
...@@ -60,8 +60,9 @@ type Position is uint128; ...@@ -60,8 +60,9 @@ type Position is uint128;
type GameType is uint8; type GameType is uint8;
/// @notice The current status of the dispute game. /// @notice The current status of the dispute game.
enum GameStatus { enum GameStatus
// The game is currently in progress, and has not been resolved. // The game is currently in progress, and has not been resolved.
{
IN_PROGRESS, IN_PROGRESS,
// The game has concluded, and the `rootClaim` was challenged successfully. // The game has concluded, and the `rootClaim` was challenged successfully.
CHALLENGER_WINS, CHALLENGER_WINS,
......
...@@ -13,11 +13,7 @@ library Encoding { ...@@ -13,11 +13,7 @@ library Encoding {
/// transaction is prefixed with 0x7e to identify its EIP-2718 type. /// transaction is prefixed with 0x7e to identify its EIP-2718 type.
/// @param _tx User deposit transaction to encode. /// @param _tx User deposit transaction to encode.
/// @return RLP encoded L2 deposit transaction. /// @return RLP encoded L2 deposit transaction.
function encodeDepositTransaction(Types.UserDepositTransaction memory _tx) function encodeDepositTransaction(Types.UserDepositTransaction memory _tx) internal pure returns (bytes memory) {
internal
pure
returns (bytes memory)
{
bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex); bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);
bytes[] memory raw = new bytes[](8); bytes[] memory raw = new bytes[](8);
raw[0] = RLPWriter.writeBytes(abi.encodePacked(source)); raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
...@@ -47,7 +43,11 @@ library Encoding { ...@@ -47,7 +43,11 @@ library Encoding {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) internal pure returns (bytes memory) { )
internal
pure
returns (bytes memory)
{
(, uint16 version) = decodeVersionedNonce(_nonce); (, uint16 version) = decodeVersionedNonce(_nonce);
if (version == 0) { if (version == 0) {
return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce); return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);
...@@ -69,15 +69,12 @@ library Encoding { ...@@ -69,15 +69,12 @@ library Encoding {
address _sender, address _sender,
bytes memory _data, bytes memory _data,
uint256 _nonce uint256 _nonce
) internal pure returns (bytes memory) { )
return internal
abi.encodeWithSignature( pure
"relayMessage(address,address,bytes,uint256)", returns (bytes memory)
_target, {
_sender, return abi.encodeWithSignature("relayMessage(address,address,bytes,uint256)", _target, _sender, _data, _nonce);
_data,
_nonce
);
} }
/// @notice Encodes a cross domain message based on the V1 (current) encoding. /// @notice Encodes a cross domain message based on the V1 (current) encoding.
...@@ -95,17 +92,20 @@ library Encoding { ...@@ -95,17 +92,20 @@ library Encoding {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) internal pure returns (bytes memory) { )
return internal
abi.encodeWithSignature( pure
"relayMessage(uint256,address,address,uint256,uint256,bytes)", returns (bytes memory)
_nonce, {
_sender, return abi.encodeWithSignature(
_target, "relayMessage(uint256,address,address,uint256,uint256,bytes)",
_value, _nonce,
_gasLimit, _sender,
_data _target,
); _value,
_gasLimit,
_data
);
} }
/// @notice Adds a version number into the first two bytes of a message nonce. /// @notice Adds a version number into the first two bytes of a message nonce.
......
...@@ -12,11 +12,7 @@ library Hashing { ...@@ -12,11 +12,7 @@ library Hashing {
/// system. /// system.
/// @param _tx User deposit transaction to hash. /// @param _tx User deposit transaction to hash.
/// @return Hash of the RLP encoded L2 deposit transaction. /// @return Hash of the RLP encoded L2 deposit transaction.
function hashDepositTransaction(Types.UserDepositTransaction memory _tx) function hashDepositTransaction(Types.UserDepositTransaction memory _tx) internal pure returns (bytes32) {
internal
pure
returns (bytes32)
{
return keccak256(Encoding.encodeDepositTransaction(_tx)); return keccak256(Encoding.encodeDepositTransaction(_tx));
} }
...@@ -26,11 +22,7 @@ library Hashing { ...@@ -26,11 +22,7 @@ library Hashing {
/// @param _l1BlockHash Hash of the L1 block where the deposit was included. /// @param _l1BlockHash Hash of the L1 block where the deposit was included.
/// @param _logIndex The index of the log that created the deposit transaction. /// @param _logIndex The index of the log that created the deposit transaction.
/// @return Hash of the deposit transaction's "source hash". /// @return Hash of the deposit transaction's "source hash".
function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex) function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex) internal pure returns (bytes32) {
internal
pure
returns (bytes32)
{
bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex)); bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));
return keccak256(abi.encode(bytes32(0), depositId)); return keccak256(abi.encode(bytes32(0), depositId));
} }
...@@ -51,7 +43,11 @@ library Hashing { ...@@ -51,7 +43,11 @@ library Hashing {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) internal pure returns (bytes32) { )
internal
pure
returns (bytes32)
{
(, uint16 version) = Encoding.decodeVersionedNonce(_nonce); (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
if (version == 0) { if (version == 0) {
return hashCrossDomainMessageV0(_target, _sender, _data, _nonce); return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);
...@@ -73,7 +69,11 @@ library Hashing { ...@@ -73,7 +69,11 @@ library Hashing {
address _sender, address _sender,
bytes memory _data, bytes memory _data,
uint256 _nonce uint256 _nonce
) internal pure returns (bytes32) { )
internal
pure
returns (bytes32)
{
return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce)); return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));
} }
...@@ -92,51 +92,33 @@ library Hashing { ...@@ -92,51 +92,33 @@ library Hashing {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) internal pure returns (bytes32) { )
return internal
keccak256( pure
Encoding.encodeCrossDomainMessageV1( returns (bytes32)
_nonce, {
_sender, return keccak256(Encoding.encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data));
_target,
_value,
_gasLimit,
_data
)
);
} }
/// @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract /// @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract
/// @param _tx Withdrawal transaction to hash. /// @param _tx Withdrawal transaction to hash.
/// @return Hashed withdrawal transaction. /// @return Hashed withdrawal transaction.
function hashWithdrawal(Types.WithdrawalTransaction memory _tx) function hashWithdrawal(Types.WithdrawalTransaction memory _tx) internal pure returns (bytes32) {
internal return keccak256(abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data));
pure
returns (bytes32)
{
return
keccak256(
abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)
);
} }
/// @notice Hashes the various elements of an output root proof into an output root hash which /// @notice Hashes the various elements of an output root proof into an output root hash which
/// can be used to check if the proof is valid. /// can be used to check if the proof is valid.
/// @param _outputRootProof Output root proof which should hash to an output root. /// @param _outputRootProof Output root proof which should hash to an output root.
/// @return Hashed output root proof. /// @return Hashed output root proof.
function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof) function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof) internal pure returns (bytes32) {
internal return keccak256(
pure abi.encode(
returns (bytes32) _outputRootProof.version,
{ _outputRootProof.stateRoot,
return _outputRootProof.messagePasserStorageRoot,
keccak256( _outputRootProof.latestBlockhash
abi.encode( )
_outputRootProof.version, );
_outputRootProof.stateRoot,
_outputRootProof.messagePasserStorageRoot,
_outputRootProof.latestBlockhash
)
);
} }
} }
...@@ -19,14 +19,13 @@ library LegacyCrossDomainUtils { ...@@ -19,14 +19,13 @@ library LegacyCrossDomainUtils {
address _sender, address _sender,
bytes memory _message, bytes memory _message,
uint256 _messageNonce uint256 _messageNonce
) internal pure returns (bytes memory) { )
return internal
abi.encodeWithSignature( pure
"relayMessage(address,address,bytes,uint256)", returns (bytes memory)
_target, {
_sender, return abi.encodeWithSignature(
_message, "relayMessage(address,address,bytes,uint256)", _target, _sender, _message, _messageNonce
_messageNonce );
);
} }
} }
...@@ -8,8 +8,7 @@ library Predeploys { ...@@ -8,8 +8,7 @@ library Predeploys {
address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016; address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;
/// @notice Address of the L2CrossDomainMessenger predeploy. /// @notice Address of the L2CrossDomainMessenger predeploy.
address internal constant L2_CROSS_DOMAIN_MESSENGER = address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007;
0x4200000000000000000000000000000000000007;
/// @notice Address of the L2StandardBridge predeploy. /// @notice Address of the L2StandardBridge predeploy.
address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;
...@@ -21,12 +20,10 @@ library Predeploys { ...@@ -21,12 +20,10 @@ library Predeploys {
address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;
/// @notice Address of the OptimismMintableERC20Factory predeploy. /// @notice Address of the OptimismMintableERC20Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY = address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY = 0x4200000000000000000000000000000000000012;
0x4200000000000000000000000000000000000012;
/// @notice Address of the OptimismMintableERC721Factory predeploy. /// @notice Address of the OptimismMintableERC721Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY = address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY = 0x4200000000000000000000000000000000000017;
0x4200000000000000000000000000000000000017;
/// @notice Address of the L1Block predeploy. /// @notice Address of the L1Block predeploy.
address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015; address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;
......
...@@ -9,22 +9,19 @@ library SafeCall { ...@@ -9,22 +9,19 @@ library SafeCall {
/// @param _target Address to call /// @param _target Address to call
/// @param _gas Amount of gas to pass to the call /// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call /// @param _value Amount of value to pass to the call
function send( function send(address _target, uint256 _gas, uint256 _value) internal returns (bool) {
address _target,
uint256 _gas,
uint256 _value
) internal returns (bool) {
bool _success; bool _success;
assembly { assembly {
_success := call( _success :=
_gas, // gas call(
_target, // recipient _gas, // gas
_value, // ether value _target, // recipient
0, // inloc _value, // ether value
0, // inlen 0, // inloc
0, // outloc 0, // inlen
0 // outlen 0, // outloc
) 0 // outlen
)
} }
return _success; return _success;
} }
...@@ -34,23 +31,19 @@ library SafeCall { ...@@ -34,23 +31,19 @@ library SafeCall {
/// @param _gas Amount of gas to pass to the call /// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call /// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call /// @param _calldata Calldata to pass to the call
function call( function call(address _target, uint256 _gas, uint256 _value, bytes memory _calldata) internal returns (bool) {
address _target,
uint256 _gas,
uint256 _value,
bytes memory _calldata
) internal returns (bool) {
bool _success; bool _success;
assembly { assembly {
_success := call( _success :=
_gas, // gas call(
_target, // recipient _gas, // gas
_value, // ether value _target, // recipient
add(_calldata, 32), // inloc _value, // ether value
mload(_calldata), // inlen add(_calldata, 32), // inloc
0, // outloc mload(_calldata), // inlen
0 // outlen 0, // outloc
) 0 // outlen
)
} }
return _success; return _success;
} }
...@@ -82,9 +75,7 @@ library SafeCall { ...@@ -82,9 +75,7 @@ library SafeCall {
bool _hasMinGas; bool _hasMinGas;
assembly { assembly {
// Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas) // Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas)
_hasMinGas := iszero( _hasMinGas := iszero(lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63))))
lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63)))
)
} }
return _hasMinGas; return _hasMinGas;
} }
...@@ -101,7 +92,10 @@ library SafeCall { ...@@ -101,7 +92,10 @@ library SafeCall {
uint256 _minGas, uint256 _minGas,
uint256 _value, uint256 _value,
bytes memory _calldata bytes memory _calldata
) internal returns (bool) { )
internal
returns (bool)
{
bool _success; bool _success;
bool _hasMinGas = hasMinGas(_minGas, 0); bool _hasMinGas = hasMinGas(_minGas, 0);
assembly { assembly {
...@@ -132,15 +126,16 @@ library SafeCall { ...@@ -132,15 +126,16 @@ library SafeCall {
// `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost` // `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost`
// factors of the dynamic cost of the `CALL` opcode), the call will receive at least // factors of the dynamic cost of the `CALL` opcode), the call will receive at least
// the minimum amount of gas specified. // the minimum amount of gas specified.
_success := call( _success :=
gas(), // gas call(
_target, // recipient gas(), // gas
_value, // ether value _target, // recipient
add(_calldata, 32), // inloc _value, // ether value
mload(_calldata), // inlen add(_calldata, 32), // inloc
0x00, // outloc mload(_calldata), // inlen
0x00 // outlen 0x00, // outloc
) 0x00 // outlen
)
} }
return _success; return _success;
} }
......
...@@ -34,10 +34,7 @@ library RLPReader { ...@@ -34,10 +34,7 @@ library RLPReader {
/// @return out_ Output memory reference. /// @return out_ Output memory reference.
function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory out_) { function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory out_) {
// Empty arrays are not RLP items. // Empty arrays are not RLP items.
require( require(_in.length > 0, "RLPReader: length of an RLP item must be greater than zero to be decodable");
_in.length > 0,
"RLPReader: length of an RLP item must be greater than zero to be decodable"
);
MemoryPointer ptr; MemoryPointer ptr;
assembly { assembly {
...@@ -53,15 +50,9 @@ library RLPReader { ...@@ -53,15 +50,9 @@ library RLPReader {
function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory out_) { function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory out_) {
(uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in); (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);
require( require(itemType == RLPItemType.LIST_ITEM, "RLPReader: decoded item type for list is not a list item");
itemType == RLPItemType.LIST_ITEM,
"RLPReader: decoded item type for list is not a list item"
);
require( require(listOffset + listLength == _in.length, "RLPReader: list item has an invalid data remainder");
listOffset + listLength == _in.length,
"RLPReader: list item has an invalid data remainder"
);
// Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by
// writing to the length. Since we can't know the number of RLP items without looping over // writing to the length. Since we can't know the number of RLP items without looping over
...@@ -72,11 +63,8 @@ library RLPReader { ...@@ -72,11 +63,8 @@ library RLPReader {
uint256 itemCount = 0; uint256 itemCount = 0;
uint256 offset = listOffset; uint256 offset = listOffset;
while (offset < _in.length) { while (offset < _in.length) {
(uint256 itemOffset, uint256 itemLength, ) = _decodeLength( (uint256 itemOffset, uint256 itemLength,) = _decodeLength(
RLPItem({ RLPItem({ length: _in.length - offset, ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset) })
length: _in.length - offset,
ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)
})
); );
// We don't need to check itemCount < out.length explicitly because Solidity already // We don't need to check itemCount < out.length explicitly because Solidity already
...@@ -109,15 +97,9 @@ library RLPReader { ...@@ -109,15 +97,9 @@ library RLPReader {
function readBytes(RLPItem memory _in) internal pure returns (bytes memory out_) { function readBytes(RLPItem memory _in) internal pure returns (bytes memory out_) {
(uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);
require( require(itemType == RLPItemType.DATA_ITEM, "RLPReader: decoded item type for bytes is not a data item");
itemType == RLPItemType.DATA_ITEM,
"RLPReader: decoded item type for bytes is not a data item"
);
require( require(_in.length == itemOffset + itemLength, "RLPReader: bytes value contains an invalid remainder");
_in.length == itemOffset + itemLength,
"RLPReader: bytes value contains an invalid remainder"
);
out_ = _copy(_in.ptr, itemOffset, itemLength); out_ = _copy(_in.ptr, itemOffset, itemLength);
} }
...@@ -144,19 +126,12 @@ library RLPReader { ...@@ -144,19 +126,12 @@ library RLPReader {
function _decodeLength(RLPItem memory _in) function _decodeLength(RLPItem memory _in)
private private
pure pure
returns ( returns (uint256 offset_, uint256 length_, RLPItemType type_)
uint256 offset_,
uint256 length_,
RLPItemType type_
)
{ {
// Short-circuit if there's nothing to decode, note that we perform this check when // Short-circuit if there's nothing to decode, note that we perform this check when
// the user creates an RLP item via toRLPItem, but it's always possible for them to bypass // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass
// that function and create an RLP item directly. So we need to check this anyway. // that function and create an RLP item directly. So we need to check this anyway.
require( require(_in.length > 0, "RLPReader: length of an RLP item must be greater than zero to be decodable");
_in.length > 0,
"RLPReader: length of an RLP item must be greater than zero to be decodable"
);
MemoryPointer ptr = _in.ptr; MemoryPointer ptr = _in.ptr;
uint256 prefix; uint256 prefix;
...@@ -174,8 +149,7 @@ library RLPReader { ...@@ -174,8 +149,7 @@ library RLPReader {
uint256 strLen = prefix - 0x80; uint256 strLen = prefix - 0x80;
require( require(
_in.length > strLen, _in.length > strLen, "RLPReader: length of content must be greater than string length (short string)"
"RLPReader: length of content must be greater than string length (short string)"
); );
bytes1 firstByteOfContent; bytes1 firstByteOfContent;
...@@ -204,8 +178,7 @@ library RLPReader { ...@@ -204,8 +178,7 @@ library RLPReader {
} }
require( require(
firstByteOfContent != 0x00, firstByteOfContent != 0x00, "RLPReader: length of content must not have any leading zeros (long string)"
"RLPReader: length of content must not have any leading zeros (long string)"
); );
uint256 strLen; uint256 strLen;
...@@ -213,10 +186,7 @@ library RLPReader { ...@@ -213,10 +186,7 @@ library RLPReader {
strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1))) strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))
} }
require( require(strLen > 55, "RLPReader: length of content must be greater than 55 bytes (long string)");
strLen > 55,
"RLPReader: length of content must be greater than 55 bytes (long string)"
);
require( require(
_in.length > lenOfStrLen + strLen, _in.length > lenOfStrLen + strLen,
...@@ -229,10 +199,7 @@ library RLPReader { ...@@ -229,10 +199,7 @@ library RLPReader {
// slither-disable-next-line variable-scope // slither-disable-next-line variable-scope
uint256 listLen = prefix - 0xc0; uint256 listLen = prefix - 0xc0;
require( require(_in.length > listLen, "RLPReader: length of content must be greater than list length (short list)");
_in.length > listLen,
"RLPReader: length of content must be greater than list length (short list)"
);
return (1, listLen, RLPItemType.LIST_ITEM); return (1, listLen, RLPItemType.LIST_ITEM);
} else { } else {
...@@ -250,8 +217,7 @@ library RLPReader { ...@@ -250,8 +217,7 @@ library RLPReader {
} }
require( require(
firstByteOfContent != 0x00, firstByteOfContent != 0x00, "RLPReader: length of content must not have any leading zeros (long list)"
"RLPReader: length of content must not have any leading zeros (long list)"
); );
uint256 listLen; uint256 listLen;
...@@ -259,10 +225,7 @@ library RLPReader { ...@@ -259,10 +225,7 @@ library RLPReader {
listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1))) listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))
} }
require( require(listLen > 55, "RLPReader: length of content must be greater than 55 bytes (long list)");
listLen > 55,
"RLPReader: length of content must be greater than 55 bytes (long list)"
);
require( require(
_in.length > lenOfListLen + listLen, _in.length > lenOfListLen + listLen,
...@@ -278,11 +241,7 @@ library RLPReader { ...@@ -278,11 +241,7 @@ library RLPReader {
/// @param _offset Offset to start reading from. /// @param _offset Offset to start reading from.
/// @param _length Number of bytes to read. /// @param _length Number of bytes to read.
/// @return out_ Copied bytes. /// @return out_ Copied bytes.
function _copy( function _copy(MemoryPointer _src, uint256 _offset, uint256 _length) private pure returns (bytes memory out_) {
MemoryPointer _src,
uint256 _offset,
uint256 _length
) private pure returns (bytes memory out_) {
out_ = new bytes(_length); out_ = new bytes(_length);
if (_length == 0) { if (_length == 0) {
return out_; return out_;
...@@ -295,17 +254,9 @@ library RLPReader { ...@@ -295,17 +254,9 @@ library RLPReader {
assembly { assembly {
let dest := add(out_, 32) let dest := add(out_, 32)
let i := 0 let i := 0
for { for { } lt(i, _length) { i := add(i, 32) } { mstore(add(dest, i), mload(add(src, i))) }
} lt(i, _length) {
i := add(i, 32)
} {
mstore(add(dest, i), mload(add(src, i)))
}
if gt(i, _length) { if gt(i, _length) { mstore(add(dest, _length), 0) }
mstore(add(dest, _length), 0)
}
} }
} }
} }
...@@ -74,7 +74,7 @@ library RLPWriter { ...@@ -74,7 +74,7 @@ library RLPWriter {
out_ = new bytes(lenLen + 1); out_ = new bytes(lenLen + 1);
out_[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55); out_[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);
for (i = 1; i <= lenLen; i++) { for (i = 1; i <= lenLen; i++) {
out_[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256)); out_[i] = bytes1(uint8((_len / (256 ** (lenLen - i))) % 256));
} }
} }
} }
...@@ -103,11 +103,7 @@ library RLPWriter { ...@@ -103,11 +103,7 @@ library RLPWriter {
/// @param _dest Destination location. /// @param _dest Destination location.
/// @param _src Source location. /// @param _src Source location.
/// @param _len Length of memory to copy. /// @param _len Length of memory to copy.
function _memcpy( function _memcpy(uint256 _dest, uint256 _src, uint256 _len) private pure {
uint256 _dest,
uint256 _src,
uint256 _len
) private pure {
uint256 dest = _dest; uint256 dest = _dest;
uint256 src = _src; uint256 src = _src;
uint256 len = _len; uint256 len = _len;
...@@ -122,7 +118,7 @@ library RLPWriter { ...@@ -122,7 +118,7 @@ library RLPWriter {
uint256 mask; uint256 mask;
unchecked { unchecked {
mask = 256**(32 - len) - 1; mask = 256 ** (32 - len) - 1;
} }
assembly { assembly {
let srcpart := and(mload(src), not(mask)) let srcpart := and(mload(src), not(mask))
......
...@@ -52,7 +52,11 @@ library MerkleTrie { ...@@ -52,7 +52,11 @@ library MerkleTrie {
bytes memory _value, bytes memory _value,
bytes[] memory _proof, bytes[] memory _proof,
bytes32 _root bytes32 _root
) internal pure returns (bool valid_) { )
internal
pure
returns (bool valid_)
{
valid_ = Bytes.equal(_value, get(_key, _proof, _root)); valid_ = Bytes.equal(_value, get(_key, _proof, _root));
} }
...@@ -61,11 +65,7 @@ library MerkleTrie { ...@@ -61,11 +65,7 @@ library MerkleTrie {
/// @param _proof Merkle trie inclusion proof for the key. /// @param _proof Merkle trie inclusion proof for the key.
/// @param _root Known root of the Merkle trie. /// @param _root Known root of the Merkle trie.
/// @return value_ Value of the key if it exists. /// @return value_ Value of the key if it exists.
function get( function get(bytes memory _key, bytes[] memory _proof, bytes32 _root) internal pure returns (bytes memory value_) {
bytes memory _key,
bytes[] memory _proof,
bytes32 _root
) internal pure returns (bytes memory value_) {
require(_key.length > 0, "MerkleTrie: empty key"); require(_key.length > 0, "MerkleTrie: empty key");
TrieNode[] memory proof = _parseProof(_proof); TrieNode[] memory proof = _parseProof(_proof);
...@@ -78,10 +78,7 @@ library MerkleTrie { ...@@ -78,10 +78,7 @@ library MerkleTrie {
TrieNode memory currentNode = proof[i]; TrieNode memory currentNode = proof[i];
// Key index should never exceed total key length or we'll be out of bounds. // Key index should never exceed total key length or we'll be out of bounds.
require( require(currentKeyIndex <= key.length, "MerkleTrie: key index exceeds total key length");
currentKeyIndex <= key.length,
"MerkleTrie: key index exceeds total key length"
);
if (currentKeyIndex == 0) { if (currentKeyIndex == 0) {
// First proof element is always the root node. // First proof element is always the root node.
...@@ -97,10 +94,7 @@ library MerkleTrie { ...@@ -97,10 +94,7 @@ library MerkleTrie {
); );
} else { } else {
// Nodes smaller than 32 bytes aren't hashed. // Nodes smaller than 32 bytes aren't hashed.
require( require(Bytes.equal(currentNode.encoded, currentNodeID), "MerkleTrie: invalid internal node hash");
Bytes.equal(currentNode.encoded, currentNodeID),
"MerkleTrie: invalid internal node hash"
);
} }
if (currentNode.decoded.length == BRANCH_NODE_LENGTH) { if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {
...@@ -111,16 +105,10 @@ library MerkleTrie { ...@@ -111,16 +105,10 @@ library MerkleTrie {
// even when the value wasn't explicitly placed there. Geth treats a value of // even when the value wasn't explicitly placed there. Geth treats a value of
// bytes(0) as "key does not exist" and so we do the same. // bytes(0) as "key does not exist" and so we do the same.
value_ = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]); value_ = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);
require( require(value_.length > 0, "MerkleTrie: value length must be greater than zero (branch)");
value_.length > 0,
"MerkleTrie: value length must be greater than zero (branch)"
);
// Extra proof elements are not allowed. // Extra proof elements are not allowed.
require( require(i == proof.length - 1, "MerkleTrie: value node must be last node in proof (branch)");
i == proof.length - 1,
"MerkleTrie: value node must be last node in proof (branch)"
);
return value_; return value_;
} else { } else {
...@@ -164,16 +152,10 @@ library MerkleTrie { ...@@ -164,16 +152,10 @@ library MerkleTrie {
// say that if the value is empty, the key should not exist and the proof is // say that if the value is empty, the key should not exist and the proof is
// invalid. // invalid.
value_ = RLPReader.readBytes(currentNode.decoded[1]); value_ = RLPReader.readBytes(currentNode.decoded[1]);
require( require(value_.length > 0, "MerkleTrie: value length must be greater than zero (leaf)");
value_.length > 0,
"MerkleTrie: value length must be greater than zero (leaf)"
);
// Extra proof elements are not allowed. // Extra proof elements are not allowed.
require( require(i == proof.length - 1, "MerkleTrie: value node must be last node in proof (leaf)");
i == proof.length - 1,
"MerkleTrie: value node must be last node in proof (leaf)"
);
return value_; return value_;
} else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) { } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {
...@@ -200,7 +182,7 @@ library MerkleTrie { ...@@ -200,7 +182,7 @@ library MerkleTrie {
function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory proof_) { function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory proof_) {
uint256 length = _proof.length; uint256 length = _proof.length;
proof_ = new TrieNode[](length); proof_ = new TrieNode[](length);
for (uint256 i = 0; i < length; ) { for (uint256 i = 0; i < length;) {
proof_[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) }); proof_[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });
unchecked { unchecked {
++i; ++i;
...@@ -227,13 +209,9 @@ library MerkleTrie { ...@@ -227,13 +209,9 @@ library MerkleTrie {
/// @param _a First nibble array. /// @param _a First nibble array.
/// @param _b Second nibble array. /// @param _b Second nibble array.
/// @return shared_ Number of shared nibbles. /// @return shared_ Number of shared nibbles.
function _getSharedNibbleLength(bytes memory _a, bytes memory _b) function _getSharedNibbleLength(bytes memory _a, bytes memory _b) private pure returns (uint256 shared_) {
private
pure
returns (uint256 shared_)
{
uint256 max = (_a.length < _b.length) ? _a.length : _b.length; uint256 max = (_a.length < _b.length) ? _a.length : _b.length;
for (; shared_ < max && _a[shared_] == _b[shared_]; ) { for (; shared_ < max && _a[shared_] == _b[shared_];) {
unchecked { unchecked {
++shared_; ++shared_;
} }
......
...@@ -21,7 +21,11 @@ library SecureMerkleTrie { ...@@ -21,7 +21,11 @@ library SecureMerkleTrie {
bytes memory _value, bytes memory _value,
bytes[] memory _proof, bytes[] memory _proof,
bytes32 _root bytes32 _root
) internal pure returns (bool valid_) { )
internal
pure
returns (bool valid_)
{
bytes memory key = _getSecureKey(_key); bytes memory key = _getSecureKey(_key);
valid_ = MerkleTrie.verifyInclusionProof(key, _value, _proof, _root); valid_ = MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);
} }
...@@ -31,11 +35,7 @@ library SecureMerkleTrie { ...@@ -31,11 +35,7 @@ library SecureMerkleTrie {
/// @param _proof Merkle trie inclusion proof for the key. /// @param _proof Merkle trie inclusion proof for the key.
/// @param _root Known root of the Merkle trie. /// @param _root Known root of the Merkle trie.
/// @return value_ Value of the key if it exists. /// @return value_ Value of the key if it exists.
function get( function get(bytes memory _key, bytes[] memory _proof, bytes32 _root) internal pure returns (bytes memory value_) {
bytes memory _key,
bytes[] memory _proof,
bytes32 _root
) internal pure returns (bytes memory value_) {
bytes memory key = _getSecureKey(_key); bytes memory key = _getSecureKey(_key);
value_ = MerkleTrie.get(key, _proof, _root); value_ = MerkleTrie.get(key, _proof, _root);
} }
......
...@@ -25,27 +25,17 @@ contract AssetReceiver is Transactor { ...@@ -25,27 +25,17 @@ contract AssetReceiver is Transactor {
/// @param recipient Address that received the withdrawal. /// @param recipient Address that received the withdrawal.
/// @param asset Address of the token being withdrawn. /// @param asset Address of the token being withdrawn.
/// @param amount ERC20 amount withdrawn. /// @param amount ERC20 amount withdrawn.
event WithdrewERC20( event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount);
address indexed withdrawer,
address indexed recipient,
address indexed asset,
uint256 amount
);
/// @notice Emitted when ERC20 tokens are withdrawn from this address. /// @notice Emitted when ERC20 tokens are withdrawn from this address.
/// @param withdrawer Address that triggered the withdrawal. /// @param withdrawer Address that triggered the withdrawal.
/// @param recipient Address that received the withdrawal. /// @param recipient Address that received the withdrawal.
/// @param asset Address of the token being withdrawn. /// @param asset Address of the token being withdrawn.
/// @param id Token ID being withdrawn. /// @param id Token ID being withdrawn.
event WithdrewERC721( event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id);
address indexed withdrawer,
address indexed recipient,
address indexed asset,
uint256 id
);
/// @param _owner Initial contract owner. /// @param _owner Initial contract owner.
constructor(address _owner) Transactor(_owner) {} constructor(address _owner) Transactor(_owner) { }
/// @notice Make sure we can receive ETH. /// @notice Make sure we can receive ETH.
receive() external payable { receive() external payable {
...@@ -63,7 +53,7 @@ contract AssetReceiver is Transactor { ...@@ -63,7 +53,7 @@ contract AssetReceiver is Transactor {
/// @param _amount Amount of ETH to withdraw. /// @param _amount Amount of ETH to withdraw.
function withdrawETH(address payable _to, uint256 _amount) public onlyOwner { function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {
// slither-disable-next-line reentrancy-unlimited-gas // slither-disable-next-line reentrancy-unlimited-gas
(bool success, ) = _to.call{ value: _amount }(""); (bool success,) = _to.call{ value: _amount }("");
success; // Suppress warning; We ignore the low-level call result. success; // Suppress warning; We ignore the low-level call result.
emit WithdrewETH(msg.sender, _to, _amount); emit WithdrewETH(msg.sender, _to, _amount);
} }
...@@ -79,11 +69,7 @@ contract AssetReceiver is Transactor { ...@@ -79,11 +69,7 @@ contract AssetReceiver is Transactor {
/// @param _asset ERC20 token to withdraw. /// @param _asset ERC20 token to withdraw.
/// @param _to Address to receive the ERC20 balance. /// @param _to Address to receive the ERC20 balance.
/// @param _amount Amount of ERC20 to withdraw. /// @param _amount Amount of ERC20 to withdraw.
function withdrawERC20( function withdrawERC20(ERC20 _asset, address _to, uint256 _amount) public onlyOwner {
ERC20 _asset,
address _to,
uint256 _amount
) public onlyOwner {
// slither-disable-next-line unchecked-transfer // slither-disable-next-line unchecked-transfer
_asset.transfer(_to, _amount); _asset.transfer(_to, _amount);
// slither-disable-next-line reentrancy-events // slither-disable-next-line reentrancy-events
...@@ -94,11 +80,7 @@ contract AssetReceiver is Transactor { ...@@ -94,11 +80,7 @@ contract AssetReceiver is Transactor {
/// @param _asset ERC721 token to withdraw. /// @param _asset ERC721 token to withdraw.
/// @param _to Address to receive the ERC721 token. /// @param _to Address to receive the ERC721 token.
/// @param _id Token ID of the ERC721 token to withdraw. /// @param _id Token ID of the ERC721 token to withdraw.
function withdrawERC721( function withdrawERC721(ERC721 _asset, address _to, uint256 _id) external onlyOwner {
ERC721 _asset,
address _to,
uint256 _id
) external onlyOwner {
_asset.transferFrom(address(this), _to, _id); _asset.transferFrom(address(this), _to, _id);
// slither-disable-next-line reentrancy-events // slither-disable-next-line reentrancy-events
emit WithdrewERC721(msg.sender, _to, address(_asset), _id); emit WithdrewERC721(msg.sender, _to, address(_asset), _id);
......
...@@ -7,7 +7,7 @@ import { Owned } from "@rari-capital/solmate/src/auth/Owned.sol"; ...@@ -7,7 +7,7 @@ import { Owned } from "@rari-capital/solmate/src/auth/Owned.sol";
/// @notice Transactor is a minimal contract that can send transactions. /// @notice Transactor is a minimal contract that can send transactions.
contract Transactor is Owned { contract Transactor is Owned {
/// @param _owner Initial contract owner. /// @param _owner Initial contract owner.
constructor(address _owner) Owned(_owner) {} constructor(address _owner) Owned(_owner) { }
/// @notice Sends a CALL to a target address. /// @notice Sends a CALL to a target address.
/// @param _target Address to call. /// @param _target Address to call.
...@@ -19,7 +19,12 @@ contract Transactor is Owned { ...@@ -19,7 +19,12 @@ contract Transactor is Owned {
address _target, address _target,
bytes memory _data, bytes memory _data,
uint256 _value uint256 _value
) external payable onlyOwner returns (bool success_, bytes memory data_) { )
external
payable
onlyOwner
returns (bool success_, bytes memory data_)
{
(success_, data_) = _target.call{ value: _value }(_data); (success_, data_) = _target.call{ value: _value }(_data);
} }
...@@ -28,7 +33,10 @@ contract Transactor is Owned { ...@@ -28,7 +33,10 @@ contract Transactor is Owned {
/// @param _data Data to send with the call. /// @param _data Data to send with the call.
/// @return success_ Boolean success value. /// @return success_ Boolean success value.
/// @return data_ Bytes data returned by the call. /// @return data_ Bytes data returned by the call.
function DELEGATECALL(address _target, bytes memory _data) function DELEGATECALL(
address _target,
bytes memory _data
)
external external
payable payable
onlyOwner onlyOwner
......
...@@ -33,11 +33,7 @@ contract TransferOnion is ReentrancyGuard { ...@@ -33,11 +33,7 @@ contract TransferOnion is ReentrancyGuard {
/// @param _token Address of the token to distribute. /// @param _token Address of the token to distribute.
/// @param _sender Address of the sender to distribute from. /// @param _sender Address of the sender to distribute from.
/// @param _shell Initial shell of the onion. /// @param _shell Initial shell of the onion.
constructor( constructor(ERC20 _token, address _sender, bytes32 _shell) {
ERC20 _token,
address _sender,
bytes32 _shell
) {
TOKEN = _token; TOKEN = _token;
SENDER = _sender; SENDER = _sender;
shell = _shell; shell = _shell;
...@@ -48,7 +44,7 @@ contract TransferOnion is ReentrancyGuard { ...@@ -48,7 +44,7 @@ contract TransferOnion is ReentrancyGuard {
function peel(Layer[] memory _layers) public nonReentrant { function peel(Layer[] memory _layers) public nonReentrant {
bytes32 tempShell = shell; bytes32 tempShell = shell;
uint256 length = _layers.length; uint256 length = _layers.length;
for (uint256 i = 0; i < length; ) { for (uint256 i = 0; i < length;) {
Layer memory layer = _layers[i]; Layer memory layer = _layers[i];
// Confirm that the onion layer is correct. // Confirm that the onion layer is correct.
......
...@@ -55,42 +55,29 @@ contract Drippie is AssetReceiver { ...@@ -55,42 +55,29 @@ contract Drippie is AssetReceiver {
/// @param nameref Indexed name parameter (hashed). /// @param nameref Indexed name parameter (hashed).
/// @param name Unindexed name parameter (unhashed). /// @param name Unindexed name parameter (unhashed).
/// @param config Config for the created drip. /// @param config Config for the created drip.
event DripCreated( // Emit name twice because indexed version is hashed.
// Emit name twice because indexed version is hashed. event DripCreated(string indexed nameref, string name, DripConfig config);
string indexed nameref,
string name,
DripConfig config
);
/// @notice Emitted when a drip status is updated. /// @notice Emitted when a drip status is updated.
/// @param nameref Indexed name parameter (hashed). /// @param nameref Indexed name parameter (hashed).
/// @param name Unindexed name parameter (unhashed). /// @param name Unindexed name parameter (unhashed).
/// @param status New drip status. /// @param status New drip status.
event DripStatusUpdated( // Emit name twice because indexed version is hashed.
// Emit name twice because indexed version is hashed. event DripStatusUpdated(string indexed nameref, string name, DripStatus status);
string indexed nameref,
string name,
DripStatus status
);
/// @notice Emitted when a drip is executed. /// @notice Emitted when a drip is executed.
/// @param nameref Indexed name parameter (hashed). /// @param nameref Indexed name parameter (hashed).
/// @param name Unindexed name parameter (unhashed). /// @param name Unindexed name parameter (unhashed).
/// @param executor Address that executed the drip. /// @param executor Address that executed the drip.
/// @param timestamp Time when the drip was executed. /// @param timestamp Time when the drip was executed.
event DripExecuted( // Emit name twice because indexed version is hashed.
// Emit name twice because indexed version is hashed. event DripExecuted(string indexed nameref, string name, address executor, uint256 timestamp);
string indexed nameref,
string name,
address executor,
uint256 timestamp
);
/// @notice Maps from drip names to drip states. /// @notice Maps from drip names to drip states.
mapping(string => DripState) public drips; mapping(string => DripState) public drips;
//// @param _owner Initial contract owner. //// @param _owner Initial contract owner.
constructor(address _owner) AssetReceiver(_owner) {} constructor(address _owner) AssetReceiver(_owner) { }
/// @notice Creates a new drip with the given name and configuration. Once created, drips cannot /// @notice Creates a new drip with the given name and configuration. Once created, drips cannot
/// be modified in any way (this is a security measure). If you want to update a drip, /// be modified in any way (this is a security measure). If you want to update a drip,
...@@ -101,24 +88,15 @@ contract Drippie is AssetReceiver { ...@@ -101,24 +88,15 @@ contract Drippie is AssetReceiver {
// Make sure this drip doesn't already exist. We *must* guarantee that no other function // Make sure this drip doesn't already exist. We *must* guarantee that no other function
// will ever set the status of a drip back to NONE after it's been created. This is why // will ever set the status of a drip back to NONE after it's been created. This is why
// archival is a separate status. // archival is a separate status.
require( require(drips[_name].status == DripStatus.NONE, "Drippie: drip with that name already exists");
drips[_name].status == DripStatus.NONE,
"Drippie: drip with that name already exists"
);
// Validate the drip interval, only allowing an interval of zero if the drip has explicitly // Validate the drip interval, only allowing an interval of zero if the drip has explicitly
// been marked as reentrant. Prevents client-side bugs making a drip infinitely executable // been marked as reentrant. Prevents client-side bugs making a drip infinitely executable
// within the same block (of course, restricted by gas limits). // within the same block (of course, restricted by gas limits).
if (_config.reentrant) { if (_config.reentrant) {
require( require(_config.interval == 0, "Drippie: if allowing reentrant drip, must set interval to zero");
_config.interval == 0,
"Drippie: if allowing reentrant drip, must set interval to zero"
);
} else { } else {
require( require(_config.interval > 0, "Drippie: interval must be greater than zero if drip is not reentrant");
_config.interval > 0,
"Drippie: interval must be greater than zero if drip is not reentrant"
);
} }
// We initialize this way because Solidity won't let us copy arrays into storage yet. // We initialize this way because Solidity won't let us copy arrays into storage yet.
...@@ -147,10 +125,7 @@ contract Drippie is AssetReceiver { ...@@ -147,10 +125,7 @@ contract Drippie is AssetReceiver {
function status(string calldata _name, DripStatus _status) external onlyOwner { function status(string calldata _name, DripStatus _status) external onlyOwner {
// Make sure we can never set drip status back to NONE. A simple security measure to // Make sure we can never set drip status back to NONE. A simple security measure to
// prevent accidental overwrites if this code is ever updated down the line. // prevent accidental overwrites if this code is ever updated down the line.
require( require(_status != DripStatus.NONE, "Drippie: drip status can never be set back to NONE after creation");
_status != DripStatus.NONE,
"Drippie: drip status can never be set back to NONE after creation"
);
// Load the drip status once to avoid unnecessary SLOADs. // Load the drip status once to avoid unnecessary SLOADs.
DripStatus curr = drips[_name].status; DripStatus curr = drips[_name].status;
...@@ -158,34 +133,22 @@ contract Drippie is AssetReceiver { ...@@ -158,34 +133,22 @@ contract Drippie is AssetReceiver {
// Make sure the drip in question actually exists. Not strictly necessary but there doesn't // Make sure the drip in question actually exists. Not strictly necessary but there doesn't
// seem to be any clear reason why you would want to do this, and it may save some gas in // seem to be any clear reason why you would want to do this, and it may save some gas in
// the case of a front-end bug. // the case of a front-end bug.
require( require(curr != DripStatus.NONE, "Drippie: drip with that name does not exist and cannot be updated");
curr != DripStatus.NONE,
"Drippie: drip with that name does not exist and cannot be updated"
);
// Once a drip has been archived, it cannot be un-archived. This is, after all, the entire // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire
// point of archiving a drip. // point of archiving a drip.
require( require(curr != DripStatus.ARCHIVED, "Drippie: drip with that name has been archived and cannot be updated");
curr != DripStatus.ARCHIVED,
"Drippie: drip with that name has been archived and cannot be updated"
);
// Although not strictly necessary, we make sure that the status here is actually changing. // Although not strictly necessary, we make sure that the status here is actually changing.
// This may save the client some gas if there's a front-end bug and the user accidentally // This may save the client some gas if there's a front-end bug and the user accidentally
// tries to "change" the status to the same value as before. // tries to "change" the status to the same value as before.
require( require(curr != _status, "Drippie: cannot set drip status to the same status as its current status");
curr != _status,
"Drippie: cannot set drip status to the same status as its current status"
);
// If the user is trying to archive this drip, make sure the drip has been paused. We do // If the user is trying to archive this drip, make sure the drip has been paused. We do
// not allow users to archive active drips so that the effects of this action are more // not allow users to archive active drips so that the effects of this action are more
// abundantly clear. // abundantly clear.
if (_status == DripStatus.ARCHIVED) { if (_status == DripStatus.ARCHIVED) {
require( require(curr == DripStatus.PAUSED, "Drippie: drip must first be paused before being archived");
curr == DripStatus.PAUSED,
"Drippie: drip must first be paused before being archived"
);
} }
// If we made it here then we can safely update the status. // If we made it here then we can safely update the status.
...@@ -200,10 +163,7 @@ contract Drippie is AssetReceiver { ...@@ -200,10 +163,7 @@ contract Drippie is AssetReceiver {
DripState storage state = drips[_name]; DripState storage state = drips[_name];
// Only allow active drips to be executed, an obvious security measure. // Only allow active drips to be executed, an obvious security measure.
require( require(state.status == DripStatus.ACTIVE, "Drippie: selected drip does not exist or is not currently active");
state.status == DripStatus.ACTIVE,
"Drippie: selected drip does not exist or is not currently active"
);
// Don't drip if the drip interval has not yet elapsed since the last time we dripped. This // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This
// is a safety measure that prevents a malicious recipient from, e.g., spending all of // is a safety measure that prevents a malicious recipient from, e.g., spending all of
...@@ -269,7 +229,7 @@ contract Drippie is AssetReceiver { ...@@ -269,7 +229,7 @@ contract Drippie is AssetReceiver {
// will ever happen in practice). Could save a marginal amount of gas to ignore the // will ever happen in practice). Could save a marginal amount of gas to ignore the
// returndata. // returndata.
// slither-disable-next-line calls-loop // slither-disable-next-line calls-loop
(bool success, ) = action.target.call{ value: action.value }(action.data); (bool success,) = action.target.call{ value: action.value }(action.data);
// Generally should not happen, but could if there's a misconfiguration (e.g., passing // Generally should not happen, but could if there's a misconfiguration (e.g., passing
// the wrong data to the target contract), the recipient is not payable, or // the wrong data to the target contract), the recipient is not payable, or
...@@ -279,10 +239,7 @@ contract Drippie is AssetReceiver { ...@@ -279,10 +239,7 @@ contract Drippie is AssetReceiver {
// Note that this forces the drip executor to supply sufficient gas to the call // Note that this forces the drip executor to supply sufficient gas to the call
// (assuming there is some sufficient gas limit that exists, otherwise the drip will // (assuming there is some sufficient gas limit that exists, otherwise the drip will
// not execute). // not execute).
require( require(success, "Drippie: drip was unsuccessful, please check your configuration for mistakes");
success,
"Drippie: drip was unsuccessful, please check your configuration for mistakes"
);
} }
emit DripExecuted(_name, _name, msg.sender, block.timestamp); emit DripExecuted(_name, _name, msg.sender, block.timestamp);
......
...@@ -25,12 +25,10 @@ contract CheckGelatoLow is IDripCheck { ...@@ -25,12 +25,10 @@ contract CheckGelatoLow is IDripCheck {
Params memory params = abi.decode(_params, (Params)); Params memory params = abi.decode(_params, (Params));
// Check GelatoTreasury ETH balance is below threshold. // Check GelatoTreasury ETH balance is below threshold.
execute_ = execute_ = IGelatoTreasury(params.treasury).userTokenBalance(
IGelatoTreasury(params.treasury).userTokenBalance( params.recipient,
params.recipient, // Gelato represents ETH as 0xeeeee....eeeee
// Gelato represents ETH as 0xeeeee....eeeee 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE ) < params.threshold;
) <
params.threshold;
} }
} }
...@@ -20,12 +20,7 @@ contract Faucet { ...@@ -20,12 +20,7 @@ contract Faucet {
/// @param userId The id of the user that requested the drip. /// @param userId The id of the user that requested the drip.
/// @param amount The amount of funds sent. /// @param amount The amount of funds sent.
/// @param recipient The recipient of the drip. /// @param recipient The recipient of the drip.
event Drip( event Drip(string indexed authModule, bytes32 indexed userId, uint256 amount, address indexed recipient);
string indexed authModule,
bytes32 indexed userId,
uint256 amount,
address indexed recipient
);
/// @notice Parameters for a drip. /// @notice Parameters for a drip.
struct DripParameters { struct DripParameters {
......
...@@ -14,8 +14,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 { ...@@ -14,8 +14,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 {
address public immutable ADMIN; address public immutable ADMIN;
/// @notice EIP712 typehash for the Proof type. /// @notice EIP712 typehash for the Proof type.
bytes32 public constant PROOF_TYPEHASH = bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
/// @notice Struct that represents a proof that verifies the admin. /// @notice Struct that represents a proof that verifies the admin.
/// @custom:field recipient Address that will be receiving the faucet funds. /// @custom:field recipient Address that will be receiving the faucet funds.
...@@ -30,11 +29,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 { ...@@ -30,11 +29,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 {
/// @param _admin Admin address that can sign off on drips. /// @param _admin Admin address that can sign off on drips.
/// @param _name Contract name. /// @param _name Contract name.
/// @param _version The current major version of the signing domain. /// @param _version The current major version of the signing domain.
constructor( constructor(address _admin, string memory _name, string memory _version) EIP712(_name, _version) {
address _admin,
string memory _name,
string memory _version
) EIP712(_name, _version) {
ADMIN = _admin; ADMIN = _admin;
} }
...@@ -43,13 +38,15 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 { ...@@ -43,13 +38,15 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 {
Faucet.DripParameters memory _params, Faucet.DripParameters memory _params,
bytes32 _id, bytes32 _id,
bytes memory _proof bytes memory _proof
) external view returns (bool valid_) { )
external
view
returns (bool valid_)
{
// Generate a EIP712 typed data hash to compare against the proof. // Generate a EIP712 typed data hash to compare against the proof.
valid_ = SignatureChecker.isValidSignatureNow( valid_ = SignatureChecker.isValidSignatureNow(
ADMIN, ADMIN,
_hashTypedDataV4( _hashTypedDataV4(keccak256(abi.encode(PROOF_TYPEHASH, _params.recipient, _params.nonce, _id))),
keccak256(abi.encode(PROOF_TYPEHASH, _params.recipient, _params.nonce, _id))
),
_proof _proof
); );
} }
......
...@@ -15,5 +15,8 @@ interface IFaucetAuthModule { ...@@ -15,5 +15,8 @@ interface IFaucetAuthModule {
Faucet.DripParameters memory _params, Faucet.DripParameters memory _params,
bytes32 _id, bytes32 _id,
bytes memory _proof bytes memory _proof
) external view returns (bool); )
external
view
returns (bool);
} }
...@@ -26,25 +26,16 @@ contract AttestationStation is Semver { ...@@ -26,25 +26,16 @@ contract AttestationStation is Semver {
/// @param about Address attestation is about. /// @param about Address attestation is about.
/// @param key Key of the attestation. /// @param key Key of the attestation.
/// @param val Value of the attestation. /// @param val Value of the attestation.
event AttestationCreated( event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
/// @custom:semver 1.1.1 /// @custom:semver 1.1.1
constructor() Semver(1, 1, 1) {} constructor() Semver(1, 1, 1) { }
/// @notice Allows anyone to create an attestation. /// @notice Allows anyone to create an attestation.
/// @param _about Address that the attestation is about. /// @param _about Address that the attestation is about.
/// @param _key A key used to namespace the attestation. /// @param _key A key used to namespace the attestation.
/// @param _val An arbitrary value stored as part of the attestation. /// @param _val An arbitrary value stored as part of the attestation.
function attest( function attest(address _about, bytes32 _key, bytes memory _val) public {
address _about,
bytes32 _key,
bytes memory _val
) public {
attestations[msg.sender][_about][_key] = _val; attestations[msg.sender][_about][_key] = _val;
emit AttestationCreated(msg.sender, _about, _key, _val); emit AttestationCreated(msg.sender, _about, _key, _val);
...@@ -54,7 +45,7 @@ contract AttestationStation is Semver { ...@@ -54,7 +45,7 @@ contract AttestationStation is Semver {
/// @param _attestations An array of AttestationData structs. /// @param _attestations An array of AttestationData structs.
function attest(AttestationData[] calldata _attestations) external { function attest(AttestationData[] calldata _attestations) external {
uint256 length = _attestations.length; uint256 length = _attestations.length;
for (uint256 i = 0; i < length; ) { for (uint256 i = 0; i < length;) {
AttestationData memory attestation = _attestations[i]; AttestationData memory attestation = _attestations[i];
attest(attestation.about, attestation.key, attestation.val); attest(attestation.about, attestation.key, attestation.val);
......
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Semver } from "../../universal/Semver.sol"; import { Semver } from "../../universal/Semver.sol";
import { import { ERC721BurnableUpgradeable } from
ERC721BurnableUpgradeable "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
import { AttestationStation } from "./AttestationStation.sol"; import { AttestationStation } from "./AttestationStation.sol";
import { OptimistAllowlist } from "./OptimistAllowlist.sol"; import { OptimistAllowlist } from "./OptimistAllowlist.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
...@@ -38,7 +37,9 @@ contract Optimist is ERC721BurnableUpgradeable, Semver { ...@@ -38,7 +37,9 @@ contract Optimist is ERC721BurnableUpgradeable, Semver {
address _baseURIAttestor, address _baseURIAttestor,
AttestationStation _attestationStation, AttestationStation _attestationStation,
OptimistAllowlist _optimistAllowlist OptimistAllowlist _optimistAllowlist
) Semver(2, 0, 1) { )
Semver(2, 0, 1)
{
BASE_URI_ATTESTOR = _baseURIAttestor; BASE_URI_ATTESTOR = _baseURIAttestor;
ATTESTATION_STATION = _attestationStation; ATTESTATION_STATION = _attestationStation;
OPTIMIST_ALLOWLIST = _optimistAllowlist; OPTIMIST_ALLOWLIST = _optimistAllowlist;
...@@ -67,11 +68,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver { ...@@ -67,11 +68,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver {
function baseURI() public view returns (string memory uri_) { function baseURI() public view returns (string memory uri_) {
uri_ = string( uri_ = string(
abi.encodePacked( abi.encodePacked(
ATTESTATION_STATION.attestations( ATTESTATION_STATION.attestations(BASE_URI_ATTESTOR, address(this), bytes32("optimist.base-uri"))
BASE_URI_ATTESTOR,
address(this),
bytes32("optimist.base-uri")
)
) )
); );
} }
...@@ -120,11 +117,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver { ...@@ -120,11 +117,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver {
/// @notice Prevents transfers of the Optimist NFT (Soul Bound Token). /// @notice Prevents transfers of the Optimist NFT (Soul Bound Token).
/// @param _from Address of the token sender. /// @param _from Address of the token sender.
/// @param _to Address of the token recipient. /// @param _to Address of the token recipient.
function _beforeTokenTransfer( function _beforeTokenTransfer(address _from, address _to, uint256) internal virtual override {
address _from,
address _to,
uint256
) internal virtual override {
require(_from == address(0) || _to == address(0), "Optimist: soul bound token"); require(_from == address(0) || _to == address(0), "Optimist: soul bound token");
} }
} }
...@@ -15,8 +15,7 @@ contract OptimistAllowlist is Semver { ...@@ -15,8 +15,7 @@ contract OptimistAllowlist is Semver {
bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32("optimist.can-mint"); bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32("optimist.can-mint");
/// @notice Attestation key used by Coinbase to issue attestations for Quest participants. /// @notice Attestation key used by Coinbase to issue attestations for Quest participants.
bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY = bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY = bytes32("coinbase.quest-eligible");
bytes32("coinbase.quest-eligible");
/// @notice Address of the AttestationStation contract. /// @notice Address of the AttestationStation contract.
AttestationStation public immutable ATTESTATION_STATION; AttestationStation public immutable ATTESTATION_STATION;
...@@ -41,7 +40,9 @@ contract OptimistAllowlist is Semver { ...@@ -41,7 +40,9 @@ contract OptimistAllowlist is Semver {
address _allowlistAttestor, address _allowlistAttestor,
address _coinbaseQuestAttestor, address _coinbaseQuestAttestor,
address _optimistInviter address _optimistInviter
) Semver(1, 0, 1) { )
Semver(1, 0, 1)
{
ATTESTATION_STATION = _attestationStation; ATTESTATION_STATION = _attestationStation;
ALLOWLIST_ATTESTOR = _allowlistAttestor; ALLOWLIST_ATTESTOR = _allowlistAttestor;
COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor; COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor;
...@@ -59,58 +60,34 @@ contract OptimistAllowlist is Semver { ...@@ -59,58 +60,34 @@ contract OptimistAllowlist is Semver {
/// @param _claimer Address to check. /// @param _claimer Address to check.
/// @return allowed_ Whether or not the address is allowed to mint yet. /// @return allowed_ Whether or not the address is allowed to mint yet.
function isAllowedToMint(address _claimer) public view returns (bool allowed_) { function isAllowedToMint(address _claimer) public view returns (bool allowed_) {
allowed_ = allowed_ = _hasAttestationFromAllowlistAttestor(_claimer) || _hasAttestationFromCoinbaseQuestAttestor(_claimer)
_hasAttestationFromAllowlistAttestor(_claimer) || || _hasAttestationFromOptimistInviter(_claimer);
_hasAttestationFromCoinbaseQuestAttestor(_claimer) ||
_hasAttestationFromOptimistInviter(_claimer);
} }
/// @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the /// @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the
/// allowlist attestor. /// allowlist attestor.
/// @param _claimer Address to check. /// @param _claimer Address to check.
/// @return valid_ Whether or not the address has a valid attestation. /// @return valid_ Whether or not the address has a valid attestation.
function _hasAttestationFromAllowlistAttestor(address _claimer) function _hasAttestationFromAllowlistAttestor(address _claimer) internal view returns (bool valid_) {
internal
view
returns (bool valid_)
{
// Expected attestation value is bytes32("true") // Expected attestation value is bytes32("true")
valid_ = _hasValidAttestation( valid_ = _hasValidAttestation(ALLOWLIST_ATTESTOR, _claimer, OPTIMIST_CAN_MINT_ATTESTATION_KEY);
ALLOWLIST_ATTESTOR,
_claimer,
OPTIMIST_CAN_MINT_ATTESTATION_KEY
);
} }
/// @notice Checks whether an address has a valid attestation from the Coinbase attestor. /// @notice Checks whether an address has a valid attestation from the Coinbase attestor.
/// @param _claimer Address to check. /// @param _claimer Address to check.
/// @return valid_ Whether or not the address has a valid attestation. /// @return valid_ Whether or not the address has a valid attestation.
function _hasAttestationFromCoinbaseQuestAttestor(address _claimer) function _hasAttestationFromCoinbaseQuestAttestor(address _claimer) internal view returns (bool valid_) {
internal
view
returns (bool valid_)
{
// Expected attestation value is bytes32("true") // Expected attestation value is bytes32("true")
valid_ = _hasValidAttestation( valid_ = _hasValidAttestation(COINBASE_QUEST_ATTESTOR, _claimer, COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY);
COINBASE_QUEST_ATTESTOR,
_claimer,
COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY
);
} }
/// @notice Checks whether an address has a valid attestation from the OptimistInviter contract. /// @notice Checks whether an address has a valid attestation from the OptimistInviter contract.
/// @param _claimer Address to check. /// @param _claimer Address to check.
/// @return valid_ Whether or not the address has a valid attestation. /// @return valid_ Whether or not the address has a valid attestation.
function _hasAttestationFromOptimistInviter(address _claimer) function _hasAttestationFromOptimistInviter(address _claimer) internal view returns (bool valid_) {
internal
view
returns (bool valid_)
{
// Expected attestation value is the inviter's address // Expected attestation value is the inviter's address
valid_ = _hasValidAttestation( valid_ = _hasValidAttestation(
OPTIMIST_INVITER, OPTIMIST_INVITER, _claimer, OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
_claimer,
OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
); );
} }
...@@ -120,11 +97,7 @@ contract OptimistAllowlist is Semver { ...@@ -120,11 +97,7 @@ contract OptimistAllowlist is Semver {
/// @param _about Address attestation is about. /// @param _about Address attestation is about.
/// @param _key Key of the attestation. /// @param _key Key of the attestation.
/// @return valid_ Whether or not the address has a valid truthy attestation. /// @return valid_ Whether or not the address has a valid truthy attestation.
function _hasValidAttestation( function _hasValidAttestation(address _creator, address _about, bytes32 _key) internal view returns (bool valid_) {
address _creator,
address _about,
bytes32 _key
) internal view returns (bool valid_) {
valid_ = ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0; valid_ = ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0;
} }
} }
...@@ -5,9 +5,7 @@ import { OptimistConstants } from "./libraries/OptimistConstants.sol"; ...@@ -5,9 +5,7 @@ import { OptimistConstants } from "./libraries/OptimistConstants.sol";
import { Semver } from "../../universal/Semver.sol"; import { Semver } from "../../universal/Semver.sol";
import { AttestationStation } from "./AttestationStation.sol"; import { AttestationStation } from "./AttestationStation.sol";
import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import { import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol";
EIP712Upgradeable
} from "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol";
/// @custom:upgradeable /// @custom:upgradeable
/// @title OptimistInviter /// @title OptimistInviter
...@@ -47,8 +45,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable { ...@@ -47,8 +45,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
string public constant EIP712_VERSION = "1.0.0"; string public constant EIP712_VERSION = "1.0.0";
/// @notice EIP712 typehash for the ClaimableInvite type. /// @notice EIP712 typehash for the ClaimableInvite type.
bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
/// @notice Attestation key for that signals that an account was allowed to issue invites /// @notice Attestation key for that signals that an account was allowed to issue invites
bytes32 public constant CAN_INVITE_ATTESTATION_KEY = bytes32("optimist.can-invite"); bytes32 public constant CAN_INVITE_ATTESTATION_KEY = bytes32("optimist.can-invite");
...@@ -113,17 +110,13 @@ contract OptimistInviter is Semver, EIP712Upgradeable { ...@@ -113,17 +110,13 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
/// @param _inviteCount Number of invites to set to. /// @param _inviteCount Number of invites to set to.
function setInviteCounts(address[] calldata _accounts, uint256 _inviteCount) public { function setInviteCounts(address[] calldata _accounts, uint256 _inviteCount) public {
// Only invite granter can grant invites // Only invite granter can grant invites
require( require(msg.sender == INVITE_GRANTER, "OptimistInviter: only invite granter can grant invites");
msg.sender == INVITE_GRANTER,
"OptimistInviter: only invite granter can grant invites"
);
uint256 length = _accounts.length; uint256 length = _accounts.length;
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestations = new AttestationStation.AttestationData[](length);
memory attestations = new AttestationStation.AttestationData[](length);
for (uint256 i; i < length; ) { for (uint256 i; i < length;) {
// Set invite count for account to _inviteCount // Set invite count for account to _inviteCount
inviteCounts[_accounts[i]] = _inviteCount; inviteCounts[_accounts[i]] = _inviteCount;
...@@ -179,20 +172,11 @@ contract OptimistInviter is Semver, EIP712Upgradeable { ...@@ -179,20 +172,11 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
/// @param _claimer Address that will be granted the invite. /// @param _claimer Address that will be granted the invite.
/// @param _claimableInvite ClaimableInvite struct containing the issuer and nonce. /// @param _claimableInvite ClaimableInvite struct containing the issuer and nonce.
/// @param _signature Signature signed over the claimable invite. /// @param _signature Signature signed over the claimable invite.
function claimInvite( function claimInvite(address _claimer, ClaimableInvite calldata _claimableInvite, bytes memory _signature) public {
address _claimer, uint256 commitmentTimestamp = commitmentTimestamps[keccak256(abi.encode(_claimer, _signature))];
ClaimableInvite calldata _claimableInvite,
bytes memory _signature
) public {
uint256 commitmentTimestamp = commitmentTimestamps[
keccak256(abi.encode(_claimer, _signature))
];
// Make sure the claimer and signature have been committed. // Make sure the claimer and signature have been committed.
require( require(commitmentTimestamp > 0, "OptimistInviter: claimer and signature have not been committed yet");
commitmentTimestamp > 0,
"OptimistInviter: claimer and signature have not been committed yet"
);
// Check that MIN_COMMITMENT_PERIOD has passed since the commitment was made. // Check that MIN_COMMITMENT_PERIOD has passed since the commitment was made.
require( require(
...@@ -202,13 +186,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable { ...@@ -202,13 +186,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
// Generate a EIP712 typed data hash to compare against the signature. // Generate a EIP712 typed data hash to compare against the signature.
bytes32 digest = _hashTypedDataV4( bytes32 digest = _hashTypedDataV4(
keccak256( keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce))
abi.encode(
CLAIMABLE_INVITE_TYPEHASH,
_claimableInvite.issuer,
_claimableInvite.nonce
)
)
); );
// Uses SignatureChecker, which supports both regular ECDSA signatures from EOAs as well as // Uses SignatureChecker, which supports both regular ECDSA signatures from EOAs as well as
...@@ -233,10 +211,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable { ...@@ -233,10 +211,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
usedNonces[_claimableInvite.issuer][_claimableInvite.nonce] = true; usedNonces[_claimableInvite.issuer][_claimableInvite.nonce] = true;
// Failing this check means that the issuer has used up all of their existing invites. // Failing this check means that the issuer has used up all of their existing invites.
require( require(inviteCounts[_claimableInvite.issuer] > 0, "OptimistInviter: issuer has no invites");
inviteCounts[_claimableInvite.issuer] > 0,
"OptimistInviter: issuer has no invites"
);
// Reduce the issuer's invite count by 1. Can be unchecked because we check above that // Reduce the issuer's invite count by 1. Can be unchecked because we check above that
// count is > 0. // count is > 0.
......
...@@ -5,6 +5,5 @@ pragma solidity 0.8.15; ...@@ -5,6 +5,5 @@ pragma solidity 0.8.15;
/// @notice Library for storing Optimist related constants that are shared in multiple contracts. /// @notice Library for storing Optimist related constants that are shared in multiple contracts.
library OptimistConstants { library OptimistConstants {
/// @notice Attestation key issued by OptimistInviter allowing the attested account to mint. /// @notice Attestation key issued by OptimistInviter allowing the attested account to mint.
bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY = bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY = bytes32("optimist.can-mint-from-invite");
bytes32("optimist.can-mint-from-invite");
} }
...@@ -149,13 +149,7 @@ abstract contract CrossDomainMessenger is ...@@ -149,13 +149,7 @@ abstract contract CrossDomainMessenger is
/// @param message Message to trigger the recipient address with. /// @param message Message to trigger the recipient address with.
/// @param messageNonce Unique nonce attached to the message. /// @param messageNonce Unique nonce attached to the message.
/// @param gasLimit Minimum gas limit that the message can be executed with. /// @param gasLimit Minimum gas limit that the message can be executed with.
event SentMessage( event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);
address indexed target,
address sender,
bytes message,
uint256 messageNonce,
uint256 gasLimit
);
/// @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the /// @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the
/// SentMessage event without breaking the ABI of this contract, this is good enough. /// SentMessage event without breaking the ABI of this contract, this is good enough.
...@@ -183,11 +177,7 @@ abstract contract CrossDomainMessenger is ...@@ -183,11 +177,7 @@ abstract contract CrossDomainMessenger is
/// @param _target Target contract or wallet address. /// @param _target Target contract or wallet address.
/// @param _message Message to trigger the target address with. /// @param _message Message to trigger the target address with.
/// @param _minGasLimit Minimum gas limit that the message can be executed with. /// @param _minGasLimit Minimum gas limit that the message can be executed with.
function sendMessage( function sendMessage(address _target, bytes calldata _message, uint32 _minGasLimit) external payable {
address _target,
bytes calldata _message,
uint32 _minGasLimit
) external payable {
// Triggers a message to the other messenger. Note that the amount of gas provided to the // Triggers a message to the other messenger. Note that the amount of gas provided to the
// message is the amount of gas requested by the user PLUS the base gas value. We want to // message is the amount of gas requested by the user PLUS the base gas value. We want to
// guarantee the property that the call to the target contract will always have at least // guarantee the property that the call to the target contract will always have at least
...@@ -197,13 +187,7 @@ abstract contract CrossDomainMessenger is ...@@ -197,13 +187,7 @@ abstract contract CrossDomainMessenger is
baseGas(_message, _minGasLimit), baseGas(_message, _minGasLimit),
msg.value, msg.value,
abi.encodeWithSelector( abi.encodeWithSelector(
this.relayMessage.selector, this.relayMessage.selector, messageNonce(), msg.sender, _target, msg.value, _minGasLimit, _message
messageNonce(),
msg.sender,
_target,
msg.value,
_minGasLimit,
_message
) )
); );
...@@ -231,33 +215,24 @@ abstract contract CrossDomainMessenger is ...@@ -231,33 +215,24 @@ abstract contract CrossDomainMessenger is
uint256 _value, uint256 _value,
uint256 _minGasLimit, uint256 _minGasLimit,
bytes calldata _message bytes calldata _message
) external payable { )
external
payable
{
(, uint16 version) = Encoding.decodeVersionedNonce(_nonce); (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
require( require(version < 2, "CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
version < 2,
"CrossDomainMessenger: only version 0 or 1 messages are supported at this time"
);
// If the message is version 0, then it's a migrated legacy withdrawal. We therefore need // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need
// to check that the legacy version of the message has not already been relayed. // to check that the legacy version of the message has not already been relayed.
if (version == 0) { if (version == 0) {
bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce); bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);
require( require(successfulMessages[oldHash] == false, "CrossDomainMessenger: legacy withdrawal already relayed");
successfulMessages[oldHash] == false,
"CrossDomainMessenger: legacy withdrawal already relayed"
);
} }
// We use the v1 message hash as the unique identifier for the message because it commits // We use the v1 message hash as the unique identifier for the message because it commits
// to the value and minimum gas limit of the message. // to the value and minimum gas limit of the message.
bytes32 versionedHash = Hashing.hashCrossDomainMessageV1( bytes32 versionedHash =
_nonce, Hashing.hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _minGasLimit, _message);
_sender,
_target,
_value,
_minGasLimit,
_message
);
if (_isOtherMessenger()) { if (_isOtherMessenger()) {
// These properties should always hold when the message is first submitted (as // These properties should always hold when the message is first submitted (as
...@@ -265,26 +240,16 @@ abstract contract CrossDomainMessenger is ...@@ -265,26 +240,16 @@ abstract contract CrossDomainMessenger is
assert(msg.value == _value); assert(msg.value == _value);
assert(!failedMessages[versionedHash]); assert(!failedMessages[versionedHash]);
} else { } else {
require( require(msg.value == 0, "CrossDomainMessenger: value must be zero unless message is from a system address");
msg.value == 0,
"CrossDomainMessenger: value must be zero unless message is from a system address" require(failedMessages[versionedHash], "CrossDomainMessenger: message cannot be replayed");
);
require(
failedMessages[versionedHash],
"CrossDomainMessenger: message cannot be replayed"
);
} }
require( require(
_isUnsafeTarget(_target) == false, _isUnsafeTarget(_target) == false, "CrossDomainMessenger: cannot send message to blocked system address"
"CrossDomainMessenger: cannot send message to blocked system address"
); );
require( require(successfulMessages[versionedHash] == false, "CrossDomainMessenger: message has already been relayed");
successfulMessages[versionedHash] == false,
"CrossDomainMessenger: message has already been relayed"
);
// If there is not enough gas left to perform the external call and finish the execution, // If there is not enough gas left to perform the external call and finish the execution,
// return early and assign the message to the failedMessages mapping. // return early and assign the message to the failedMessages mapping.
...@@ -296,8 +261,8 @@ abstract contract CrossDomainMessenger is ...@@ -296,8 +261,8 @@ abstract contract CrossDomainMessenger is
// If `xDomainMsgSender` is not the default L2 sender, this function // If `xDomainMsgSender` is not the default L2 sender, this function
// is being re-entered. This marks the message as failed to allow it to be replayed. // is being re-entered. This marks the message as failed to allow it to be replayed.
if ( if (
!SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) || !SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER)
xDomainMsgSender != Constants.DEFAULT_L2_SENDER || xDomainMsgSender != Constants.DEFAULT_L2_SENDER
) { ) {
failedMessages[versionedHash] = true; failedMessages[versionedHash] = true;
emit FailedRelayedMessage(versionedHash); emit FailedRelayedMessage(versionedHash);
...@@ -342,8 +307,7 @@ abstract contract CrossDomainMessenger is ...@@ -342,8 +307,7 @@ abstract contract CrossDomainMessenger is
/// @return Address of the sender of the currently executing message on the other chain. /// @return Address of the sender of the currently executing message on the other chain.
function xDomainMessageSender() external view returns (address) { function xDomainMessageSender() external view returns (address) {
require( require(
xDomainMsgSender != Constants.DEFAULT_L2_SENDER, xDomainMsgSender != Constants.DEFAULT_L2_SENDER, "CrossDomainMessenger: xDomainMessageSender is not set"
"CrossDomainMessenger: xDomainMessageSender is not set"
); );
return xDomainMsgSender; return xDomainMsgSender;
...@@ -366,22 +330,21 @@ abstract contract CrossDomainMessenger is ...@@ -366,22 +330,21 @@ abstract contract CrossDomainMessenger is
/// @return Amount of gas required to guarantee message receipt. /// @return Amount of gas required to guarantee message receipt.
function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) { function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {
return return
// Constant overhead // Constant overhead
RELAY_CONSTANT_OVERHEAD + RELAY_CONSTANT_OVERHEAD
// Calldata overhead // Calldata overhead
(uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) + + (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD)
// Dynamic overhead (EIP-150) // Dynamic overhead (EIP-150)
((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) / + ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) / MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR)
MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) + // Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas
// Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas // factors. (Conservative)
// factors. (Conservative) + RELAY_CALL_OVERHEAD
RELAY_CALL_OVERHEAD + // Relay reserved gas (to ensure execution of `relayMessage` completes after the
// Relay reserved gas (to ensure execution of `relayMessage` completes after the // subcontext finishes executing) (Conservative)
// subcontext finishes executing) (Conservative) + RELAY_RESERVED_GAS
RELAY_RESERVED_GAS + // Gas reserved for the execution between the `hasMinGas` check and the `CALL`
// Gas reserved for the execution between the `hasMinGas` check and the `CALL` // opcode. (Conservative)
// opcode. (Conservative) + RELAY_GAS_CHECK_BUFFER;
RELAY_GAS_CHECK_BUFFER;
} }
/// @notice Initializer. /// @notice Initializer.
...@@ -397,12 +360,7 @@ abstract contract CrossDomainMessenger is ...@@ -397,12 +360,7 @@ abstract contract CrossDomainMessenger is
/// @param _gasLimit Minimum gas limit the message can be executed with. /// @param _gasLimit Minimum gas limit the message can be executed with.
/// @param _value Amount of ETH to send with the message. /// @param _value Amount of ETH to send with the message.
/// @param _data Message data. /// @param _data Message data.
function _sendMessage( function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal virtual;
address _to,
uint64 _gasLimit,
uint256 _value,
bytes memory _data
) internal virtual;
/// @notice Checks whether the message is coming from the other messenger. Implemented by child /// @notice Checks whether the message is coming from the other messenger. Implemented by child
/// contracts because the logic for this depends on the network where the messenger is /// contracts because the logic for this depends on the network where the messenger is
......
...@@ -106,7 +106,9 @@ abstract contract ERC721Bridge is Initializable { ...@@ -106,7 +106,9 @@ abstract contract ERC721Bridge is Initializable {
uint256 _tokenId, uint256 _tokenId,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) external { )
external
{
// Modifier requiring sender to be EOA. This prevents against a user error that would occur // Modifier requiring sender to be EOA. This prevents against a user error that would occur
// if the sender is a smart contract wallet that has a different address on the remote chain // if the sender is a smart contract wallet that has a different address on the remote chain
// (or doesn't have an address on the remote chain at all). The user would fail to receive // (or doesn't have an address on the remote chain at all). The user would fail to receive
...@@ -115,15 +117,7 @@ abstract contract ERC721Bridge is Initializable { ...@@ -115,15 +117,7 @@ abstract contract ERC721Bridge is Initializable {
// care of the user error we want to avoid. // care of the user error we want to avoid.
require(!Address.isContract(msg.sender), "ERC721Bridge: account is not externally owned"); require(!Address.isContract(msg.sender), "ERC721Bridge: account is not externally owned");
_initiateBridgeERC721( _initiateBridgeERC721(_localToken, _remoteToken, msg.sender, msg.sender, _tokenId, _minGasLimit, _extraData);
_localToken,
_remoteToken,
msg.sender,
msg.sender,
_tokenId,
_minGasLimit,
_extraData
);
} }
/// @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note /// @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note
...@@ -148,18 +142,12 @@ abstract contract ERC721Bridge is Initializable { ...@@ -148,18 +142,12 @@ abstract contract ERC721Bridge is Initializable {
uint256 _tokenId, uint256 _tokenId,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) external { )
external
{
require(_to != address(0), "ERC721Bridge: nft recipient cannot be address(0)"); require(_to != address(0), "ERC721Bridge: nft recipient cannot be address(0)");
_initiateBridgeERC721( _initiateBridgeERC721(_localToken, _remoteToken, msg.sender, _to, _tokenId, _minGasLimit, _extraData);
_localToken,
_remoteToken,
msg.sender,
_to,
_tokenId,
_minGasLimit,
_extraData
);
} }
/// @notice Internal function for initiating a token bridge to the other domain. /// @notice Internal function for initiating a token bridge to the other domain.
...@@ -180,5 +168,7 @@ abstract contract ERC721Bridge is Initializable { ...@@ -180,5 +168,7 @@ abstract contract ERC721Bridge is Initializable {
uint256 _tokenId, uint256 _tokenId,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) internal virtual; )
internal
virtual;
} }
...@@ -48,18 +48,14 @@ abstract contract FeeVault { ...@@ -48,18 +48,14 @@ abstract contract FeeVault {
/// @param _recipient Wallet that will receive the fees. /// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals. /// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on. /// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor( constructor(address _recipient, uint256 _minWithdrawalAmount, WithdrawalNetwork _withdrawalNetwork) {
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
) {
RECIPIENT = _recipient; RECIPIENT = _recipient;
MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount; MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;
WITHDRAWAL_NETWORK = _withdrawalNetwork; WITHDRAWAL_NETWORK = _withdrawalNetwork;
} }
/// @notice Allow the contract to receive ETH. /// @notice Allow the contract to receive ETH.
receive() external payable {} receive() external payable { }
/// @notice Triggers a withdrawal of funds to the fee wallet on L1 or L2. /// @notice Triggers a withdrawal of funds to the fee wallet on L1 or L2.
function withdraw() external { function withdraw() external {
...@@ -75,13 +71,11 @@ abstract contract FeeVault { ...@@ -75,13 +71,11 @@ abstract contract FeeVault {
emit Withdrawal(value, RECIPIENT, msg.sender, WITHDRAWAL_NETWORK); emit Withdrawal(value, RECIPIENT, msg.sender, WITHDRAWAL_NETWORK);
if (WITHDRAWAL_NETWORK == WithdrawalNetwork.L2) { if (WITHDRAWAL_NETWORK == WithdrawalNetwork.L2) {
(bool success, ) = RECIPIENT.call{ value: value }(hex""); (bool success,) = RECIPIENT.call{ value: value }(hex"");
require(success, "FeeVault: failed to send ETH to L2 fee recipient"); require(success, "FeeVault: failed to send ETH to L2 fee recipient");
} else { } else {
L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }( L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(
RECIPIENT, RECIPIENT, WITHDRAWAL_MIN_GAS, bytes("")
WITHDRAWAL_MIN_GAS,
bytes("")
); );
} }
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
IERC721Enumerable
} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
/// @title IOptimismMintableERC721 /// @title IOptimismMintableERC721
/// @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard. /// @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.
......
...@@ -45,7 +45,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ...@@ -45,7 +45,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20,
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
string memory _symbol string memory _symbol
) ERC20(_name, _symbol) Semver(1, 0, 2) { )
ERC20(_name, _symbol)
Semver(1, 0, 2)
{
REMOTE_TOKEN = _remoteToken; REMOTE_TOKEN = _remoteToken;
BRIDGE = _bridge; BRIDGE = _bridge;
} }
...@@ -53,7 +56,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ...@@ -53,7 +56,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20,
/// @notice Allows the StandardBridge on this network to mint tokens. /// @notice Allows the StandardBridge on this network to mint tokens.
/// @param _to Address to mint tokens to. /// @param _to Address to mint tokens to.
/// @param _amount Amount of tokens to mint. /// @param _amount Amount of tokens to mint.
function mint(address _to, uint256 _amount) function mint(
address _to,
uint256 _amount
)
external external
virtual virtual
override(IOptimismMintableERC20, ILegacyMintableERC20) override(IOptimismMintableERC20, ILegacyMintableERC20)
...@@ -66,7 +72,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ...@@ -66,7 +72,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20,
/// @notice Allows the StandardBridge on this network to burn tokens. /// @notice Allows the StandardBridge on this network to burn tokens.
/// @param _from Address to burn tokens from. /// @param _from Address to burn tokens from.
/// @param _amount Amount of tokens to burn. /// @param _amount Amount of tokens to burn.
function burn(address _from, uint256 _amount) function burn(
address _from,
uint256 _amount
)
external external
virtual virtual
override(IOptimismMintableERC20, ILegacyMintableERC20) override(IOptimismMintableERC20, ILegacyMintableERC20)
......
...@@ -26,11 +26,7 @@ contract OptimismMintableERC20Factory is Semver { ...@@ -26,11 +26,7 @@ contract OptimismMintableERC20Factory is Semver {
/// @param localToken Address of the created token on the local chain. /// @param localToken Address of the created token on the local chain.
/// @param remoteToken Address of the corresponding token on the remote chain. /// @param remoteToken Address of the corresponding token on the remote chain.
/// @param deployer Address of the account that deployed the token. /// @param deployer Address of the account that deployed the token.
event OptimismMintableERC20Created( event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
address indexed localToken,
address indexed remoteToken,
address deployer
);
/// @custom:semver 1.1.1 /// @custom:semver 1.1.1
/// @notice The semver MUST be bumped any time that there is a change in /// @notice The semver MUST be bumped any time that there is a change in
...@@ -52,7 +48,10 @@ contract OptimismMintableERC20Factory is Semver { ...@@ -52,7 +48,10 @@ contract OptimismMintableERC20Factory is Semver {
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
string memory _symbol string memory _symbol
) external returns (address) { )
external
returns (address)
{
return createOptimismMintableERC20(_remoteToken, _name, _symbol); return createOptimismMintableERC20(_remoteToken, _name, _symbol);
} }
...@@ -65,15 +64,13 @@ contract OptimismMintableERC20Factory is Semver { ...@@ -65,15 +64,13 @@ contract OptimismMintableERC20Factory is Semver {
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
string memory _symbol string memory _symbol
) public returns (address) { )
require( public
_remoteToken != address(0), returns (address)
"OptimismMintableERC20Factory: must provide remote token address" {
); require(_remoteToken != address(0), "OptimismMintableERC20Factory: must provide remote token address");
address localToken = address( address localToken = address(new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol));
new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)
);
// Emit the old event too for legacy support. // Emit the old event too for legacy support.
emit StandardL2TokenCreated(_remoteToken, localToken); emit StandardL2TokenCreated(_remoteToken, localToken);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
ERC721Enumerable
} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
...@@ -45,13 +43,13 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Se ...@@ -45,13 +43,13 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Se
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
string memory _symbol string memory _symbol
) ERC721(_name, _symbol) Semver(1, 1, 1) { )
ERC721(_name, _symbol)
Semver(1, 1, 1)
{
require(_bridge != address(0), "OptimismMintableERC721: bridge cannot be address(0)"); require(_bridge != address(0), "OptimismMintableERC721: bridge cannot be address(0)");
require(_remoteChainId != 0, "OptimismMintableERC721: remote chain id cannot be zero"); require(_remoteChainId != 0, "OptimismMintableERC721: remote chain id cannot be zero");
require( require(_remoteToken != address(0), "OptimismMintableERC721: remote token cannot be address(0)");
_remoteToken != address(0),
"OptimismMintableERC721: remote token cannot be address(0)"
);
REMOTE_CHAIN_ID = _remoteChainId; REMOTE_CHAIN_ID = _remoteChainId;
REMOTE_TOKEN = _remoteToken; REMOTE_TOKEN = _remoteToken;
...@@ -102,12 +100,7 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Se ...@@ -102,12 +100,7 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Se
/// @notice Checks if a given interface ID is supported by this contract. /// @notice Checks if a given interface ID is supported by this contract.
/// @param _interfaceId The interface ID to check. /// @param _interfaceId The interface ID to check.
/// @return True if the interface ID is supported, false otherwise. /// @return True if the interface ID is supported, false otherwise.
function supportsInterface(bytes4 _interfaceId) function supportsInterface(bytes4 _interfaceId) public view override(ERC721Enumerable, IERC165) returns (bool) {
public
view
override(ERC721Enumerable, IERC165)
returns (bool)
{
bytes4 iface = type(IOptimismMintableERC721).interfaceId; bytes4 iface = type(IOptimismMintableERC721).interfaceId;
return _interfaceId == iface || super.supportsInterface(_interfaceId); return _interfaceId == iface || super.supportsInterface(_interfaceId);
} }
......
...@@ -20,11 +20,7 @@ contract OptimismMintableERC721Factory is Semver { ...@@ -20,11 +20,7 @@ contract OptimismMintableERC721Factory is Semver {
/// @param localToken Address of the token on the this domain. /// @param localToken Address of the token on the this domain.
/// @param remoteToken Address of the token on the remote domain. /// @param remoteToken Address of the token on the remote domain.
/// @param deployer Address of the initiator of the deployment /// @param deployer Address of the initiator of the deployment
event OptimismMintableERC721Created( event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
address indexed localToken,
address indexed remoteToken,
address deployer
);
/// @custom:semver 1.2.1 /// @custom:semver 1.2.1
/// @notice The semver MUST be bumped any time that there is a change in /// @notice The semver MUST be bumped any time that there is a change in
...@@ -45,15 +41,13 @@ contract OptimismMintableERC721Factory is Semver { ...@@ -45,15 +41,13 @@ contract OptimismMintableERC721Factory is Semver {
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
string memory _symbol string memory _symbol
) external returns (address) { )
require( external
_remoteToken != address(0), returns (address)
"OptimismMintableERC721Factory: L1 token address cannot be address(0)" {
); require(_remoteToken != address(0), "OptimismMintableERC721Factory: L1 token address cannot be address(0)");
address localToken = address( address localToken = address(new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol));
new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)
);
isOptimismMintableERC721[localToken] = true; isOptimismMintableERC721[localToken] = true;
emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender); emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);
......
...@@ -8,13 +8,11 @@ pragma solidity 0.8.15; ...@@ -8,13 +8,11 @@ pragma solidity 0.8.15;
contract Proxy { contract Proxy {
/// @notice The storage slot that holds the address of the implementation. /// @notice The storage slot that holds the address of the implementation.
/// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) /// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
bytes32 internal constant IMPLEMENTATION_KEY = bytes32 internal constant IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/// @notice The storage slot that holds the address of the owner. /// @notice The storage slot that holds the address of the owner.
/// bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) /// bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
bytes32 internal constant OWNER_KEY = bytes32 internal constant OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/// @notice An event that is emitted each time the implementation is changed. This event is part /// @notice An event that is emitted each time the implementation is changed. This event is part
/// of the EIP-1967 specification. /// of the EIP-1967 specification.
...@@ -72,7 +70,10 @@ contract Proxy { ...@@ -72,7 +70,10 @@ contract Proxy {
/// atomic execution of initialization-based upgrades. /// atomic execution of initialization-based upgrades.
/// @param _implementation Address of the implementation contract. /// @param _implementation Address of the implementation contract.
/// @param _data Calldata to delegatecall the new implementation with. /// @param _data Calldata to delegatecall the new implementation with.
function upgradeToAndCall(address _implementation, bytes calldata _data) function upgradeToAndCall(
address _implementation,
bytes calldata _data
)
public public
payable payable
virtual virtual
...@@ -140,9 +141,7 @@ contract Proxy { ...@@ -140,9 +141,7 @@ contract Proxy {
returndatacopy(0x0, 0x0, returndatasize()) returndatacopy(0x0, 0x0, returndatasize())
// Success == 0 means a revert. We'll revert too and pass the data up. // Success == 0 means a revert. We'll revert too and pass the data up.
if iszero(success) { if iszero(success) { revert(0x0, returndatasize()) }
revert(0x0, returndatasize())
}
// Otherwise we'll just return and pass the data up. // Otherwise we'll just return and pass the data up.
return(0x0, returndatasize()) return(0x0, returndatasize())
......
...@@ -186,14 +186,18 @@ contract ProxyAdmin is Ownable { ...@@ -186,14 +186,18 @@ contract ProxyAdmin is Ownable {
address payable _proxy, address payable _proxy,
address _implementation, address _implementation,
bytes memory _data bytes memory _data
) external payable onlyOwner { )
external
payable
onlyOwner
{
ProxyType ptype = proxyType[_proxy]; ProxyType ptype = proxyType[_proxy];
if (ptype == ProxyType.ERC1967) { if (ptype == ProxyType.ERC1967) {
Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data); Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);
} else { } else {
// reverts if proxy type is unknown // reverts if proxy type is unknown
upgrade(_proxy, _implementation); upgrade(_proxy, _implementation);
(bool success, ) = _proxy.call{ value: msg.value }(_data); (bool success,) = _proxy.call{ value: msg.value }(_data);
require(success, "ProxyAdmin: call to proxy after upgrade failed"); require(success, "ProxyAdmin: call to proxy after upgrade failed");
} }
} }
......
...@@ -18,11 +18,7 @@ contract Semver { ...@@ -18,11 +18,7 @@ contract Semver {
/// @param _major Version number (major). /// @param _major Version number (major).
/// @param _minor Version number (minor). /// @param _minor Version number (minor).
/// @param _patch Version number (patch). /// @param _patch Version number (patch).
constructor( constructor(uint256 _major, uint256 _minor, uint256 _patch) {
uint256 _major,
uint256 _minor,
uint256 _patch
) {
MAJOR_VERSION = _major; MAJOR_VERSION = _major;
MINOR_VERSION = _minor; MINOR_VERSION = _minor;
PATCH_VERSION = _patch; PATCH_VERSION = _patch;
...@@ -31,15 +27,14 @@ contract Semver { ...@@ -31,15 +27,14 @@ contract Semver {
/// @notice Returns the full semver contract version. /// @notice Returns the full semver contract version.
/// @return Semver contract version as a string. /// @return Semver contract version as a string.
function version() public view returns (string memory) { function version() public view returns (string memory) {
return return string(
string( abi.encodePacked(
abi.encodePacked( Strings.toString(MAJOR_VERSION),
Strings.toString(MAJOR_VERSION), ".",
".", Strings.toString(MINOR_VERSION),
Strings.toString(MINOR_VERSION), ".",
".", Strings.toString(PATCH_VERSION)
Strings.toString(PATCH_VERSION) )
) );
);
} }
} }
...@@ -56,24 +56,14 @@ abstract contract StandardBridge is Initializable { ...@@ -56,24 +56,14 @@ abstract contract StandardBridge is Initializable {
/// @param to Address of the receiver. /// @param to Address of the receiver.
/// @param amount Amount of ETH sent. /// @param amount Amount of ETH sent.
/// @param extraData Extra data sent with the transaction. /// @param extraData Extra data sent with the transaction.
event ETHBridgeInitiated( event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
/// @notice Emitted when an ETH bridge is finalized on this chain. /// @notice Emitted when an ETH bridge is finalized on this chain.
/// @param from Address of the sender. /// @param from Address of the sender.
/// @param to Address of the receiver. /// @param to Address of the receiver.
/// @param amount Amount of ETH sent. /// @param amount Amount of ETH sent.
/// @param extraData Extra data sent with the transaction. /// @param extraData Extra data sent with the transaction.
event ETHBridgeFinalized( event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
/// @notice Emitted when an ERC20 bridge is initiated to the other chain. /// @notice Emitted when an ERC20 bridge is initiated to the other chain.
/// @param localToken Address of the ERC20 on this chain. /// @param localToken Address of the ERC20 on this chain.
...@@ -111,18 +101,14 @@ abstract contract StandardBridge is Initializable { ...@@ -111,18 +101,14 @@ abstract contract StandardBridge is Initializable {
/// calling code within their constructors, but also doesn't really matter since we're /// calling code within their constructors, but also doesn't really matter since we're
/// just trying to prevent users accidentally depositing with smart contract wallets. /// just trying to prevent users accidentally depositing with smart contract wallets.
modifier onlyEOA() { modifier onlyEOA() {
require( require(!Address.isContract(msg.sender), "StandardBridge: function can only be called from an EOA");
!Address.isContract(msg.sender),
"StandardBridge: function can only be called from an EOA"
);
_; _;
} }
/// @notice Ensures that the caller is a cross-chain message from the other bridge. /// @notice Ensures that the caller is a cross-chain message from the other bridge.
modifier onlyOtherBridge() { modifier onlyOtherBridge() {
require( require(
msg.sender == address(messenger) && msg.sender == address(messenger) && messenger.xDomainMessageSender() == address(OTHER_BRIDGE),
messenger.xDomainMessageSender() == address(OTHER_BRIDGE),
"StandardBridge: function can only be called from the other bridge" "StandardBridge: function can only be called from the other bridge"
); );
_; _;
...@@ -177,11 +163,7 @@ abstract contract StandardBridge is Initializable { ...@@ -177,11 +163,7 @@ abstract contract StandardBridge is Initializable {
/// @param _extraData Extra data to be sent with the transaction. Note that the recipient will /// @param _extraData Extra data to be sent with the transaction. Note that the recipient will
/// not be triggered with this data, but it will be emitted and can be used /// not be triggered with this data, but it will be emitted and can be used
/// to identify the transaction. /// to identify the transaction.
function bridgeETHTo( function bridgeETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) public payable {
address _to,
uint32 _minGasLimit,
bytes calldata _extraData
) public payable {
_initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData); _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);
} }
...@@ -202,16 +184,12 @@ abstract contract StandardBridge is Initializable { ...@@ -202,16 +184,12 @@ abstract contract StandardBridge is Initializable {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) public virtual onlyEOA { )
_initiateBridgeERC20( public
_localToken, virtual
_remoteToken, onlyEOA
msg.sender, {
msg.sender, _initiateBridgeERC20(_localToken, _remoteToken, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
_amount,
_minGasLimit,
_extraData
);
} }
/// @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the /// @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the
...@@ -233,16 +211,11 @@ abstract contract StandardBridge is Initializable { ...@@ -233,16 +211,11 @@ abstract contract StandardBridge is Initializable {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes calldata _extraData bytes calldata _extraData
) public virtual { )
_initiateBridgeERC20( public
_localToken, virtual
_remoteToken, {
msg.sender, _initiateBridgeERC20(_localToken, _remoteToken, msg.sender, _to, _amount, _minGasLimit, _extraData);
_to,
_amount,
_minGasLimit,
_extraData
);
} }
/// @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other /// @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other
...@@ -258,7 +231,11 @@ abstract contract StandardBridge is Initializable { ...@@ -258,7 +231,11 @@ abstract contract StandardBridge is Initializable {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes calldata _extraData bytes calldata _extraData
) public payable onlyOtherBridge { )
public
payable
onlyOtherBridge
{
require(msg.value == _amount, "StandardBridge: amount sent does not match amount required"); require(msg.value == _amount, "StandardBridge: amount sent does not match amount required");
require(_to != address(this), "StandardBridge: cannot send to self"); require(_to != address(this), "StandardBridge: cannot send to self");
require(_to != address(messenger), "StandardBridge: cannot send to messenger"); require(_to != address(messenger), "StandardBridge: cannot send to messenger");
...@@ -288,7 +265,10 @@ abstract contract StandardBridge is Initializable { ...@@ -288,7 +265,10 @@ abstract contract StandardBridge is Initializable {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes calldata _extraData bytes calldata _extraData
) public onlyOtherBridge { )
public
onlyOtherBridge
{
if (_isOptimismMintableERC20(_localToken)) { if (_isOptimismMintableERC20(_localToken)) {
require( require(
_isCorrectTokenPair(_localToken, _remoteToken), _isCorrectTokenPair(_localToken, _remoteToken),
...@@ -320,11 +300,10 @@ abstract contract StandardBridge is Initializable { ...@@ -320,11 +300,10 @@ abstract contract StandardBridge is Initializable {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes memory _extraData bytes memory _extraData
) internal { )
require( internal
msg.value == _amount, {
"StandardBridge: bridging ETH must include sufficient ETH value" require(msg.value == _amount, "StandardBridge: bridging ETH must include sufficient ETH value");
);
// Emit the correct events. By default this will be _amount, but child // Emit the correct events. By default this will be _amount, but child
// contracts may override this function in order to emit legacy events as well. // contracts may override this function in order to emit legacy events as well.
...@@ -332,13 +311,7 @@ abstract contract StandardBridge is Initializable { ...@@ -332,13 +311,7 @@ abstract contract StandardBridge is Initializable {
messenger.sendMessage{ value: _amount }( messenger.sendMessage{ value: _amount }(
address(OTHER_BRIDGE), address(OTHER_BRIDGE),
abi.encodeWithSelector( abi.encodeWithSelector(this.finalizeBridgeETH.selector, _from, _to, _amount, _extraData),
this.finalizeBridgeETH.selector,
_from,
_to,
_amount,
_extraData
),
_minGasLimit _minGasLimit
); );
} }
...@@ -360,7 +333,9 @@ abstract contract StandardBridge is Initializable { ...@@ -360,7 +333,9 @@ abstract contract StandardBridge is Initializable {
uint256 _amount, uint256 _amount,
uint32 _minGasLimit, uint32 _minGasLimit,
bytes memory _extraData bytes memory _extraData
) internal { )
internal
{
if (_isOptimismMintableERC20(_localToken)) { if (_isOptimismMintableERC20(_localToken)) {
require( require(
_isCorrectTokenPair(_localToken, _remoteToken), _isCorrectTokenPair(_localToken, _remoteToken),
...@@ -400,9 +375,8 @@ abstract contract StandardBridge is Initializable { ...@@ -400,9 +375,8 @@ abstract contract StandardBridge is Initializable {
/// @param _token Address of the token to check. /// @param _token Address of the token to check.
/// @return True if the token is an OptimismMintableERC20. /// @return True if the token is an OptimismMintableERC20.
function _isOptimismMintableERC20(address _token) internal view returns (bool) { function _isOptimismMintableERC20(address _token) internal view returns (bool) {
return return ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId)
ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) || || ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);
ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);
} }
/// @notice Checks if the "other token" is the correct pair token for the OptimismMintableERC20. /// @notice Checks if the "other token" is the correct pair token for the OptimismMintableERC20.
...@@ -411,14 +385,8 @@ abstract contract StandardBridge is Initializable { ...@@ -411,14 +385,8 @@ abstract contract StandardBridge is Initializable {
/// @param _mintableToken OptimismMintableERC20 to check against. /// @param _mintableToken OptimismMintableERC20 to check against.
/// @param _otherToken Pair token to check. /// @param _otherToken Pair token to check.
/// @return True if the other token is the correct pair token for the OptimismMintableERC20. /// @return True if the other token is the correct pair token for the OptimismMintableERC20.
function _isCorrectTokenPair(address _mintableToken, address _otherToken) function _isCorrectTokenPair(address _mintableToken, address _otherToken) internal view returns (bool) {
internal if (ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)) {
view
returns (bool)
{
if (
ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)
) {
return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token(); return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();
} else { } else {
return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken(); return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();
...@@ -436,7 +404,10 @@ abstract contract StandardBridge is Initializable { ...@@ -436,7 +404,10 @@ abstract contract StandardBridge is Initializable {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal virtual { )
internal
virtual
{
emit ETHBridgeInitiated(_from, _to, _amount, _extraData); emit ETHBridgeInitiated(_from, _to, _amount, _extraData);
} }
...@@ -451,7 +422,10 @@ abstract contract StandardBridge is Initializable { ...@@ -451,7 +422,10 @@ abstract contract StandardBridge is Initializable {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal virtual { )
internal
virtual
{
emit ETHBridgeFinalized(_from, _to, _amount, _extraData); emit ETHBridgeFinalized(_from, _to, _amount, _extraData);
} }
...@@ -470,7 +444,10 @@ abstract contract StandardBridge is Initializable { ...@@ -470,7 +444,10 @@ abstract contract StandardBridge is Initializable {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal virtual { )
internal
virtual
{
emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData); emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
} }
...@@ -489,7 +466,10 @@ abstract contract StandardBridge is Initializable { ...@@ -489,7 +466,10 @@ abstract contract StandardBridge is Initializable {
address _to, address _to,
uint256 _amount, uint256 _amount,
bytes memory _extraData bytes memory _extraData
) internal virtual { )
internal
virtual
{
emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData); emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
} }
} }
...@@ -16,53 +16,52 @@ ...@@ -16,53 +16,52 @@
pragma solidity >=0.4.22 <0.6; pragma solidity >=0.4.22 <0.6;
contract WETH9 { contract WETH9 {
string public name = "Wrapped Ether"; string public name = "Wrapped Ether";
string public symbol = "WETH"; string public symbol = "WETH";
uint8 public decimals = 18; uint8 public decimals = 18;
event Approval(address indexed src, address indexed guy, uint wad); event Approval(address indexed src, address indexed guy, uint256 wad);
event Transfer(address indexed src, address indexed dst, uint wad); event Transfer(address indexed src, address indexed dst, uint256 wad);
event Deposit(address indexed dst, uint wad); event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint wad); event Withdrawal(address indexed src, uint256 wad);
mapping (address => uint) public balanceOf; mapping(address => uint256) public balanceOf;
mapping (address => mapping (address => uint)) public allowance; mapping(address => mapping(address => uint256)) public allowance;
function() external payable { function() external payable {
deposit(); deposit();
} }
function deposit() public payable { function deposit() public payable {
balanceOf[msg.sender] += msg.value; balanceOf[msg.sender] += msg.value;
emit Deposit(msg.sender, msg.value); emit Deposit(msg.sender, msg.value);
} }
function withdraw(uint wad) public {
function withdraw(uint256 wad) public {
require(balanceOf[msg.sender] >= wad); require(balanceOf[msg.sender] >= wad);
balanceOf[msg.sender] -= wad; balanceOf[msg.sender] -= wad;
msg.sender.transfer(wad); msg.sender.transfer(wad);
emit Withdrawal(msg.sender, wad); emit Withdrawal(msg.sender, wad);
} }
function totalSupply() public view returns (uint) { function totalSupply() public view returns (uint256) {
return address(this).balance; return address(this).balance;
} }
function approve(address guy, uint wad) public returns (bool) { function approve(address guy, uint256 wad) public returns (bool) {
allowance[msg.sender][guy] = wad; allowance[msg.sender][guy] = wad;
emit Approval(msg.sender, guy, wad); emit Approval(msg.sender, guy, wad);
return true; return true;
} }
function transfer(address dst, uint wad) public returns (bool) { function transfer(address dst, uint256 wad) public returns (bool) {
return transferFrom(msg.sender, dst, wad); return transferFrom(msg.sender, dst, wad);
} }
function transferFrom(address src, address dst, uint wad) function transferFrom(address src, address dst, uint256 wad) public returns (bool) {
public
returns (bool)
{
require(balanceOf[src] >= wad); require(balanceOf[src] >= wad);
if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { if (src != msg.sender && allowance[src][msg.sender] != uint256(-1)) {
require(allowance[src][msg.sender] >= wad); require(allowance[src][msg.sender] >= wad);
allowance[src][msg.sender] -= wad; allowance[src][msg.sender] -= wad;
} }
...@@ -76,7 +75,6 @@ contract WETH9 { ...@@ -76,7 +75,6 @@ contract WETH9 {
} }
} }
/* /*
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
......
...@@ -45,11 +45,7 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -45,11 +45,7 @@ contract AdminFaucetAuthModuleTest is Test {
} }
/// @notice Get signature as a bytes blob. /// @notice Get signature as a bytes blob.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
internal
pure
returns (bytes memory)
{
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest); (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v); bytes memory signature = abi.encodePacked(r, s, v);
...@@ -68,23 +64,18 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -68,23 +64,18 @@ contract AdminFaucetAuthModuleTest is Test {
address recipient, address recipient,
bytes32 id, bytes32 id,
bytes32 nonce bytes32 nonce
) internal view returns (bytes memory) { )
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof( internal
recipient, view
nonce, returns (bytes memory)
id {
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(recipient, nonce, id);
return _getSignature(
_issuerPrivateKey,
faucetHelper.getDigestWithEIP712Domain(
proof, _eip712Name, _contractVersion, _eip712Chainid, _eip712VerifyingContract
)
); );
return
_getSignature(
_issuerPrivateKey,
faucetHelper.getDigestWithEIP712Domain(
proof,
_eip712Name,
_contractVersion,
_eip712Chainid,
_eip712VerifyingContract
)
);
} }
/// @notice Assert that verify returns true for valid proofs signed by admins. /// @notice Assert that verify returns true for valid proofs signed by admins.
...@@ -105,9 +96,7 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -105,9 +96,7 @@ contract AdminFaucetAuthModuleTest is Test {
vm.prank(nonAdmin); vm.prank(nonAdmin);
assertEq( assertEq(
adminFam.verify( adminFam.verify(
Faucet.DripParameters(payable(fundsReceiver), nonce), Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(fundsReceiver)), proof
keccak256(abi.encodePacked(fundsReceiver)),
proof
), ),
true true
); );
...@@ -131,9 +120,7 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -131,9 +120,7 @@ contract AdminFaucetAuthModuleTest is Test {
vm.prank(admin); vm.prank(admin);
assertEq( assertEq(
adminFam.verify( adminFam.verify(
Faucet.DripParameters(payable(fundsReceiver), nonce), Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(fundsReceiver)), proof
keccak256(abi.encodePacked(fundsReceiver)),
proof
), ),
false false
); );
...@@ -159,9 +146,7 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -159,9 +146,7 @@ contract AdminFaucetAuthModuleTest is Test {
vm.prank(admin); vm.prank(admin);
assertEq( assertEq(
adminFam.verify( adminFam.verify(
Faucet.DripParameters(payable(fundsReceiver), nonce), Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(randomAddress)), proof
keccak256(abi.encodePacked(randomAddress)),
proof
), ),
false false
); );
......
...@@ -19,18 +19,8 @@ contract AssetReceiver_Initializer is Test { ...@@ -19,18 +19,8 @@ contract AssetReceiver_Initializer is Test {
event ReceivedETH(address indexed from, uint256 amount); event ReceivedETH(address indexed from, uint256 amount);
event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount); event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);
event WithdrewERC20( event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount);
address indexed withdrawer, event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id);
address indexed recipient,
address indexed asset,
uint256 amount
);
event WithdrewERC721(
address indexed withdrawer,
address indexed recipient,
address indexed asset,
uint256 id
);
function setUp() public { function setUp() public {
// Deploy ERC20 and ERC721 tokens // Deploy ERC20 and ERC721 tokens
...@@ -67,7 +57,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { ...@@ -67,7 +57,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
emit ReceivedETH(alice, 100); emit ReceivedETH(alice, 100);
// Send funds // Send funds
vm.prank(alice); vm.prank(alice);
(bool success, ) = address(assetReceiver).call{ value: 100 }(hex""); (bool success,) = address(assetReceiver).call{ value: 100 }(hex"");
// Compare balance after the tx sent // Compare balance after the tx sent
assertTrue(success); assertTrue(success);
......
...@@ -21,12 +21,7 @@ contract AttestationStation_Initializer is Test { ...@@ -21,12 +21,7 @@ contract AttestationStation_Initializer is Test {
} }
contract AttestationStationTest is AttestationStation_Initializer { contract AttestationStationTest is AttestationStation_Initializer {
event AttestationCreated( event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
function test_attest_individual_succeeds() external { function test_attest_individual_succeeds() external {
AttestationStation attestationStation = new AttestationStation(); AttestationStation attestationStation = new AttestationStation();
...@@ -41,26 +36,17 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -41,26 +36,17 @@ contract AttestationStationTest is AttestationStation_Initializer {
function test_attest_single_succeeds() external { function test_attest_single_succeeds() external {
AttestationStation attestationStation = new AttestationStation(); AttestationStation attestationStation = new AttestationStation();
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestationDataArr = new AttestationStation.AttestationData[](1);
memory attestationDataArr = new AttestationStation.AttestationData[](1);
// alice is going to attest about bob // alice is going to attest about bob
AttestationStation.AttestationData memory attestationData = AttestationStation AttestationStation.AttestationData memory attestationData = AttestationStation.AttestationData({
.AttestationData({ about: bob,
about: bob, key: bytes32("test-key:string"),
key: bytes32("test-key:string"), val: bytes("test-value")
val: bytes("test-value") });
});
// assert the attestation starts empty // assert the attestation starts empty
assertEq( assertEq(attestationStation.attestations(alice_attestor, attestationData.about, attestationData.key), "");
attestationStation.attestations(
alice_attestor,
attestationData.about,
attestationData.key
),
""
);
// make attestation // make attestation
vm.prank(alice_attestor); vm.prank(alice_attestor);
...@@ -69,21 +55,14 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -69,21 +55,14 @@ contract AttestationStationTest is AttestationStation_Initializer {
// assert the attestation is there // assert the attestation is there
assertEq( assertEq(
attestationStation.attestations( attestationStation.attestations(alice_attestor, attestationData.about, attestationData.key),
alice_attestor,
attestationData.about,
attestationData.key
),
attestationData.val attestationData.val
); );
bytes memory new_val = bytes("new updated value"); bytes memory new_val = bytes("new updated value");
// make a new attestations to same about and key // make a new attestations to same about and key
attestationData = AttestationStation.AttestationData({ attestationData =
about: attestationData.about, AttestationStation.AttestationData({ about: attestationData.about, key: attestationData.key, val: new_val });
key: attestationData.key,
val: new_val
});
vm.prank(alice_attestor); vm.prank(alice_attestor);
attestationDataArr[0] = attestationData; attestationDataArr[0] = attestationData;
...@@ -91,11 +70,7 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -91,11 +70,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
// assert the attestation is updated // assert the attestation is updated
assertEq( assertEq(
attestationStation.attestations( attestationStation.attestations(alice_attestor, attestationData.about, attestationData.key),
alice_attestor,
attestationData.about,
attestationData.key
),
attestationData.val attestationData.val
); );
} }
...@@ -105,19 +80,15 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -105,19 +80,15 @@ contract AttestationStationTest is AttestationStation_Initializer {
vm.prank(alice_attestor); vm.prank(alice_attestor);
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](3);
memory attestationData = new AttestationStation.AttestationData[](3);
attestationData[0] = AttestationStation.AttestationData({ attestationData[0] = AttestationStation.AttestationData({
about: bob, about: bob,
key: bytes32("test-key:string"), key: bytes32("test-key:string"),
val: bytes("test-value") val: bytes("test-value")
}); });
attestationData[1] = AttestationStation.AttestationData({ attestationData[1] =
about: bob, AttestationStation.AttestationData({ about: bob, key: bytes32("test-key2"), val: bytes("test-value2") });
key: bytes32("test-key2"),
val: bytes("test-value2")
});
attestationData[2] = AttestationStation.AttestationData({ attestationData[2] = AttestationStation.AttestationData({
about: sally, about: sally,
...@@ -129,27 +100,15 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -129,27 +100,15 @@ contract AttestationStationTest is AttestationStation_Initializer {
// assert the attestations are there // assert the attestations are there
assertEq( assertEq(
attestationStation.attestations( attestationStation.attestations(alice_attestor, attestationData[0].about, attestationData[0].key),
alice_attestor,
attestationData[0].about,
attestationData[0].key
),
attestationData[0].val attestationData[0].val
); );
assertEq( assertEq(
attestationStation.attestations( attestationStation.attestations(alice_attestor, attestationData[1].about, attestationData[1].key),
alice_attestor,
attestationData[1].about,
attestationData[1].key
),
attestationData[1].val attestationData[1].val
); );
assertEq( assertEq(
attestationStation.attestations( attestationStation.attestations(alice_attestor, attestationData[2].about, attestationData[2].key),
alice_attestor,
attestationData[2].about,
attestationData[2].key
),
attestationData[2].val attestationData[2].val
); );
} }
......
...@@ -9,18 +9,14 @@ import { CrossDomainMessenger } from "../src/universal/CrossDomainMessenger.sol" ...@@ -9,18 +9,14 @@ import { CrossDomainMessenger } from "../src/universal/CrossDomainMessenger.sol"
import { ResourceMetering } from "../src/L1/ResourceMetering.sol"; import { ResourceMetering } from "../src/L1/ResourceMetering.sol";
// Free function for setting the prevBaseFee param in the OptimismPortal. // Free function for setting the prevBaseFee param in the OptimismPortal.
function setPrevBaseFee( function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) {
Vm _vm,
address _op,
uint128 _prevBaseFee
) {
_vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee)); _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));
} }
contract SetPrevBaseFee_Test is Portal_Initializer { contract SetPrevBaseFee_Test is Portal_Initializer {
function test_setPrevBaseFee_succeeds() external { function test_setPrevBaseFee_succeeds() external {
setPrevBaseFee(vm, address(op), 100 gwei); setPrevBaseFee(vm, address(op), 100 gwei);
(uint128 prevBaseFee, , uint64 prevBlockNum) = op.params(); (uint128 prevBaseFee,, uint64 prevBlockNum) = op.params();
assertEq(uint256(prevBaseFee), 100 gwei); assertEq(uint256(prevBaseFee), 100 gwei);
assertEq(uint256(prevBlockNum), block.number); assertEq(uint256(prevBlockNum), block.number);
} }
...@@ -56,8 +52,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { ...@@ -56,8 +52,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
// Get withdrawal proof data we can use for testing. // Get withdrawal proof data we can use for testing.
bytes32 _storageRoot; bytes32 _storageRoot;
bytes32 _stateRoot; bytes32 _stateRoot;
(_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi (_stateRoot, _storageRoot, _outputRoot,, _withdrawalProof) = ffi.getProveWithdrawalTransactionInputs(_defaultTx);
.getProveWithdrawalTransactionInputs(_defaultTx);
// Setup a dummy output root proof for reuse. // Setup a dummy output root proof for reuse.
_outputRootProof = Types.OutputRootProof({ _outputRootProof = Types.OutputRootProof({
...@@ -78,11 +73,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { ...@@ -78,11 +73,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp( vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
oracle.getL2Output(_proposedOutputIndex).timestamp +
oracle.FINALIZATION_PERIOD_SECONDS() +
1
);
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF); vm.deal(address(op), 0xFFFFFFFF);
...@@ -90,32 +81,19 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { ...@@ -90,32 +81,19 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
function test_depositTransaction_benchmark() external { function test_depositTransaction_benchmark() external {
op.depositTransaction{ value: NON_ZERO_VALUE }( op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
); );
} }
function test_depositTransaction_benchmark_1() external { function test_depositTransaction_benchmark_1() external {
setPrevBaseFee(vm, address(op), 1 gwei); setPrevBaseFee(vm, address(op), 1 gwei);
op.depositTransaction{ value: NON_ZERO_VALUE }( op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
); );
} }
function test_proveWithdrawalTransaction_benchmark() external { function test_proveWithdrawalTransaction_benchmark() external {
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
} }
} }
...@@ -124,8 +102,8 @@ contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer { ...@@ -124,8 +102,8 @@ contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 1 gwei); setPrevBaseFee(vm, address(op), 1 gwei);
// The amount of data typically sent during a bridge deposit. // The amount of data typically sent during a bridge deposit.
bytes bytes memory data =
memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Messenger.sendMessage(bob, data, uint32(100)); L1Messenger.sendMessage(bob, data, uint32(100));
} }
...@@ -134,8 +112,8 @@ contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer { ...@@ -134,8 +112,8 @@ contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 10 gwei); setPrevBaseFee(vm, address(op), 10 gwei);
// The amount of data typically sent during a bridge deposit. // The amount of data typically sent during a bridge deposit.
bytes bytes memory data =
memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Messenger.sendMessage(bob, data, uint32(100)); L1Messenger.sendMessage(bob, data, uint32(100));
} }
......
...@@ -10,11 +10,7 @@ contract BlockOracle_Test is Test { ...@@ -10,11 +10,7 @@ contract BlockOracle_Test is Test {
BlockOracle oracle; BlockOracle oracle;
/// @notice Emitted when a block is checkpointed. /// @notice Emitted when a block is checkpointed.
event Checkpoint( event Checkpoint(uint256 indexed blockNumber, Hash indexed blockHash, Timestamp indexed childTimestamp);
uint256 indexed blockNumber,
Hash indexed blockHash,
Timestamp indexed childTimestamp
);
function setUp() public { function setUp() public {
oracle = new BlockOracle(); oracle = new BlockOracle();
...@@ -27,9 +23,7 @@ contract BlockOracle_Test is Test { ...@@ -27,9 +23,7 @@ contract BlockOracle_Test is Test {
function test_checkpointAndLoad_succeeds() public { function test_checkpointAndLoad_succeeds() public {
vm.expectEmit(true, true, true, false); vm.expectEmit(true, true, true, false);
emit Checkpoint( emit Checkpoint(
block.number - 1, block.number - 1, Hash.wrap(blockhash(block.number - 1)), Timestamp.wrap(uint64(block.timestamp))
Hash.wrap(blockhash(block.number - 1)),
Timestamp.wrap(uint64(block.timestamp))
); );
oracle.checkpoint(); oracle.checkpoint();
uint256 blockNumber = block.number - 1; uint256 blockNumber = block.number - 1;
......
...@@ -48,8 +48,8 @@ contract Bytes_slice_Test is Test { ...@@ -48,8 +48,8 @@ contract Bytes_slice_Test is Test {
/// in memory. In this case, we test that a 2 byte slice between the 32nd byte of the /// in memory. In this case, we test that a 2 byte slice between the 32nd byte of the
/// first word and the 1st byte of the second word is correct. /// first word and the 1st byte of the second word is correct.
function test_slice_acrossWords_works() public { function test_slice_acrossWords_works() public {
bytes bytes memory input =
memory input = hex"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000"; hex"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000";
assertEq(Bytes.slice(input, 31, 2), hex"1122"); assertEq(Bytes.slice(input, 31, 2), hex"1122");
} }
...@@ -58,21 +58,16 @@ contract Bytes_slice_Test is Test { ...@@ -58,21 +58,16 @@ contract Bytes_slice_Test is Test {
/// words in memory. In this case, we test that a 34 byte slice between 3 separate words /// words in memory. In this case, we test that a 34 byte slice between 3 separate words
/// returns the correct result. /// returns the correct result.
function test_slice_acrossMultipleWords_works() public { function test_slice_acrossMultipleWords_works() public {
bytes bytes memory input =
memory input = hex"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000"; hex"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000";
bytes bytes memory expected = hex"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11";
memory expected = hex"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11";
assertEq(Bytes.slice(input, 31, 34), expected); assertEq(Bytes.slice(input, 31, 34), expected);
} }
/// @notice Tests that the `slice` function correctly updates the free memory pointer depending /// @notice Tests that the `slice` function correctly updates the free memory pointer depending
/// on the length of the slice. /// on the length of the slice.
function testFuzz_slice_memorySafety_succeeds( function testFuzz_slice_memorySafety_succeeds(bytes memory _input, uint256 _start, uint256 _length) public {
bytes memory _input,
uint256 _start,
uint256 _length
) public {
// The start should never be more than the length of the input bytes array - 1 // The start should never be more than the length of the input bytes array - 1
vm.assume(_start < _input.length); vm.assume(_start < _input.length);
// The length should never be more than the length of the input bytes array - the starting // The length should never be more than the length of the input bytes array - the starting
...@@ -125,11 +120,7 @@ contract Bytes_slice_Test is Test { ...@@ -125,11 +120,7 @@ contract Bytes_slice_Test is Test {
contract Bytes_slice_TestFail is Test { contract Bytes_slice_TestFail is Test {
/// @notice Tests that, when given an input bytes array of length `n`, the `slice` function will /// @notice Tests that, when given an input bytes array of length `n`, the `slice` function will
/// always revert if `_start + _length > n`. /// always revert if `_start + _length > n`.
function testFuzz_slice_outOfBounds_reverts( function testFuzz_slice_outOfBounds_reverts(bytes memory _input, uint256 _start, uint256 _length) public {
bytes memory _input,
uint256 _start,
uint256 _length
) public {
// We want a valid start index and a length that will not overflow. // We want a valid start index and a length that will not overflow.
vm.assume(_start < _input.length && _length < type(uint256).max - 31); vm.assume(_start < _input.length && _length < type(uint256).max - 31);
// But, we want an invalid slice length. // But, we want an invalid slice length.
...@@ -141,11 +132,7 @@ contract Bytes_slice_TestFail is Test { ...@@ -141,11 +132,7 @@ contract Bytes_slice_TestFail is Test {
/// @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`, /// @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,
/// the `slice` function reverts. /// the `slice` function reverts.
function testFuzz_slice_lengthOverflows_reverts( function testFuzz_slice_lengthOverflows_reverts(bytes memory _input, uint256 _start, uint256 _length) public {
bytes memory _input,
uint256 _start,
uint256 _length
) public {
// Ensure that the `_length` will overflow if a number >= 31 is added to it. // Ensure that the `_length` will overflow if a number >= 31 is added to it.
vm.assume(_length > type(uint256).max - 31); vm.assume(_length > type(uint256).max - 31);
...@@ -155,11 +142,7 @@ contract Bytes_slice_TestFail is Test { ...@@ -155,11 +142,7 @@ contract Bytes_slice_TestFail is Test {
/// @notice Tests that, when given a start index `n` that is greater than /// @notice Tests that, when given a start index `n` that is greater than
/// `type(uint256).max - n`, the `slice` function reverts. /// `type(uint256).max - n`, the `slice` function reverts.
function testFuzz_slice_rangeOverflows_reverts( function testFuzz_slice_rangeOverflows_reverts(bytes memory _input, uint256 _start, uint256 _length) public {
bytes memory _input,
uint256 _start,
uint256 _length
) public {
// Ensure that `_length` is a realistic length of a slice. This is to make sure // Ensure that `_length` is a realistic length of a slice. This is to make sure
// we revert on the correct require statement. // we revert on the correct require statement.
vm.assume(_length < _input.length); vm.assume(_length < _input.length);
...@@ -188,10 +171,10 @@ contract Bytes_toNibbles_Test is Test { ...@@ -188,10 +171,10 @@ contract Bytes_toNibbles_Test is Test {
/// of 256 nibbles corresponding to the input data. This test exists to ensure that, /// of 256 nibbles corresponding to the input data. This test exists to ensure that,
/// given a large input, the `toNibbles` function works as expected. /// given a large input, the `toNibbles` function works as expected.
function test_toNibbles_expectedResult128Bytes_works() public { function test_toNibbles_expectedResult128Bytes_works() public {
bytes bytes memory input =
memory input = hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"; hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f";
bytes bytes memory expected =
memory expected = hex"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f"; hex"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f";
bytes memory actual = Bytes.toNibbles(input); bytes memory actual = Bytes.toNibbles(input);
assertEq(input.length * 2, actual.length); assertEq(input.length * 2, actual.length);
...@@ -265,13 +248,14 @@ contract Bytes_equal_Test is Test { ...@@ -265,13 +248,14 @@ contract Bytes_equal_Test is Test {
function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) { function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {
bool _eq; bool _eq;
assembly { assembly {
_eq := and( _eq :=
// Check if the contents of the two bytes arrays are equal in memory. and(
eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))), // Check if the contents of the two bytes arrays are equal in memory.
// Check if the length of the two bytes arrays are equal in memory. eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),
// This is redundant given the above check, but included for completeness. // Check if the length of the two bytes arrays are equal in memory.
eq(mload(_a), mload(_b)) // This is redundant given the above check, but included for completeness.
) eq(mload(_a), mload(_b))
)
} }
return _eq; return _eq;
} }
......
...@@ -19,10 +19,7 @@ contract CheckBalanceHighTest is Test { ...@@ -19,10 +19,7 @@ contract CheckBalanceHighTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns true /// @notice Fuzz the `check` function and assert that it always returns true
/// when the target's balance is larger than the threshold. /// when the target's balance is larger than the threshold.
function testFuzz_check_succeeds(address _target, uint256 _threshold) external { function testFuzz_check_succeeds(address _target, uint256 _threshold) external {
CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold });
target: _target,
threshold: _threshold
});
// prevent overflows // prevent overflows
vm.assume(_threshold != type(uint256).max); vm.assume(_threshold != type(uint256).max);
...@@ -34,10 +31,7 @@ contract CheckBalanceHighTest is Test { ...@@ -34,10 +31,7 @@ contract CheckBalanceHighTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns false /// @notice Fuzz the `check` function and assert that it always returns false
/// when the target's balance is smaller than the threshold. /// when the target's balance is smaller than the threshold.
function testFuzz_check_lowBalance_fails(address _target, uint256 _threshold) external { function testFuzz_check_lowBalance_fails(address _target, uint256 _threshold) external {
CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold });
target: _target,
threshold: _threshold
});
vm.assume(_target.balance < _threshold); vm.assume(_target.balance < _threshold);
......
...@@ -19,10 +19,7 @@ contract CheckBalanceLowTest is Test { ...@@ -19,10 +19,7 @@ contract CheckBalanceLowTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns true /// @notice Fuzz the `check` function and assert that it always returns true
/// when the target's balance is smaller than the threshold. /// when the target's balance is smaller than the threshold.
function testFuzz_check_succeeds(address _target, uint256 _threshold) external { function testFuzz_check_succeeds(address _target, uint256 _threshold) external {
CheckBalanceLow.Params memory p = CheckBalanceLow.Params({ CheckBalanceLow.Params memory p = CheckBalanceLow.Params({ target: _target, threshold: _threshold });
target: _target,
threshold: _threshold
});
vm.assume(_target.balance < _threshold); vm.assume(_target.balance < _threshold);
...@@ -32,10 +29,7 @@ contract CheckBalanceLowTest is Test { ...@@ -32,10 +29,7 @@ contract CheckBalanceLowTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns false /// @notice Fuzz the `check` function and assert that it always returns false
/// when the target's balance is larger than the threshold. /// when the target's balance is larger than the threshold.
function testFuzz_check_highBalance_fails(address _target, uint256 _threshold) external { function testFuzz_check_highBalance_fails(address _target, uint256 _threshold) external {
CheckBalanceLow.Params memory p = CheckBalanceLow.Params({ CheckBalanceLow.Params memory p = CheckBalanceLow.Params({ target: _target, threshold: _threshold });
target: _target,
threshold: _threshold
});
// prevent overflows // prevent overflows
vm.assume(_threshold != type(uint256).max); vm.assume(_threshold != type(uint256).max);
......
...@@ -2,10 +2,7 @@ ...@@ -2,10 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { import { CheckGelatoLow, IGelatoTreasury } from "../src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
CheckGelatoLow,
IGelatoTreasury
} from "../src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
/// @title MockGelatoTreasury /// @title MockGelatoTreasury
/// @notice Mocks the Gelato treasury for testing purposes. Allows arbitrary /// @notice Mocks the Gelato treasury for testing purposes. Allows arbitrary
...@@ -13,11 +10,7 @@ import { ...@@ -13,11 +10,7 @@ import {
contract MockGelatoTreasury is IGelatoTreasury { contract MockGelatoTreasury is IGelatoTreasury {
mapping(address => mapping(address => uint256)) private tokenBalances; mapping(address => mapping(address => uint256)) private tokenBalances;
function setTokenBalance( function setTokenBalance(address _user, address _token, uint256 _balance) external {
address _user,
address _token,
uint256 _balance
) external {
tokenBalances[_token][_user] = _balance; tokenBalances[_token][_user] = _balance;
} }
...@@ -48,11 +41,8 @@ contract CheckGelatoLowTest is Test { ...@@ -48,11 +41,8 @@ contract CheckGelatoLowTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns true /// @notice Fuzz the `check` function and assert that it always returns true
/// when the user's balance in the treasury is less than the threshold. /// when the user's balance in the treasury is less than the threshold.
function testFuzz_check_succeeds(uint256 _threshold, address _recipient) external { function testFuzz_check_succeeds(uint256 _threshold, address _recipient) external {
CheckGelatoLow.Params memory p = CheckGelatoLow.Params({ CheckGelatoLow.Params memory p =
treasury: address(gelato), CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
threshold: _threshold,
recipient: _recipient
});
vm.assume(gelato.userTokenBalance(_recipient, eth) < _threshold); vm.assume(gelato.userTokenBalance(_recipient, eth) < _threshold);
...@@ -63,11 +53,8 @@ contract CheckGelatoLowTest is Test { ...@@ -63,11 +53,8 @@ contract CheckGelatoLowTest is Test {
/// when the user's balance in the treasury is greater than or equal /// when the user's balance in the treasury is greater than or equal
/// to the threshold. /// to the threshold.
function testFuzz_check_highBalance_fails(uint256 _threshold, address _recipient) external { function testFuzz_check_highBalance_fails(uint256 _threshold, address _recipient) external {
CheckGelatoLow.Params memory p = CheckGelatoLow.Params({ CheckGelatoLow.Params memory p =
treasury: address(gelato), CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
threshold: _threshold,
recipient: _recipient
});
gelato.setTokenBalance(_recipient, eth, _threshold); gelato.setTokenBalance(_recipient, eth, _threshold);
......
...@@ -117,9 +117,7 @@ contract Clones_Test is Test { ...@@ -117,9 +117,7 @@ contract Clones_Test is Test {
assertEq(fetched, param); assertEq(fetched, param);
} }
function testFuzz_clone_uintArrayArg_succeeds(uint256 argOffset, uint256[] memory param) function testFuzz_clone_uintArrayArg_succeeds(uint256 argOffset, uint256[] memory param) public {
public
{
ExampleClone implementation = new ExampleClone(argOffset); ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation); ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createUintArrayClone(param); ExampleClone clone = factory.createUintArrayClone(param);
......
...@@ -49,12 +49,7 @@ contract CommonTest is Test { ...@@ -49,12 +49,7 @@ contract CommonTest is Test {
bytes32 nonZeroHash = keccak256(abi.encode("NON_ZERO")); bytes32 nonZeroHash = keccak256(abi.encode("NON_ZERO"));
bytes NON_ZERO_DATA = hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000"; bytes NON_ZERO_DATA = hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000";
event TransactionDeposited( event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
address indexed from,
address indexed to,
uint256 indexed version,
bytes opaqueData
);
FFIInterface ffi; FFIInterface ffi;
...@@ -82,13 +77,10 @@ contract CommonTest is Test { ...@@ -82,13 +77,10 @@ contract CommonTest is Test {
uint64 _gasLimit, uint64 _gasLimit,
bool _isCreation, bool _isCreation,
bytes memory _data bytes memory _data
) internal { )
emit TransactionDeposited( internal
_from, {
_to, emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data));
0,
abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)
);
} }
} }
...@@ -97,8 +89,7 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -97,8 +89,7 @@ contract L2OutputOracle_Initializer is CommonTest {
L2OutputOracle oracle; L2OutputOracle oracle;
L2OutputOracle oracleImpl; L2OutputOracle oracleImpl;
L2ToL1MessagePasser messagePasser = L2ToL1MessagePasser messagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
// Constructor arguments // Constructor arguments
address internal proposer = 0x000000000000000000000000000000000000AbBa; address internal proposer = 0x000000000000000000000000000000000000AbBa;
...@@ -114,10 +105,7 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -114,10 +105,7 @@ contract L2OutputOracle_Initializer is CommonTest {
uint256 initL1Time; uint256 initL1Time;
event OutputProposed( event OutputProposed(
bytes32 indexed outputRoot, bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp
uint256 indexed l2OutputIndex,
uint256 indexed l2BlockNumber,
uint256 l1Timestamp
); );
event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);
...@@ -166,15 +154,7 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -166,15 +154,7 @@ contract L2OutputOracle_Initializer is CommonTest {
vm.prank(multisig); vm.prank(multisig);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(
address(oracleImpl), address(oracleImpl),
abi.encodeCall( abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp, proposer, owner))
L2OutputOracle.initialize,
(
startingBlockNumber,
startingTimestamp,
proposer,
owner
)
)
); );
oracle = L2OutputOracle(address(proxy)); oracle = L2OutputOracle(address(proxy));
vm.label(address(oracle), "L2OutputOracle"); vm.label(address(oracle), "L2OutputOracle");
...@@ -193,11 +173,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer { ...@@ -193,11 +173,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
SystemConfig systemConfig; SystemConfig systemConfig;
event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);
event WithdrawalProven( event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to);
bytes32 indexed withdrawalHash,
address indexed from,
address indexed to
);
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
...@@ -212,16 +188,16 @@ contract Portal_Initializer is L2OutputOracle_Initializer { ...@@ -212,16 +188,16 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
( (
address(1), //_owner, address(1), //_owner,
0, //_overhead, 0, //_overhead,
10000, //_scalar, 10000, //_scalar,
bytes32(0), //_batcherHash, bytes32(0), //_batcherHash,
30_000_000, //_gasLimit, 30_000_000, //_gasLimit,
address(0), //_unsafeBlockSigner, address(0), //_unsafeBlockSigner,
Constants.DEFAULT_RESOURCE_CONFIG(), //_config, Constants.DEFAULT_RESOURCE_CONFIG(), //_config,
0, //_startBlock 0, //_startBlock
address(0xff), // _batchInbox address(0xff), // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: address(0), l1CrossDomainMessenger: address(0),
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
...@@ -240,11 +216,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer { ...@@ -240,11 +216,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
Proxy proxy = new Proxy(multisig); Proxy proxy = new Proxy(multisig);
vm.prank(multisig); vm.prank(multisig);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(
address(opImpl), address(opImpl), abi.encodeCall(OptimismPortal.initialize, (oracle, guardian, systemConfig, false))
abi.encodeCall(
OptimismPortal.initialize,
(oracle, guardian, systemConfig, false)
)
); );
op = OptimismPortal(payable(address(proxy))); op = OptimismPortal(payable(address(proxy)));
vm.label(address(op), "OptimismPortal"); vm.label(address(op), "OptimismPortal");
...@@ -254,16 +226,9 @@ contract Portal_Initializer is L2OutputOracle_Initializer { ...@@ -254,16 +226,9 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
contract Messenger_Initializer is Portal_Initializer { contract Messenger_Initializer is Portal_Initializer {
AddressManager internal addressManager; AddressManager internal addressManager;
L1CrossDomainMessenger internal L1Messenger; L1CrossDomainMessenger internal L1Messenger;
L2CrossDomainMessenger internal L2Messenger = L2CrossDomainMessenger internal L2Messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
event SentMessage( event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);
address indexed target,
address sender,
bytes message,
uint256 messageNonce,
uint256 gasLimit
);
event SentMessageExtension1(address indexed sender, uint256 value); event SentMessageExtension1(address indexed sender, uint256 value);
...@@ -312,10 +277,7 @@ contract Messenger_Initializer is Portal_Initializer { ...@@ -312,10 +277,7 @@ contract Messenger_Initializer is Portal_Initializer {
L1Messenger = L1CrossDomainMessenger(address(proxy)); L1Messenger = L1CrossDomainMessenger(address(proxy));
L1Messenger.initialize(op); L1Messenger.initialize(op);
vm.etch( vm.etch(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(new L2CrossDomainMessenger(address(L1Messenger))).code);
Predeploys.L2_CROSS_DOMAIN_MESSENGER,
address(new L2CrossDomainMessenger(address(L1Messenger))).code
);
L2Messenger.initialize(); L2Messenger.initialize();
...@@ -326,10 +288,7 @@ contract Messenger_Initializer is Portal_Initializer { ...@@ -326,10 +288,7 @@ contract Messenger_Initializer is Portal_Initializer {
vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH"); vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH");
vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger");
vm.label( vm.label(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), "L1CrossDomainMessenger_aliased");
AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),
"L1CrossDomainMessenger_aliased"
);
} }
} }
...@@ -348,56 +307,26 @@ contract Bridge_Initializer is Messenger_Initializer { ...@@ -348,56 +307,26 @@ contract Bridge_Initializer is Messenger_Initializer {
event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data); event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);
event ETHWithdrawalFinalized( event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data);
address indexed from,
address indexed to,
uint256 amount,
bytes data
);
event ERC20DepositInitiated( event ERC20DepositInitiated(
address indexed l1Token, address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
); );
event ERC20WithdrawalFinalized( event ERC20WithdrawalFinalized(
address indexed l1Token, address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
); );
event WithdrawalInitiated( event WithdrawalInitiated(
address indexed l1Token, address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
); );
event DepositFinalized( event DepositFinalized(
address indexed l1Token, address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
); );
event DepositFailed( event DepositFailed(
address indexed l1Token, address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
); );
event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data); event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);
...@@ -431,11 +360,7 @@ contract Bridge_Initializer is Messenger_Initializer { ...@@ -431,11 +360,7 @@ contract Bridge_Initializer is Messenger_Initializer {
// Deploy the L1 bridge and initialize it with the address of the // Deploy the L1 bridge and initialize it with the address of the
// L1CrossDomainMessenger // L1CrossDomainMessenger
L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig); L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);
vm.mockCall( vm.mockCall(multisig, abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector), abi.encode(true));
multisig,
abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),
abi.encode(true)
);
vm.startPrank(multisig); vm.startPrank(multisig);
proxy.setCode(address(new L1StandardBridge()).code); proxy.setCode(address(new L1StandardBridge()).code);
vm.clearMockedCalls(); vm.clearMockedCalls();
...@@ -443,9 +368,7 @@ contract Bridge_Initializer is Messenger_Initializer { ...@@ -443,9 +368,7 @@ contract Bridge_Initializer is Messenger_Initializer {
vm.stopPrank(); vm.stopPrank();
L1Bridge = L1StandardBridge(payable(address(proxy))); L1Bridge = L1StandardBridge(payable(address(proxy)));
L1Bridge.initialize({ L1Bridge.initialize({ _messenger: L1Messenger });
_messenger: L1Messenger
});
vm.label(address(proxy), "L1StandardBridge_Proxy"); vm.label(address(proxy), "L1StandardBridge_Proxy");
vm.label(address(L1Bridge_Impl), "L1StandardBridge_Impl"); vm.label(address(L1Bridge_Impl), "L1StandardBridge_Impl");
...@@ -526,11 +449,7 @@ contract ERC721Bridge_Initializer is Messenger_Initializer { ...@@ -526,11 +449,7 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
vm.prank(multisig); vm.prank(multisig);
l1BridgeProxy.upgradeToAndCall( l1BridgeProxy.upgradeToAndCall(
address(l1BridgeImpl), address(l1BridgeImpl), abi.encodeCall(L1ERC721Bridge.initialize, (CrossDomainMessenger(L1Messenger)))
abi.encodeCall(
L1ERC721Bridge.initialize,
(CrossDomainMessenger(L1Messenger))
)
); );
L1Bridge = L1ERC721Bridge(address(l1BridgeProxy)); L1Bridge = L1ERC721Bridge(address(l1BridgeProxy));
...@@ -546,8 +465,7 @@ contract ERC721Bridge_Initializer is Messenger_Initializer { ...@@ -546,8 +465,7 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
vm.prank(multisig); vm.prank(multisig);
Proxy(payable(Predeploys.L2_ERC721_BRIDGE)).upgradeToAndCall( Proxy(payable(Predeploys.L2_ERC721_BRIDGE)).upgradeToAndCall(
address(l2BridgeImpl), address(l2BridgeImpl), abi.encodeCall(L2ERC721Bridge.initialize, (L2Messenger))
abi.encodeCall(L2ERC721Bridge.initialize, (L2Messenger))
); );
// Set up a reference to the L2ERC721Bridge. // Set up a reference to the L2ERC721Bridge.
...@@ -565,24 +483,13 @@ contract FeeVault_Initializer is Bridge_Initializer { ...@@ -565,24 +483,13 @@ contract FeeVault_Initializer is Bridge_Initializer {
event Withdrawal(uint256 value, address to, address from); event Withdrawal(uint256 value, address to, address from);
event Withdrawal( event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork);
uint256 value,
address to,
address from,
FeeVault.WithdrawalNetwork withdrawalNetwork
);
} }
contract FFIInterface is Test { contract FFIInterface is Test {
function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx) function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)
external external
returns ( returns (bytes32, bytes32, bytes32, bytes32, bytes[] memory)
bytes32,
bytes32,
bytes32,
bytes32,
bytes[] memory
)
{ {
string[] memory cmds = new string[](8); string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing"; cmds[0] = "scripts/differential-testing/differential-testing";
...@@ -613,7 +520,10 @@ contract FFIInterface is Test { ...@@ -613,7 +520,10 @@ contract FFIInterface is Test {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external returns (bytes32) { )
external
returns (bytes32)
{
string[] memory cmds = new string[](8); string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing"; cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashCrossDomainMessage"; cmds[1] = "hashCrossDomainMessage";
...@@ -635,7 +545,10 @@ contract FFIInterface is Test { ...@@ -635,7 +545,10 @@ contract FFIInterface is Test {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external returns (bytes32) { )
external
returns (bytes32)
{
string[] memory cmds = new string[](8); string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing"; cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashWithdrawal"; cmds[1] = "hashWithdrawal";
...@@ -655,7 +568,10 @@ contract FFIInterface is Test { ...@@ -655,7 +568,10 @@ contract FFIInterface is Test {
bytes32 _stateRoot, bytes32 _stateRoot,
bytes32 _messagePasserStorageRoot, bytes32 _messagePasserStorageRoot,
bytes32 _latestBlockhash bytes32 _latestBlockhash
) external returns (bytes32) { )
external
returns (bytes32)
{
string[] memory cmds = new string[](6); string[] memory cmds = new string[](6);
cmds[0] = "scripts/differential-testing/differential-testing"; cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashOutputRootProof"; cmds[1] = "hashOutputRootProof";
...@@ -676,7 +592,10 @@ contract FFIInterface is Test { ...@@ -676,7 +592,10 @@ contract FFIInterface is Test {
uint64 _gas, uint64 _gas,
bytes memory _data, bytes memory _data,
uint64 _logIndex uint64 _logIndex
) external returns (bytes32) { )
external
returns (bytes32)
{
string[] memory cmds = new string[](10); string[] memory cmds = new string[](10);
cmds[0] = "scripts/differential-testing/differential-testing"; cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashDepositTransaction"; cmds[1] = "hashDepositTransaction";
...@@ -693,10 +612,7 @@ contract FFIInterface is Test { ...@@ -693,10 +612,7 @@ contract FFIInterface is Test {
return abi.decode(result, (bytes32)); return abi.decode(result, (bytes32));
} }
function encodeDepositTransaction(Types.UserDepositTransaction calldata txn) function encodeDepositTransaction(Types.UserDepositTransaction calldata txn) external returns (bytes memory) {
external
returns (bytes memory)
{
string[] memory cmds = new string[](11); string[] memory cmds = new string[](11);
cmds[0] = "scripts/differential-testing/differential-testing"; cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "encodeDepositTransaction"; cmds[1] = "encodeDepositTransaction";
...@@ -721,7 +637,10 @@ contract FFIInterface is Test { ...@@ -721,7 +637,10 @@ contract FFIInterface is Test {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external returns (bytes memory) { )
external
returns (bytes memory)
{
string[] memory cmds = new string[](8); string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing"; cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "encodeCrossDomainMessage"; cmds[1] = "encodeCrossDomainMessage";
...@@ -748,12 +667,7 @@ contract FFIInterface is Test { ...@@ -748,12 +667,7 @@ contract FFIInterface is Test {
function getMerkleTrieFuzzCase(string memory variant) function getMerkleTrieFuzzCase(string memory variant)
external external
returns ( returns (bytes32, bytes memory, bytes memory, bytes[] memory)
bytes32,
bytes memory,
bytes memory,
bytes[] memory
)
{ {
string[] memory cmds = new string[](5); string[] memory cmds = new string[](5);
cmds[0] = "./test-case-generator/fuzz"; cmds[0] = "./test-case-generator/fuzz";
...@@ -797,12 +711,8 @@ contract CallerCaller { ...@@ -797,12 +711,8 @@ contract CallerCaller {
emit WhatHappened(success, returndata); emit WhatHappened(success, returndata);
assembly { assembly {
switch success switch success
case 0 { case 0 { revert(add(returndata, 0x20), mload(returndata)) }
revert(add(returndata, 0x20), mload(returndata)) default { return(add(returndata, 0x20), mload(returndata)) }
}
default {
return(add(returndata, 0x20), mload(returndata))
}
} }
} }
} }
...@@ -824,12 +734,8 @@ contract ConfigurableCaller { ...@@ -824,12 +734,8 @@ contract ConfigurableCaller {
emit WhatHappened(success, returndata); emit WhatHappened(success, returndata);
assembly { assembly {
switch success switch success
case 0 { case 0 { revert(add(returndata, 0x20), mload(returndata)) }
revert(add(returndata, 0x20), mload(returndata)) default { return(add(returndata, 0x20), mload(returndata)) }
}
default {
return(add(returndata, 0x20), mload(returndata))
}
} }
} }
} }
......
...@@ -28,9 +28,7 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { ...@@ -28,9 +28,7 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
/// or equal to the minimum gas limit value on the OptimismPortal. /// or equal to the minimum gas limit value on the OptimismPortal.
/// This guarantees that the messengers will always pass sufficient /// This guarantees that the messengers will always pass sufficient
/// gas to the OptimismPortal. /// gas to the OptimismPortal.
function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) external {
external
{
vm.assume(_data.length <= type(uint64).max); vm.assume(_data.length <= type(uint64).max);
uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit); uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit);
uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length)); uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length));
......
...@@ -61,12 +61,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { ...@@ -61,12 +61,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1); bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);
bytes32 hash = Hashing.hashCrossDomainMessage( bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce(nonce, 1), Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
sender,
target,
value,
minGasLimit,
message
); );
// It should be a failed message. The revert is caught, // It should be a failed message. The revert is caught,
...@@ -75,14 +70,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { ...@@ -75,14 +70,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
emit FailedRelayedMessage(hash); emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage( L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message);
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
);
assertEq(setter.value(), 0); assertEq(setter.value(), 0);
} }
......
...@@ -30,11 +30,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { ...@@ -30,11 +30,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/// @dev CrossDomainOwnable3.sol transferOwnership event /// @dev CrossDomainOwnable3.sol transferOwnership event
event OwnershipTransferred( event OwnershipTransferred(address indexed previousOwner, address indexed newOwner, bool isLocal);
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
function setUp() public override { function setUp() public override {
...@@ -111,12 +107,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { ...@@ -111,12 +107,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1); bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);
bytes32 hash = Hashing.hashCrossDomainMessage( bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce(nonce, 1), Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
sender,
target,
value,
minGasLimit,
message
); );
// It should be a failed message. The revert is caught, // It should be a failed message. The revert is caught,
...@@ -125,14 +116,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { ...@@ -125,14 +116,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
emit FailedRelayedMessage(hash); emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage( L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message);
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
);
assertEq(setter.value(), 0); assertEq(setter.value(), 0);
} }
......
...@@ -14,11 +14,7 @@ contract DisputeGameFactory_Init is L2OutputOracle_Initializer { ...@@ -14,11 +14,7 @@ contract DisputeGameFactory_Init is L2OutputOracle_Initializer {
DisputeGameFactory factory; DisputeGameFactory factory;
FakeClone fakeClone; FakeClone fakeClone;
event DisputeGameCreated( event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);
address indexed disputeProxy,
GameType indexed gameType,
Claim indexed rootClaim
);
event ImplementationSet(address indexed impl, GameType indexed gameType); event ImplementationSet(address indexed impl, GameType indexed gameType);
...@@ -42,11 +38,7 @@ contract DisputeGameFactory_Init is L2OutputOracle_Initializer { ...@@ -42,11 +38,7 @@ contract DisputeGameFactory_Init is L2OutputOracle_Initializer {
contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init { contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
/// @dev Tests that the `create` function succeeds when creating a new dispute game /// @dev Tests that the `create` function succeeds when creating a new dispute game
/// with a `GameType` that has an implementation set. /// with a `GameType` that has an implementation set.
function testFuzz_create_succeeds( function testFuzz_create_succeeds(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
...@@ -73,11 +65,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init { ...@@ -73,11 +65,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
/// @dev Tests that the `create` function reverts when there is no implementation /// @dev Tests that the `create` function reverts when there is no implementation
/// set for the given `GameType`. /// set for the given `GameType`.
function testFuzz_create_noImpl_reverts( function testFuzz_create_noImpl_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
...@@ -86,11 +74,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init { ...@@ -86,11 +74,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
} }
/// @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID. /// @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID.
function testFuzz_create_sameUUID_reverts( function testFuzz_create_sameUUID_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
...@@ -111,10 +95,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init { ...@@ -111,10 +95,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
// Ensure that the `create` function reverts when called with parameters that would result in the same UUID. // Ensure that the `create` function reverts when called with parameters that would result in the same UUID.
vm.expectRevert( vm.expectRevert(
abi.encodeWithSelector( abi.encodeWithSelector(GameAlreadyExists.selector, factory.getGameUUID(gt, rootClaim, extraData))
GameAlreadyExists.selector,
factory.getGameUUID(gt, rootClaim, extraData)
)
); );
factory.create(gt, rootClaim, extraData); factory.create(gt, rootClaim, extraData);
} }
...@@ -148,17 +129,12 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init { ...@@ -148,17 +129,12 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init { contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
/// @dev Tests that the `getGameUUID` function returns the correct hash when comparing /// @dev Tests that the `getGameUUID` function returns the correct hash when comparing
/// against the keccak256 hash of the abi-encoded parameters. /// against the keccak256 hash of the abi-encoded parameters.
function testDiff_getGameUUID_succeeds( function testDiff_getGameUUID_succeeds(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
assertEq( assertEq(
Hash.unwrap(factory.getGameUUID(gt, rootClaim, extraData)), Hash.unwrap(factory.getGameUUID(gt, rootClaim, extraData)), keccak256(abi.encode(gt, rootClaim, extraData))
keccak256(abi.encode(gt, rootClaim, extraData))
); );
} }
} }
......
...@@ -14,7 +14,7 @@ import { SimpleStorage } from "./Helpers.sol"; ...@@ -14,7 +14,7 @@ import { SimpleStorage } from "./Helpers.sol";
/// to go up by ~4x. Each of the methods is a simple getter around /// to go up by ~4x. Each of the methods is a simple getter around
/// parts of the `DripState`. /// parts of the `DripState`.
contract TestDrippie is Drippie { contract TestDrippie is Drippie {
constructor(address owner) Drippie(owner) {} constructor(address owner) Drippie(owner) { }
function dripStatus(string memory name) external view returns (Drippie.DripStatus) { function dripStatus(string memory name) external view returns (Drippie.DripStatus) {
return drips[name].status; return drips[name].status;
...@@ -28,11 +28,7 @@ contract TestDrippie is Drippie { ...@@ -28,11 +28,7 @@ contract TestDrippie is Drippie {
return drips[name].config; return drips[name].config;
} }
function dripConfigActions(string memory name) function dripConfigActions(string memory name) external view returns (Drippie.DripAction[] memory) {
external
view
returns (Drippie.DripAction[] memory)
{
return drips[name].config.actions; return drips[name].config.actions;
} }
...@@ -93,14 +89,13 @@ contract Drippie_Test is Test { ...@@ -93,14 +89,13 @@ contract Drippie_Test is Test {
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
actions[0] = Drippie.DripAction({ target: payable(address(0x44)), data: hex"", value: 1 }); actions[0] = Drippie.DripAction({ target: payable(address(0x44)), data: hex"", value: 1 });
return return Drippie.DripConfig({
Drippie.DripConfig({ interval: 100,
interval: 100, dripcheck: check,
dripcheck: check, reentrant: false,
reentrant: false, checkparams: hex"",
checkparams: hex"", actions: actions
actions: actions });
});
} }
/// @notice Creates a default drip using the default drip config. /// @notice Creates a default drip using the default drip config.
...@@ -189,11 +184,7 @@ contract Drippie_Test is Test { ...@@ -189,11 +184,7 @@ contract Drippie_Test is Test {
vm.prank(owner); vm.prank(owner);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit DripStatusUpdated({ emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.ACTIVE });
nameref: dripName,
name: dripName,
status: Drippie.DripStatus.ACTIVE
});
drippie.status(dripName, Drippie.DripStatus.ACTIVE); drippie.status(dripName, Drippie.DripStatus.ACTIVE);
...@@ -205,11 +196,7 @@ contract Drippie_Test is Test { ...@@ -205,11 +196,7 @@ contract Drippie_Test is Test {
vm.prank(owner); vm.prank(owner);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit DripStatusUpdated({ emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.PAUSED });
nameref: dripName,
name: dripName,
status: Drippie.DripStatus.PAUSED
});
drippie.status(dripName, Drippie.DripStatus.PAUSED); drippie.status(dripName, Drippie.DripStatus.PAUSED);
...@@ -252,11 +239,7 @@ contract Drippie_Test is Test { ...@@ -252,11 +239,7 @@ contract Drippie_Test is Test {
vm.prank(owner); vm.prank(owner);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit DripStatusUpdated({ emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.ARCHIVED });
nameref: dripName,
name: dripName,
status: Drippie.DripStatus.ARCHIVED
});
drippie.status(dripName, Drippie.DripStatus.ARCHIVED); drippie.status(dripName, Drippie.DripStatus.ARCHIVED);
...@@ -339,20 +322,12 @@ contract Drippie_Test is Test { ...@@ -339,20 +322,12 @@ contract Drippie_Test is Test {
_warpToExecutable(dripName); _warpToExecutable(dripName);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit DripExecuted({ emit DripExecuted({ nameref: dripName, name: dripName, executor: address(this), timestamp: block.timestamp });
nameref: dripName,
name: dripName,
executor: address(this),
timestamp: block.timestamp
});
Drippie.DripAction[] memory actions = drippie.dripConfigActions(dripName); Drippie.DripAction[] memory actions = drippie.dripConfigActions(dripName);
assertEq(actions.length, 1); assertEq(actions.length, 1);
vm.expectCall( vm.expectCall(drippie.dripConfigCheckAddress(dripName), drippie.dripConfigCheckParams(dripName));
drippie.dripConfigCheckAddress(dripName),
drippie.dripConfigCheckParams(dripName)
);
vm.expectCall(actions[0].target, actions[0].value, actions[0].data); vm.expectCall(actions[0].target, actions[0].value, actions[0].data);
...@@ -381,11 +356,7 @@ contract Drippie_Test is Test { ...@@ -381,11 +356,7 @@ contract Drippie_Test is Test {
vm.prank(drippie.owner()); vm.prank(drippie.owner());
drippie.status(dripName, Drippie.DripStatus.ACTIVE); drippie.status(dripName, Drippie.DripStatus.ACTIVE);
vm.expectCall( vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, key, value));
address(simpleStorage),
0,
abi.encodeWithSelector(SimpleStorage.set.selector, key, value)
);
vm.expectEmit(true, true, true, true, address(drippie)); vm.expectEmit(true, true, true, true, address(drippie));
emit DripExecuted(dripName, dripName, address(this), block.timestamp); emit DripExecuted(dripName, dripName, address(this), block.timestamp);
...@@ -425,22 +396,11 @@ contract Drippie_Test is Test { ...@@ -425,22 +396,11 @@ contract Drippie_Test is Test {
vm.prank(drippie.owner()); vm.prank(drippie.owner());
drippie.status(dripName, Drippie.DripStatus.ACTIVE); drippie.status(dripName, Drippie.DripStatus.ACTIVE);
vm.expectCall( vm.expectCall(drippie.dripConfigCheckAddress(dripName), drippie.dripConfigCheckParams(dripName));
drippie.dripConfigCheckAddress(dripName),
drippie.dripConfigCheckParams(dripName)
);
vm.expectCall( vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, keyOne, valueOne));
address(simpleStorage),
0,
abi.encodeWithSelector(SimpleStorage.set.selector, keyOne, valueOne)
);
vm.expectCall( vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, keyTwo, valueTwo));
address(simpleStorage),
0,
abi.encodeWithSelector(SimpleStorage.set.selector, keyTwo, valueTwo)
);
vm.expectEmit(true, true, true, true, address(drippie)); vm.expectEmit(true, true, true, true, address(drippie));
emit DripExecuted(dripName, dripName, address(this), block.timestamp); emit DripExecuted(dripName, dripName, address(this), block.timestamp);
...@@ -475,12 +435,7 @@ contract Drippie_Test is Test { ...@@ -475,12 +435,7 @@ contract Drippie_Test is Test {
_warpToExecutable(dripName); _warpToExecutable(dripName);
vm.expectEmit(true, true, true, true, address(drippie)); vm.expectEmit(true, true, true, true, address(drippie));
emit DripExecuted({ emit DripExecuted({ nameref: dripName, name: dripName, executor: address(this), timestamp: block.timestamp });
nameref: dripName,
name: dripName,
executor: address(this),
timestamp: block.timestamp
});
drippie.drip(dripName); drippie.drip(dripName);
} }
......
...@@ -14,9 +14,7 @@ import { Encoding } from "../src/libraries/Encoding.sol"; ...@@ -14,9 +14,7 @@ import { Encoding } from "../src/libraries/Encoding.sol";
contract Encoding_Test is CommonTest { contract Encoding_Test is CommonTest {
/// @dev Tests encoding and decoding a nonce and version. /// @dev Tests encoding and decoding a nonce and version.
function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external { function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {
(uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce( (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(Encoding.encodeVersionedNonce(_nonce, _version));
Encoding.encodeVersionedNonce(_nonce, _version)
);
assertEq(version, _version); assertEq(version, _version);
assertEq(nonce, _nonce); assertEq(nonce, _nonce);
} }
...@@ -40,27 +38,15 @@ contract Encoding_Test is CommonTest { ...@@ -40,27 +38,15 @@ contract Encoding_Test is CommonTest {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
uint8 version = _version % 2; uint8 version = _version % 2;
uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version); uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);
bytes memory encoding = Encoding.encodeCrossDomainMessage( bytes memory encoding = Encoding.encodeCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data);
nonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes memory _encoding = ffi.encodeCrossDomainMessage( bytes memory _encoding = ffi.encodeCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data);
nonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
assertEq(encoding, _encoding); assertEq(encoding, _encoding);
} }
...@@ -71,23 +57,15 @@ contract Encoding_Test is CommonTest { ...@@ -71,23 +57,15 @@ contract Encoding_Test is CommonTest {
address _sender, address _sender,
address _target, address _target,
bytes memory _data bytes memory _data
) external { )
external
{
uint8 version = 0; uint8 version = 0;
uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version); uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);
bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata( bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(_target, _sender, _data, nonce);
_target,
_sender,
_data,
nonce
);
bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0( bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, nonce);
_target,
_sender,
_data,
nonce
);
assertEq(legacyEncoding, bedrockEncoding); assertEq(legacyEncoding, bedrockEncoding);
} }
...@@ -102,17 +80,11 @@ contract Encoding_Test is CommonTest { ...@@ -102,17 +80,11 @@ contract Encoding_Test is CommonTest {
bool isCreate, bool isCreate,
bytes memory _data, bytes memory _data,
uint64 _logIndex uint64 _logIndex
) external { )
external
{
Types.UserDepositTransaction memory t = Types.UserDepositTransaction( Types.UserDepositTransaction memory t = Types.UserDepositTransaction(
_from, _from, _to, isCreate, _value, _mint, _gas, _data, bytes32(uint256(0)), _logIndex
_to,
isCreate,
_value,
_mint,
_gas,
_data,
bytes32(uint256(0)),
_logIndex
); );
bytes memory txn = Encoding.encodeDepositTransaction(t); bytes memory txn = Encoding.encodeDepositTransaction(t);
......
...@@ -7,12 +7,8 @@ import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/Admin ...@@ -7,12 +7,8 @@ import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/Admin
import { FaucetHelper } from "./Helpers.sol"; import { FaucetHelper } from "./Helpers.sol";
contract Faucet_Initializer is Test { contract Faucet_Initializer is Test {
event Drip( event Drip(string indexed authModule, bytes32 indexed userId, uint256 amount, address indexed recipient);
string indexed authModule,
bytes32 indexed userId,
uint256 amount,
address indexed recipient
);
address internal faucetContractAdmin; address internal faucetContractAdmin;
address internal faucetAuthAdmin; address internal faucetAuthAdmin;
address internal nonAdmin; address internal nonAdmin;
...@@ -66,20 +62,13 @@ contract Faucet_Initializer is Test { ...@@ -66,20 +62,13 @@ contract Faucet_Initializer is Test {
function _enableFaucetAuthModules() internal { function _enableFaucetAuthModules() internal {
vm.startPrank(faucetContractAdmin); vm.startPrank(faucetContractAdmin);
faucet.configure( faucet.configure(optimistNftFam, Faucet.ModuleConfig("OptimistNftModule", true, 1 days, 1 ether));
optimistNftFam, faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", true, 1 days, 0.05 ether));
Faucet.ModuleConfig("OptimistNftModule", true, 1 days, 1 ether)
);
faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", true, 1 days, .05 ether));
vm.stopPrank(); vm.stopPrank();
} }
/// @notice Get signature as a bytes blob. /// @notice Get signature as a bytes blob.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
internal
pure
returns (bytes memory)
{
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest); (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v); bytes memory signature = abi.encodePacked(r, s, v);
...@@ -98,23 +87,18 @@ contract Faucet_Initializer is Test { ...@@ -98,23 +87,18 @@ contract Faucet_Initializer is Test {
address recipient, address recipient,
bytes32 id, bytes32 id,
bytes32 nonce bytes32 nonce
) internal view returns (bytes memory) { )
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof( internal
recipient, view
nonce, returns (bytes memory)
id {
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(recipient, nonce, id);
return _getSignature(
_issuerPrivateKey,
faucetHelper.getDigestWithEIP712Domain(
proof, _eip712Name, _contractVersion, _eip712Chainid, _eip712VerifyingContract
)
); );
return
_getSignature(
_issuerPrivateKey,
faucetHelper.getDigestWithEIP712Domain(
proof,
_eip712Name,
_contractVersion,
_eip712Chainid,
_eip712VerifyingContract
)
);
} }
} }
...@@ -140,11 +124,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -140,11 +124,7 @@ contract FaucetTest is Faucet_Initializer {
vm.prank(nonAdmin); vm.prank(nonAdmin);
faucet.drip( faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce), Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters( Faucet.AuthParameters(optimistNftFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
optimistNftFam,
keccak256(abi.encodePacked(fundsReceiver)),
signature
)
); );
} }
...@@ -166,11 +146,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -166,11 +146,7 @@ contract FaucetTest is Faucet_Initializer {
vm.expectRevert("Faucet: drip parameters could not be verified by security module"); vm.expectRevert("Faucet: drip parameters could not be verified by security module");
faucet.drip( faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce), Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters( Faucet.AuthParameters(optimistNftFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
optimistNftFam,
keccak256(abi.encodePacked(fundsReceiver)),
signature
)
); );
} }
...@@ -192,18 +168,10 @@ contract FaucetTest is Faucet_Initializer { ...@@ -192,18 +168,10 @@ contract FaucetTest is Faucet_Initializer {
vm.prank(nonAdmin); vm.prank(nonAdmin);
faucet.drip( faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce), Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters( Faucet.AuthParameters(optimistNftFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
optimistNftFam,
keccak256(abi.encodePacked(fundsReceiver)),
signature
)
); );
uint256 recipientBalanceAfter = address(fundsReceiver).balance; uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq( assertEq(recipientBalanceAfter - recipientBalanceBefore, 1 ether, "expect increase of 1 ether");
recipientBalanceAfter - recipientBalanceBefore,
1 ether,
"expect increase of 1 ether"
);
} }
function test_drip_githubSendsCorrectAmount_succeeds() external { function test_drip_githubSendsCorrectAmount_succeeds() external {
...@@ -227,11 +195,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -227,11 +195,7 @@ contract FaucetTest is Faucet_Initializer {
Faucet.AuthParameters(githubFam, keccak256(abi.encodePacked(fundsReceiver)), signature) Faucet.AuthParameters(githubFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
); );
uint256 recipientBalanceAfter = address(fundsReceiver).balance; uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq( assertEq(recipientBalanceAfter - recipientBalanceBefore, 0.05 ether, "expect increase of .05 ether");
recipientBalanceAfter - recipientBalanceBefore,
.05 ether,
"expect increase of .05 ether"
);
} }
function test_drip_emitsEvent_succeeds() external { function test_drip_emitsEvent_succeeds() external {
...@@ -249,12 +213,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -249,12 +213,7 @@ contract FaucetTest is Faucet_Initializer {
); );
vm.expectEmit(true, true, true, true, address(faucet)); vm.expectEmit(true, true, true, true, address(faucet));
emit Drip( emit Drip("GithubModule", keccak256(abi.encodePacked(fundsReceiver)), 0.05 ether, fundsReceiver);
"GithubModule",
keccak256(abi.encodePacked(fundsReceiver)),
.05 ether,
fundsReceiver
);
vm.prank(nonAdmin); vm.prank(nonAdmin);
faucet.drip( faucet.drip(
...@@ -283,7 +242,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -283,7 +242,7 @@ contract FaucetTest is Faucet_Initializer {
Faucet.AuthParameters(githubFam, keccak256(abi.encodePacked(fundsReceiver)), signature) Faucet.AuthParameters(githubFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
); );
faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", false, 1 days, .05 ether)); faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", false, 1 days, 0.05 ether));
vm.expectRevert("Faucet: provided auth module is not supported by this faucet"); vm.expectRevert("Faucet: provided auth module is not supported by this faucet");
faucet.drip( faucet.drip(
...@@ -408,11 +367,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -408,11 +367,7 @@ contract FaucetTest is Faucet_Initializer {
faucet.withdraw(payable(fundsReceiver), 2 ether); faucet.withdraw(payable(fundsReceiver), 2 ether);
uint256 recipientBalanceAfter = address(fundsReceiver).balance; uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq( assertEq(recipientBalanceAfter - recipientBalanceBefore, 2 ether, "expect increase of 2 ether");
recipientBalanceAfter - recipientBalanceBefore,
2 ether,
"expect increase of 2 ether"
);
vm.stopPrank(); vm.stopPrank();
} }
...@@ -426,7 +381,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -426,7 +381,7 @@ contract FaucetTest is Faucet_Initializer {
uint256 faucetBalanceBefore = address(faucet).balance; uint256 faucetBalanceBefore = address(faucet).balance;
vm.prank(nonAdmin); vm.prank(nonAdmin);
(bool success, ) = address(faucet).call{ value: 1 ether }(""); (bool success,) = address(faucet).call{ value: 1 ether }("");
assertTrue(success); assertTrue(success);
uint256 faucetBalanceAfter = address(faucet).balance; uint256 faucetBalanceAfter = address(faucet).balance;
......
...@@ -126,11 +126,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -126,11 +126,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// contain the disputed L2 output root. /// contain the disputed L2 output root.
function test_initialize_l1HeadTooOld_reverts() public { function test_initialize_l1HeadTooOld_reverts() public {
// Store a mock block hash for the genesis block. The timestamp will default to 0. // Store a mock block hash for the genesis block. The timestamp will default to 0.
vm.store( vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1)));
address(gameImpl.BLOCK_ORACLE()),
keccak256(abi.encode(0, 0)),
bytes32(uint256(1))
);
bytes memory _extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, 0); bytes memory _extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, 0);
vm.expectRevert(L1HeadTooOld.selector); vm.expectRevert(L1HeadTooOld.selector);
...@@ -150,10 +146,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -150,10 +146,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that the game is initialized with the correct data. /// @dev Tests that the game is initialized with the correct data.
function test_initialize_correctData_succeeds() public { function test_initialize_correctData_succeeds() public {
// Starting // Starting
( (FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) =
FaultDisputeGame.OutputProposal memory startingProp, gameProxy.proposals();
FaultDisputeGame.OutputProposal memory disputedProp
) = gameProxy.proposals();
Types.OutputProposal memory starting = oracle.getL2Output(startingProp.index); Types.OutputProposal memory starting = oracle.getL2Output(startingProp.index);
assertEq(startingProp.index, 0); assertEq(startingProp.index, 0);
assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber); assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber);
...@@ -168,21 +162,14 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -168,21 +162,14 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
(, uint256 l1HeadNumber) = abi.decode(gameProxy.extraData(), (uint256, uint256)); (, uint256 l1HeadNumber) = abi.decode(gameProxy.extraData(), (uint256, uint256));
assertEq(blockhash(l1HeadNumber), Hash.unwrap(gameProxy.l1Head())); assertEq(blockhash(l1HeadNumber), Hash.unwrap(gameProxy.l1Head()));
( (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(0);
uint32 parentIndex,
bool countered,
Claim claim,
Position position,
Clock clock
) = gameProxy.claimData(0);
assertEq(parentIndex, type(uint32).max); assertEq(parentIndex, type(uint32).max);
assertEq(countered, false); assertEq(countered, false);
assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM)); assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM));
assertEq(Position.unwrap(position), 1); assertEq(Position.unwrap(position), 1);
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
); );
} }
...@@ -256,44 +243,39 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -256,44 +243,39 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @notice Static unit test for the correctness of the chess clock incrementation. /// @notice Static unit test for the correctness of the chess clock incrementation.
function test_move_clockCorrectness_succeeds() public { function test_move_clockCorrectness_succeeds() public {
(, , , , Clock clock) = gameProxy.claimData(0); (,,,, Clock clock) = gameProxy.claimData(0);
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
); );
Claim claim = Claim.wrap(bytes32(uint256(5))); Claim claim = Claim.wrap(bytes32(uint256(5)));
vm.warp(block.timestamp + 15); vm.warp(block.timestamp + 15);
gameProxy.attack(0, claim); gameProxy.attack(0, claim);
(, , , , clock) = gameProxy.claimData(1); (,,,, clock) = gameProxy.claimData(1);
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp))))
); );
vm.warp(block.timestamp + 10); vm.warp(block.timestamp + 10);
gameProxy.attack(1, claim); gameProxy.attack(1, claim);
(, , , , clock) = gameProxy.claimData(2); (,,,, clock) = gameProxy.claimData(2);
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))))
); );
vm.warp(block.timestamp + 10); vm.warp(block.timestamp + 10);
gameProxy.attack(2, claim); gameProxy.attack(2, claim);
(, , , , clock) = gameProxy.claimData(3); (,,,, clock) = gameProxy.claimData(3);
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp))))
); );
vm.warp(block.timestamp + 10); vm.warp(block.timestamp + 10);
gameProxy.attack(3, claim); gameProxy.attack(3, claim);
(, , , , clock) = gameProxy.claimData(4); (,,,, clock) = gameProxy.claimData(4);
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp))))
); );
} }
...@@ -323,13 +305,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -323,13 +305,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, counter); gameProxy.attack(0, counter);
// Grab the claim data of the attack. // Grab the claim data of the attack.
( (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(1);
uint32 parentIndex,
bool countered,
Claim claim,
Position position,
Clock clock
) = gameProxy.claimData(1);
// Assert correctness of the attack claim's data. // Assert correctness of the attack claim's data.
assertEq(parentIndex, 0); assertEq(parentIndex, 0);
...@@ -337,8 +313,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -337,8 +313,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(Claim.unwrap(claim), Claim.unwrap(counter)); assertEq(Claim.unwrap(claim), Claim.unwrap(counter));
assertEq(Position.unwrap(position), Position.unwrap(Position.wrap(1).move(true))); assertEq(Position.unwrap(position), Position.unwrap(Position.wrap(1).move(true)));
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(5), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(LibClock.wrap(Duration.wrap(5), Timestamp.wrap(uint64(block.timestamp))))
); );
// Grab the claim data of the parent. // Grab the claim data of the parent.
...@@ -351,9 +326,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -351,9 +326,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(Position.unwrap(position), 1); assertEq(Position.unwrap(position), 1);
assertEq( assertEq(
Clock.unwrap(clock), Clock.unwrap(clock),
Clock.unwrap( Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp - 5))))
LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp - 5)))
)
); );
} }
...@@ -438,10 +411,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -438,10 +411,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that local data is loaded into the preimage oracle correctly. /// @dev Tests that local data is loaded into the preimage oracle correctly.
function test_addLocalData_static_succeeds() public { function test_addLocalData_static_succeeds() public {
IPreimageOracle oracle = IPreimageOracle(address(gameProxy.VM().oracle())); IPreimageOracle oracle = IPreimageOracle(address(gameProxy.VM().oracle()));
( (FaultDisputeGame.OutputProposal memory starting, FaultDisputeGame.OutputProposal memory disputed) =
FaultDisputeGame.OutputProposal memory starting, gameProxy.proposals();
FaultDisputeGame.OutputProposal memory disputed
) = gameProxy.proposals();
bytes32[5] memory data = [ bytes32[5] memory data = [
Hash.unwrap(gameProxy.l1Head()), Hash.unwrap(gameProxy.l1Head()),
...@@ -493,11 +464,7 @@ contract GamePlayer { ...@@ -493,11 +464,7 @@ contract GamePlayer {
uint256 internal maxDepth; uint256 internal maxDepth;
/// @notice Initializes the player /// @notice Initializes the player
function init( function init(FaultDisputeGame _gameProxy, GamePlayer _counterParty, Vm _vm) public {
FaultDisputeGame _gameProxy,
GamePlayer _counterParty,
Vm _vm
) public {
gameProxy = _gameProxy; gameProxy = _gameProxy;
counterParty = _counterParty; counterParty = _counterParty;
vm = _vm; vm = _vm;
...@@ -507,9 +474,7 @@ contract GamePlayer { ...@@ -507,9 +474,7 @@ contract GamePlayer {
/// @notice Perform the next move in the game. /// @notice Perform the next move in the game.
function play(uint256 _parentIndex) public virtual { function play(uint256 _parentIndex) public virtual {
// Grab the claim data at the parent index. // Grab the claim data at the parent index.
(uint32 grandparentIndex, , Claim parentClaim, Position parentPos, ) = gameProxy.claimData( (uint32 grandparentIndex,, Claim parentClaim, Position parentPos,) = gameProxy.claimData(_parentIndex);
_parentIndex
);
// The position to move to. // The position to move to.
Position movePos; Position movePos;
...@@ -531,9 +496,7 @@ contract GamePlayer { ...@@ -531,9 +496,7 @@ contract GamePlayer {
Claim ourParentClaim = claimAt(parentPos); Claim ourParentClaim = claimAt(parentPos);
// Fetch our claim at the grandparent's position. // Fetch our claim at the grandparent's position.
(, , Claim grandparentClaim, Position grandparentPos, ) = gameProxy.claimData( (,, Claim grandparentClaim, Position grandparentPos,) = gameProxy.claimData(grandparentIndex);
grandparentIndex
);
Claim ourGrandparentClaim = claimAt(grandparentPos); Claim ourGrandparentClaim = claimAt(grandparentPos);
if (Claim.unwrap(ourParentClaim) != Claim.unwrap(parentClaim)) { if (Claim.unwrap(ourParentClaim) != Claim.unwrap(parentClaim)) {
...@@ -547,8 +510,8 @@ contract GamePlayer { ...@@ -547,8 +510,8 @@ contract GamePlayer {
// Flag the move as an attack. // Flag the move as an attack.
isAttack = true; isAttack = true;
} else if ( } else if (
Claim.unwrap(ourParentClaim) == Claim.unwrap(parentClaim) && Claim.unwrap(ourParentClaim) == Claim.unwrap(parentClaim)
Claim.unwrap(ourGrandparentClaim) == Claim.unwrap(grandparentClaim) && Claim.unwrap(ourGrandparentClaim) == Claim.unwrap(grandparentClaim)
) { ) {
movePos = parentPos.move(false); movePos = parentPos.move(false);
} }
...@@ -598,7 +561,7 @@ contract GamePlayer { ...@@ -598,7 +561,7 @@ contract GamePlayer {
// If we have a second move position, attack the grandparent. // If we have a second move position, attack the grandparent.
if (Position.unwrap(movePos2) != 0) { if (Position.unwrap(movePos2) != 0) {
(, , , Position grandparentPos, ) = gameProxy.claimData(grandparentIndex); (,,, Position grandparentPos,) = gameProxy.claimData(grandparentIndex);
Claim ourGrandparentClaim = claimAt(grandparentPos.move(true)); Claim ourGrandparentClaim = claimAt(grandparentPos.move(true));
gameProxy.attack(grandparentIndex, ourGrandparentClaim); gameProxy.attack(grandparentIndex, ourGrandparentClaim);
...@@ -606,10 +569,7 @@ contract GamePlayer { ...@@ -606,10 +569,7 @@ contract GamePlayer {
} }
} else { } else {
// Don't defend a claim we would've made ourselves. // Don't defend a claim we would've made ourselves.
if ( if (parentPos.depth() % 2 == 0 && Claim.unwrap(claimAt(15)) == Claim.unwrap(gameProxy.rootClaim())) {
parentPos.depth() % 2 == 0 &&
Claim.unwrap(claimAt(15)) == Claim.unwrap(gameProxy.rootClaim())
) {
return; return;
} }
...@@ -628,23 +588,14 @@ contract GamePlayer { ...@@ -628,23 +588,14 @@ contract GamePlayer {
/// @notice Returns the state at the trace index within the player's trace. /// @notice Returns the state at the trace index within the player's trace.
function traceAt(uint256 _traceIndex) public view returns (uint256 state_) { function traceAt(uint256 _traceIndex) public view returns (uint256 state_) {
return return uint256(uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex]));
uint256(
uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex])
);
} }
/// @notice Returns the player's claim that commits to a given trace index. /// @notice Returns the player's claim that commits to a given trace index.
function claimAt(uint256 _traceIndex) public view returns (Claim claim_) { function claimAt(uint256 _traceIndex) public view returns (Claim claim_) {
return return Claim.wrap(
Claim.wrap( keccak256(abi.encode(_traceIndex >= trace.length ? trace.length - 1 : _traceIndex, traceAt(_traceIndex)))
keccak256( );
abi.encode(
_traceIndex >= trace.length ? trace.length - 1 : _traceIndex,
traceAt(_traceIndex)
)
)
);
} }
/// @notice Returns the player's claim that commits to a given trace index. /// @notice Returns the player's claim that commits to a given trace index.
...@@ -663,14 +614,8 @@ contract OneVsOne_Arena is FaultDisputeGame_Init { ...@@ -663,14 +614,8 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
/// @dev The challenger. /// @dev The challenger.
GamePlayer internal challenger; GamePlayer internal challenger;
function init( function init(GamePlayer _defender, GamePlayer _challenger, uint256 _finalTraceIndex) public {
GamePlayer _defender, Claim rootClaim = Claim.wrap(keccak256(abi.encode(_finalTraceIndex, _defender.traceAt(_finalTraceIndex))));
GamePlayer _challenger,
uint256 _finalTraceIndex
) public {
Claim rootClaim = Claim.wrap(
keccak256(abi.encode(_finalTraceIndex, _defender.traceAt(_finalTraceIndex)))
);
super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM); super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM);
defender = _defender; defender = _defender;
challenger = _challenger; challenger = _challenger;
...@@ -995,11 +940,7 @@ contract HonestPlayer_QuarterTrace is GamePlayer { ...@@ -995,11 +940,7 @@ contract HonestPlayer_QuarterTrace is GamePlayer {
} }
contract VariableDivergentPlayer is GamePlayer { contract VariableDivergentPlayer is GamePlayer {
constructor( constructor(bytes memory _absolutePrestate, uint256 _traceLength, uint256 _divergeAt) {
bytes memory _absolutePrestate,
uint256 _traceLength,
uint256 _divergeAt
) {
uint8 absolutePrestate = uint8(_absolutePrestate[31]); uint8 absolutePrestate = uint8(_absolutePrestate[31]);
bytes memory _trace = new bytes(_traceLength); bytes memory _trace = new bytes(_traceLength);
for (uint8 i = 0; i < _trace.length; i++) { for (uint8 i = 0; i < _trace.length; i++) {
...@@ -1024,11 +965,7 @@ contract AlphabetVM is IBigStepper { ...@@ -1024,11 +965,7 @@ contract AlphabetVM is IBigStepper {
} }
/// @inheritdoc IBigStepper /// @inheritdoc IBigStepper
function step(bytes calldata _stateData, bytes calldata) function step(bytes calldata _stateData, bytes calldata) external view returns (bytes32 postState_) {
external
view
returns (bytes32 postState_)
{
uint256 traceIndex; uint256 traceIndex;
uint256 claim; uint256 claim;
if (keccak256(_stateData) == Claim.unwrap(ABSOLUTE_PRESTATE)) { if (keccak256(_stateData) == Claim.unwrap(ABSOLUTE_PRESTATE)) {
......
...@@ -31,9 +31,7 @@ contract FeeVault_Test is Bridge_Initializer { ...@@ -31,9 +31,7 @@ contract FeeVault_Test is Bridge_Initializer {
); );
vm.etch( vm.etch(
Predeploys.L1_FEE_VAULT, Predeploys.L1_FEE_VAULT,
address( address(new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)).code
new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)
).code
); );
vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault"); vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault");
......
...@@ -94,9 +94,8 @@ contract GasPriceOracle_Test is CommonTest { ...@@ -94,9 +94,8 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `setGasPrice` reverts since it was removed in bedrock. /// @dev Tests that `setGasPrice` reverts since it was removed in bedrock.
function test_setGasPrice_doesNotExist_reverts() external { function test_setGasPrice_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = address(gasOracle).call( (bool success, bytes memory returndata) =
abi.encodeWithSignature("setGasPrice(uint256)", 1) address(gasOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1));
);
assertEq(success, false); assertEq(success, false);
assertEq(returndata, hex""); assertEq(returndata, hex"");
...@@ -104,9 +103,8 @@ contract GasPriceOracle_Test is CommonTest { ...@@ -104,9 +103,8 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock. /// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock.
function test_setL1BaseFee_doesNotExist_reverts() external { function test_setL1BaseFee_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = address(gasOracle).call( (bool success, bytes memory returndata) =
abi.encodeWithSignature("setL1BaseFee(uint256)", 1) address(gasOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1));
);
assertEq(success, false); assertEq(success, false);
assertEq(returndata, hex""); assertEq(returndata, hex"");
......
...@@ -16,10 +16,7 @@ contract Hashing_hashDepositSource_Test is CommonTest { ...@@ -16,10 +16,7 @@ contract Hashing_hashDepositSource_Test is CommonTest {
/// @notice Tests that hashDepositSource returns the correct hash in a simple case. /// @notice Tests that hashDepositSource returns the correct hash in a simple case.
function test_hashDepositSource_succeeds() external { function test_hashDepositSource_succeeds() external {
assertEq( assertEq(
Hashing.hashDepositSource( Hashing.hashDepositSource(0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959, 0x1),
0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,
0x1
),
0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc
); );
} }
...@@ -35,7 +32,9 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest { ...@@ -35,7 +32,9 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
// Ensure the version is valid. // Ensure the version is valid.
uint16 version = uint16(bound(uint256(_version), 0, 1)); uint16 version = uint16(bound(uint256(_version), 0, 1));
uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version); uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);
...@@ -52,16 +51,11 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest { ...@@ -52,16 +51,11 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest {
address _sender, address _sender,
bytes memory _message, bytes memory _message,
uint256 _messageNonce uint256 _messageNonce
) external { )
external
{
assertEq( assertEq(
keccak256( keccak256(LegacyCrossDomainUtils.encodeXDomainCalldata(_target, _sender, _message, _messageNonce)),
LegacyCrossDomainUtils.encodeXDomainCalldata(
_target,
_sender,
_message,
_messageNonce
)
),
Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce) Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)
); );
} }
...@@ -76,11 +70,11 @@ contract Hashing_hashWithdrawal_Test is CommonTest { ...@@ -76,11 +70,11 @@ contract Hashing_hashWithdrawal_Test is CommonTest {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
assertEq( assertEq(
Hashing.hashWithdrawal( Hashing.hashWithdrawal(Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)),
Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)
),
ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data) ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)
); );
} }
...@@ -92,7 +86,9 @@ contract Hashing_hashOutputRootProof_Test is CommonTest { ...@@ -92,7 +86,9 @@ contract Hashing_hashOutputRootProof_Test is CommonTest {
bytes32 _stateRoot, bytes32 _stateRoot,
bytes32 _messagePasserStorageRoot, bytes32 _messagePasserStorageRoot,
bytes32 _latestBlockhash bytes32 _latestBlockhash
) external { )
external
{
bytes32 version = 0; bytes32 version = 0;
assertEq( assertEq(
Hashing.hashOutputRootProof( Hashing.hashOutputRootProof(
...@@ -103,12 +99,7 @@ contract Hashing_hashOutputRootProof_Test is CommonTest { ...@@ -103,12 +99,7 @@ contract Hashing_hashOutputRootProof_Test is CommonTest {
latestBlockhash: _latestBlockhash latestBlockhash: _latestBlockhash
}) })
), ),
ffi.hashOutputRootProof( ffi.hashOutputRootProof(version, _stateRoot, _messagePasserStorageRoot, _latestBlockhash)
version,
_stateRoot,
_messagePasserStorageRoot,
_latestBlockhash
)
); );
} }
} }
...@@ -123,7 +114,9 @@ contract Hashing_hashDepositTransaction_Test is CommonTest { ...@@ -123,7 +114,9 @@ contract Hashing_hashDepositTransaction_Test is CommonTest {
uint64 _gas, uint64 _gas,
bytes memory _data, bytes memory _data,
uint64 _logIndex uint64 _logIndex
) external { )
external
{
assertEq( assertEq(
Hashing.hashDepositTransaction( Hashing.hashDepositTransaction(
Types.UserDepositTransaction( Types.UserDepositTransaction(
......
...@@ -7,13 +7,11 @@ import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; ...@@ -7,13 +7,11 @@ import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { OptimistInviter } from "../src/periphery/op-nft/OptimistInviter.sol"; import { OptimistInviter } from "../src/periphery/op-nft/OptimistInviter.sol";
import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
ECDSAUpgradeable
} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
contract TestERC20 is ERC20 { contract TestERC20 is ERC20 {
constructor() ERC20("TEST", "TST", 18) {} constructor() ERC20("TEST", "TST", 18) { }
function mint(address to, uint256 value) public { function mint(address to, uint256 value) public {
_mint(to, value); _mint(to, value);
...@@ -21,13 +19,13 @@ contract TestERC20 is ERC20 { ...@@ -21,13 +19,13 @@ contract TestERC20 is ERC20 {
} }
contract TestERC721 is ERC721 { contract TestERC721 is ERC721 {
constructor() ERC721("TEST", "TST") {} constructor() ERC721("TEST", "TST") { }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
_mint(to, tokenId); _mint(to, tokenId);
} }
function tokenURI(uint256) public pure virtual override returns (string memory) {} function tokenURI(uint256) public pure virtual override returns (string memory) { }
} }
contract CallRecorder { contract CallRecorder {
...@@ -71,14 +69,11 @@ contract SimpleStorage { ...@@ -71,14 +69,11 @@ contract SimpleStorage {
/// in OptimistInviter.t.sol for reusability. /// in OptimistInviter.t.sol for reusability.
contract OptimistInviterHelper { contract OptimistInviterHelper {
/// @notice EIP712 typehash for the ClaimableInvite type. /// @notice EIP712 typehash for the ClaimableInvite type.
bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
/// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature.
bytes32 public constant EIP712_DOMAIN_TYPEHASH = bytes32 public constant EIP712_DOMAIN_TYPEHASH =
keccak256( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
/// @notice Address of OptimistInviter contract we are testing. /// @notice Address of OptimistInviter contract we are testing.
OptimistInviter public optimistInviter; OptimistInviter public optimistInviter;
...@@ -102,14 +97,7 @@ contract OptimistInviterHelper { ...@@ -102,14 +97,7 @@ contract OptimistInviterHelper {
pure pure
returns (bytes32) returns (bytes32)
{ {
return return keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce));
keccak256(
abi.encode(
CLAIMABLE_INVITE_TYPEHASH,
_claimableInvite.issuer,
_claimableInvite.nonce
)
);
} }
/// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use
...@@ -122,29 +110,21 @@ contract OptimistInviterHelper { ...@@ -122,29 +110,21 @@ contract OptimistInviterHelper {
/// @notice Returns a ClaimableInvite with the issuer and current nonce. /// @notice Returns a ClaimableInvite with the issuer and current nonce.
/// @param _issuer Issuer to include in the ClaimableInvite. /// @param _issuer Issuer to include in the ClaimableInvite.
/// @return ClaimableInvite that can be hashed & signed. /// @return ClaimableInvite that can be hashed & signed.
function getClaimableInviteWithNewNonce(address _issuer) function getClaimableInviteWithNewNonce(address _issuer) public returns (OptimistInviter.ClaimableInvite memory) {
public
returns (OptimistInviter.ClaimableInvite memory)
{
return OptimistInviter.ClaimableInvite(_issuer, consumeNonce()); return OptimistInviter.ClaimableInvite(_issuer, consumeNonce());
} }
/// @notice Computes the EIP712 digest with default correct parameters. /// @notice Computes the EIP712 digest with default correct parameters.
/// @param _claimableInvite ClaimableInvite struct to hash. /// @param _claimableInvite ClaimableInvite struct to hash.
/// @return EIP-712 compatible digest. /// @return EIP-712 compatible digest.
function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite) function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite) public view returns (bytes32) {
public return getDigestWithEIP712Domain(
view _claimableInvite,
returns (bytes32) bytes(name),
{ bytes(optimistInviter.EIP712_VERSION()),
return block.chainid,
getDigestWithEIP712Domain( address(optimistInviter)
_claimableInvite, );
bytes(name),
bytes(optimistInviter.EIP712_VERSION()),
block.chainid,
address(optimistInviter)
);
} }
/// @notice Computes the EIP712 digest with the given domain parameters. /// @notice Computes the EIP712 digest with the given domain parameters.
...@@ -161,18 +141,15 @@ contract OptimistInviterHelper { ...@@ -161,18 +141,15 @@ contract OptimistInviterHelper {
bytes memory _version, bytes memory _version,
uint256 _chainid, uint256 _chainid,
address _verifyingContract address _verifyingContract
) public pure returns (bytes32) { )
public
pure
returns (bytes32)
{
bytes32 domainSeparator = keccak256( bytes32 domainSeparator = keccak256(
abi.encode( abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract)
EIP712_DOMAIN_TYPEHASH,
keccak256(_name),
keccak256(_version),
_chainid,
_verifyingContract
)
); );
return return ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite));
ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite));
} }
} }
...@@ -184,28 +161,19 @@ contract TestERC1271Wallet is Ownable, IERC1271 { ...@@ -184,28 +161,19 @@ contract TestERC1271Wallet is Ownable, IERC1271 {
transferOwnership(originalOwner); transferOwnership(originalOwner);
} }
function isValidSignature(bytes32 hash, bytes memory signature) function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) {
public return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
view
override
returns (bytes4 magicValue)
{
return
ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
} }
} }
/// @notice Simple helper contract that helps with testing the Faucet contract. /// @notice Simple helper contract that helps with testing the Faucet contract.
contract FaucetHelper { contract FaucetHelper {
/// @notice EIP712 typehash for the Proof type. /// @notice EIP712 typehash for the Proof type.
bytes32 public constant PROOF_TYPEHASH = bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
/// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature.
bytes32 public constant EIP712_DOMAIN_TYPEHASH = bytes32 public constant EIP712_DOMAIN_TYPEHASH =
keccak256( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
/// @notice Keeps track of current nonce to generate new nonces for each drip. /// @notice Keeps track of current nonce to generate new nonces for each drip.
uint256 public currentNonce; uint256 public currentNonce;
...@@ -220,11 +188,7 @@ contract FaucetHelper { ...@@ -220,11 +188,7 @@ contract FaucetHelper {
/// @notice Returns the hash of the struct Proof. /// @notice Returns the hash of the struct Proof.
/// @param _proof Proof struct to hash. /// @param _proof Proof struct to hash.
/// @return EIP-712 typed struct hash. /// @return EIP-712 typed struct hash.
function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof) function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof) public pure returns (bytes32) {
public
pure
returns (bytes32)
{
return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id)); return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id));
} }
...@@ -244,15 +208,13 @@ contract FaucetHelper { ...@@ -244,15 +208,13 @@ contract FaucetHelper {
bytes memory _version, bytes memory _version,
uint256 _chainid, uint256 _chainid,
address _verifyingContract address _verifyingContract
) public pure returns (bytes32) { )
public
pure
returns (bytes32)
{
bytes32 domainSeparator = keccak256( bytes32 domainSeparator = keccak256(
abi.encode( abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract)
EIP712_DOMAIN_TYPEHASH,
keccak256(_name),
keccak256(_version),
_chainid,
_verifyingContract
)
); );
return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof)); return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof));
} }
......
...@@ -40,7 +40,9 @@ contract L1BlockTest is CommonTest { ...@@ -40,7 +40,9 @@ contract L1BlockTest is CommonTest {
bytes32 bt, bytes32 bt,
uint256 fo, uint256 fo,
uint256 fs uint256 fs
) external { )
external
{
vm.prank(depositor); vm.prank(depositor);
lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs); lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);
assertEq(lb.number(), n); assertEq(lb.number(), n);
......
...@@ -44,14 +44,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -44,14 +44,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
0, 0,
L1Messenger.baseGas(hex"ff", 100), L1Messenger.baseGas(hex"ff", 100),
false, false,
Encoding.encodeCrossDomainMessage( Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff")
L1Messenger.messageNonce(),
alice,
recipient,
0,
100,
hex"ff"
)
) )
); );
...@@ -64,14 +57,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -64,14 +57,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
0, 0,
L1Messenger.baseGas(hex"ff", 100), L1Messenger.baseGas(hex"ff", 100),
false, false,
Encoding.encodeCrossDomainMessage( Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff")
L1Messenger.messageNonce(),
alice,
recipient,
0,
100,
hex"ff"
)
); );
// SentMessage event // SentMessage event
...@@ -112,9 +98,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -112,9 +98,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Expect a revert. // Expect a revert.
vm.expectRevert( vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
"CrossDomainMessenger: only version 0 or 1 messages are supported at this time"
);
// Try to relay a v2 message. // Try to relay a v2 message.
vm.prank(address(op)); vm.prank(address(op));
...@@ -143,12 +127,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -143,12 +127,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
bytes32 hash = Hashing.hashCrossDomainMessage( bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, hex"1111"
sender,
target,
0,
0,
hex"1111"
); );
emit RelayedMessage(hash); emit RelayedMessage(hash);
...@@ -179,23 +158,13 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -179,23 +158,13 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.prank(address(op)); vm.prank(address(op));
vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage( L1Messenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
sender,
target,
0,
0,
message
); );
vm.store(address(op), 0, bytes32(abi.encode(sender))); vm.store(address(op), 0, bytes32(abi.encode(sender)));
vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage( L1Messenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
sender,
target,
0,
0,
message
); );
} }
...@@ -206,16 +175,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -206,16 +175,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
bytes memory message = hex"1111"; bytes memory message = hex"1111";
vm.expectRevert( vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address");
"CrossDomainMessenger: value must be zero unless message is from a system address"
);
L1Messenger.relayMessage{ value: 100 }( L1Messenger.relayMessage{ value: 100 }(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
sender,
target,
0,
0,
message
); );
} }
...@@ -230,12 +192,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -230,12 +192,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.prank(address(op)); vm.prank(address(op));
L1Messenger.relayMessage( L1Messenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), address(0), address(0), 0, 0, hex""
address(0),
address(0),
0,
0,
hex""
); );
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
...@@ -253,12 +210,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -253,12 +210,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectCall(target, hex"1111"); vm.expectCall(target, hex"1111");
bytes32 hash = Hashing.hashCrossDomainMessage( bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, value, 0, hex"1111"
sender,
target,
value,
0,
hex"1111"
); );
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
......
...@@ -14,7 +14,7 @@ import { L1ERC721Bridge } from "../src/L1/L1ERC721Bridge.sol"; ...@@ -14,7 +14,7 @@ import { L1ERC721Bridge } from "../src/L1/L1ERC721Bridge.sol";
/// @dev Test ERC721 contract. /// @dev Test ERC721 contract.
contract TestERC721 is ERC721 { contract TestERC721 is ERC721 {
constructor() ERC721("Test", "TST") {} constructor() ERC721("Test", "TST") { }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
_mint(to, tokenId); _mint(to, tokenId);
...@@ -78,15 +78,8 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -78,15 +78,8 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
address(L2Bridge), address(L2Bridge),
abi.encodeCall( abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721, L2ERC721Bridge.finalizeBridgeERC721,
( (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
address(remoteToken), ),
address(localToken),
alice,
alice,
tokenId,
hex"5678"
)
),
1234 1234
) )
) )
...@@ -94,14 +87,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -94,14 +87,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated( emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
...@@ -174,7 +160,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -174,7 +160,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encodeCall( abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721, L2ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678")
), ),
1234 1234
) )
) )
...@@ -182,25 +168,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -182,25 +168,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated( emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
bob,
tokenId,
hex"5678"
);
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L1Bridge.bridgeERC721To( L1Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
// Token is locked in the bridge. // Token is locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), true); assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
...@@ -239,14 +211,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -239,14 +211,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner"); vm.expectRevert("ERC721: transfer from incorrect owner");
L1Bridge.bridgeERC721To( L1Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
...@@ -261,14 +226,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -261,14 +226,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ERC721BridgeFinalized( emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
...@@ -277,14 +235,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -277,14 +235,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encode(Predeploys.L2_ERC721_BRIDGE) abi.encode(Predeploys.L2_ERC721_BRIDGE)
); );
vm.prank(address(L1Messenger)); vm.prank(address(L1Messenger));
L1Bridge.finalizeBridgeERC721( L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
...@@ -297,14 +248,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -297,14 +248,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1Bridge.finalizeBridgeERC721( L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
/// @dev Tests that the ERC721 bridge finalize reverts when not called /// @dev Tests that the ERC721 bridge finalize reverts when not called
...@@ -312,20 +256,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -312,20 +256,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L1Messenger), address(L1Messenger), abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encode(alice)
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),
abi.encode(alice)
); );
vm.prank(address(L1Messenger)); vm.prank(address(L1Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1Bridge.finalizeBridgeERC721( L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
/// @dev Tests that the ERC721 bridge finalize reverts when the local token /// @dev Tests that the ERC721 bridge finalize reverts when the local token
...@@ -339,14 +274,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -339,14 +274,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
); );
vm.prank(address(L1Messenger)); vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: local token cannot be self"); vm.expectRevert("L1ERC721Bridge: local token cannot be self");
L1Bridge.finalizeBridgeERC721( L1Bridge.finalizeBridgeERC721(address(L1Bridge), address(remoteToken), alice, alice, tokenId, hex"5678");
address(L1Bridge),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
/// @dev Tests that the ERC721 bridge finalize reverts when the remote token /// @dev Tests that the ERC721 bridge finalize reverts when the remote token
...@@ -360,13 +288,6 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -360,13 +288,6 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
); );
vm.prank(address(L1Messenger)); vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge"); vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge");
L1Bridge.finalizeBridgeERC721( L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
} }
...@@ -44,7 +44,7 @@ contract L1StandardBridge_Initialize_Test is Bridge_Initializer { ...@@ -44,7 +44,7 @@ contract L1StandardBridge_Initialize_Test is Bridge_Initializer {
} }
} }
contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {} contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer { }
contract L1StandardBridge_Receive_Test is Bridge_Initializer { contract L1StandardBridge_Receive_Test is Bridge_Initializer {
/// @dev Tests receive bridges ETH successfully. /// @dev Tests receive bridges ETH successfully.
...@@ -63,25 +63,19 @@ contract L1StandardBridge_Receive_Test is Bridge_Initializer { ...@@ -63,25 +63,19 @@ contract L1StandardBridge_Receive_Test is Bridge_Initializer {
abi.encodeWithSelector( abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector, CrossDomainMessenger.sendMessage.selector,
address(L2Bridge), address(L2Bridge),
abi.encodeWithSelector( abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""),
StandardBridge.finalizeBridgeETH.selector,
alice,
alice,
100,
hex""
),
200_000 200_000
) )
); );
vm.prank(alice, alice); vm.prank(alice, alice);
(bool success, ) = address(L1Bridge).call{ value: 100 }(hex""); (bool success,) = address(L1Bridge).call{ value: 100 }(hex"");
assertEq(success, true); assertEq(success, true);
assertEq(address(op).balance, 100); assertEq(address(op).balance, 100);
} }
} }
contract L1StandardBridge_Receive_TestFail {} contract L1StandardBridge_Receive_TestFail { }
contract PreBridgeETH is Bridge_Initializer { contract PreBridgeETH is Bridge_Initializer {
/// @dev Asserts the expected calls and events for bridging ETH depending /// @dev Asserts the expected calls and events for bridging ETH depending
...@@ -92,46 +86,24 @@ contract PreBridgeETH is Bridge_Initializer { ...@@ -92,46 +86,24 @@ contract PreBridgeETH is Bridge_Initializer {
uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
bytes memory message = abi.encodeWithSelector( bytes memory message =
StandardBridge.finalizeBridgeETH.selector, abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 500, hex"dead");
alice,
alice,
500,
hex"dead"
);
if (isLegacy) { if (isLegacy) {
vm.expectCall( vm.expectCall(
address(L1Bridge), address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex"dead")
500,
abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex"dead")
); );
} else { } else {
vm.expectCall( vm.expectCall(address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex"dead"));
address(L1Bridge),
500,
abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex"dead")
);
} }
vm.expectCall( vm.expectCall(
address(L1Messenger), address(L1Messenger),
500, 500,
abi.encodeWithSelector( abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 50000)
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
50000
)
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 500, 50000, message
nonce,
address(L1Bridge),
address(L2Bridge),
500,
50000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 50000); uint64 baseGas = L1Messenger.baseGas(message, 50000);
...@@ -139,22 +111,11 @@ contract PreBridgeETH is Bridge_Initializer { ...@@ -139,22 +111,11 @@ contract PreBridgeETH is Bridge_Initializer {
address(op), address(op),
500, 500,
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, OptimismPortal.depositTransaction.selector, address(L2Messenger), 500, baseGas, false, innerMessage
address(L2Messenger),
500,
baseGas,
false,
innerMessage
) )
); );
bytes memory opaqueData = abi.encodePacked( bytes memory opaqueData = abi.encodePacked(uint256(500), uint256(500), baseGas, false, innerMessage);
uint256(500),
uint256(500),
baseGas,
false,
innerMessage
);
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(L1Bridge));
emit ETHDepositInitiated(alice, alice, 500, hex"dead"); emit ETHDepositInitiated(alice, alice, 500, hex"dead");
...@@ -225,68 +186,37 @@ contract PreBridgeETHTo is Bridge_Initializer { ...@@ -225,68 +186,37 @@ contract PreBridgeETHTo is Bridge_Initializer {
if (isLegacy) { if (isLegacy) {
vm.expectCall( vm.expectCall(
address(L1Bridge), address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex"dead")
600,
abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex"dead")
); );
} else { } else {
vm.expectCall( vm.expectCall(
address(L1Bridge), address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex"dead")
600,
abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex"dead")
); );
} }
bytes memory message = abi.encodeWithSelector( bytes memory message =
StandardBridge.finalizeBridgeETH.selector, abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, bob, 600, hex"dead");
alice,
bob,
600,
hex"dead"
);
// the L1 bridge should call // the L1 bridge should call
// L1CrossDomainMessenger.sendMessage // L1CrossDomainMessenger.sendMessage
vm.expectCall( vm.expectCall(
address(L1Messenger), address(L1Messenger),
abi.encodeWithSelector( abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 60000)
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
60000
)
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 600, 60000, message
nonce,
address(L1Bridge),
address(L2Bridge),
600,
60000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 60000); uint64 baseGas = L1Messenger.baseGas(message, 60000);
vm.expectCall( vm.expectCall(
address(op), address(op),
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, OptimismPortal.depositTransaction.selector, address(L2Messenger), 600, baseGas, false, innerMessage
address(L2Messenger),
600,
baseGas,
false,
innerMessage
) )
); );
bytes memory opaqueData = abi.encodePacked( bytes memory opaqueData = abi.encodePacked(uint256(600), uint256(600), baseGas, false, innerMessage);
uint256(600),
uint256(600),
baseGas,
false,
innerMessage
);
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(L1Bridge));
emit ETHDepositInitiated(alice, bob, 600, hex"dead"); emit ETHDepositInitiated(alice, bob, 600, hex"dead");
...@@ -337,7 +267,7 @@ contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo { ...@@ -337,7 +267,7 @@ contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {
} }
} }
contract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {} contract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer { }
contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {
using stdStorage for StdStorage; using stdStorage for StdStorage;
...@@ -365,61 +295,32 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { ...@@ -365,61 +295,32 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {
// The L1Bridge should transfer alice's tokens to itself // The L1Bridge should transfer alice's tokens to itself
vm.expectCall( vm.expectCall(
address(L1Token), address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)
abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)
); );
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector, StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, alice, 100, hex""
address(L2Token),
address(L1Token),
alice,
alice,
100,
hex""
); );
// the L1 bridge should call L1CrossDomainMessenger.sendMessage // the L1 bridge should call L1CrossDomainMessenger.sendMessage
vm.expectCall( vm.expectCall(
address(L1Messenger), address(L1Messenger),
abi.encodeWithSelector( abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000)
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
10000
)
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message
nonce,
address(L1Bridge),
address(L2Bridge),
0,
10000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 10000); uint64 baseGas = L1Messenger.baseGas(message, 10000);
vm.expectCall( vm.expectCall(
address(op), address(op),
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage
address(L2Messenger),
0,
baseGas,
false,
innerMessage
) )
); );
bytes memory opaqueData = abi.encodePacked( bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage);
uint256(0),
uint256(0),
baseGas,
false,
innerMessage
);
// Should emit both the bedrock and legacy events // Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(L1Bridge));
...@@ -472,33 +373,15 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { ...@@ -472,33 +373,15 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector, StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, bob, 1000, hex""
address(L2Token),
address(L1Token),
alice,
bob,
1000,
hex""
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message
nonce,
address(L1Bridge),
address(L2Bridge),
0,
10000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 10000); uint64 baseGas = L1Messenger.baseGas(message, 10000);
bytes memory opaqueData = abi.encodePacked( bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage);
uint256(0),
uint256(0),
baseGas,
false,
innerMessage
);
deal(address(L1Token), alice, 100000, true); deal(address(L1Token), alice, 100000, true);
...@@ -527,28 +410,17 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { ...@@ -527,28 +410,17 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {
// the L1 bridge should call L1CrossDomainMessenger.sendMessage // the L1 bridge should call L1CrossDomainMessenger.sendMessage
vm.expectCall( vm.expectCall(
address(L1Messenger), address(L1Messenger),
abi.encodeWithSelector( abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000)
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
10000
)
); );
// The L1 XDM should call OptimismPortal.depositTransaction // The L1 XDM should call OptimismPortal.depositTransaction
vm.expectCall( vm.expectCall(
address(op), address(op),
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage
address(L2Messenger),
0,
baseGas,
false,
innerMessage
) )
); );
vm.expectCall( vm.expectCall(
address(L1Token), address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)
abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)
); );
vm.prank(alice); vm.prank(alice);
...@@ -590,7 +462,7 @@ contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer { ...@@ -590,7 +462,7 @@ contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {
} }
} }
contract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {} contract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer { }
contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
using stdStorage for StdStorage; using stdStorage for StdStorage;
...@@ -602,12 +474,8 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { ...@@ -602,12 +474,8 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
function test_finalizeERC20Withdrawal_succeeds() external { function test_finalizeERC20Withdrawal_succeeds() external {
deal(address(L1Token), address(L1Bridge), 100, true); deal(address(L1Token), address(L1Bridge), 100, true);
uint256 slot = stdstore uint256 slot = stdstore.target(address(L1Bridge)).sig("deposits(address,address)").with_key(address(L1Token))
.target(address(L1Bridge)) .with_key(address(L2Token)).find();
.sig("deposits(address,address)")
.with_key(address(L1Token))
.with_key(address(L2Token))
.find();
// Give the L1 bridge some ERC20 tokens // Give the L1 bridge some ERC20 tokens
vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100))); vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));
...@@ -619,10 +487,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { ...@@ -619,10 +487,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(L1Bridge));
emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex"");
vm.expectCall( vm.expectCall(address(L1Token), abi.encodeWithSelector(ERC20.transfer.selector, alice, 100));
address(L1Token),
abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)
);
vm.mockCall( vm.mockCall(
address(L1Bridge.messenger()), address(L1Bridge.messenger()),
...@@ -630,14 +495,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { ...@@ -630,14 +495,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(L1Bridge.OTHER_BRIDGE()))
); );
vm.prank(address(L1Bridge.messenger())); vm.prank(address(L1Bridge.messenger()));
L1Bridge.finalizeERC20Withdrawal( L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
address(L1Token),
address(L2Token),
alice,
alice,
100,
hex""
);
assertEq(L1Token.balanceOf(address(L1Bridge)), 0); assertEq(L1Token.balanceOf(address(L1Bridge)), 0);
assertEq(L1Token.balanceOf(address(alice)), 100); assertEq(L1Token.balanceOf(address(alice)), 100);
...@@ -654,14 +512,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer ...@@ -654,14 +512,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer
); );
vm.prank(address(28)); vm.prank(address(28));
vm.expectRevert("StandardBridge: function can only be called from the other bridge"); vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal( L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
address(L1Token),
address(L2Token),
alice,
alice,
100,
hex""
);
} }
/// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge.
...@@ -673,14 +524,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer ...@@ -673,14 +524,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer
); );
vm.prank(address(L1Bridge.messenger())); vm.prank(address(L1Bridge.messenger()));
vm.expectRevert("StandardBridge: function can only be called from the other bridge"); vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal( L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
address(L1Token),
address(L2Token),
alice,
alice,
100,
hex""
);
} }
} }
......
...@@ -29,14 +29,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -29,14 +29,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
/// @dev Tests that `sendMessage` executes successfully. /// @dev Tests that `sendMessage` executes successfully.
function test_sendMessage_succeeds() external { function test_sendMessage_succeeds() external {
bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage( bytes memory xDomainCallData =
L2Messenger.messageNonce(), Encoding.encodeCrossDomainMessage(L2Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff");
alice,
recipient,
0,
100,
hex"ff"
);
vm.expectCall( vm.expectCall(
address(messagePasser), address(messagePasser),
abi.encodeWithSelector( abi.encodeWithSelector(
...@@ -95,9 +89,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -95,9 +89,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
// Expect a revert. // Expect a revert.
vm.expectRevert( vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
"CrossDomainMessenger: only version 0 or 1 messages are supported at this time"
);
// Try to relay a v2 message. // Try to relay a v2 message.
vm.prank(caller); vm.prank(caller);
...@@ -123,14 +115,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -123,14 +115,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
bytes32 hash = Hashing.hashCrossDomainMessage( bytes32 hash =
Encoding.encodeVersionedNonce(0, 1), Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, hex"1111");
sender,
target,
0,
0,
hex"1111"
);
emit RelayedMessage(hash); emit RelayedMessage(hash);
...@@ -159,14 +145,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -159,14 +145,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
vm.prank(caller); vm.prank(caller);
vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage( L1Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message);
Encoding.encodeVersionedNonce(0, 1),
sender,
target,
0,
0,
message
);
} }
/// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender` /// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender`
...@@ -177,14 +156,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -177,14 +156,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
vm.prank(caller); vm.prank(caller);
L2Messenger.relayMessage( L2Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex"");
Encoding.encodeVersionedNonce(0, 1),
address(0),
address(0),
0,
0,
hex""
);
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender(); L2Messenger.xDomainMessageSender();
...@@ -199,14 +171,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -199,14 +171,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
uint256 value = 100; uint256 value = 100;
bytes32 hash = Hashing.hashCrossDomainMessage( bytes32 hash =
Encoding.encodeVersionedNonce(0, 1), Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, value, 0, hex"1111");
sender,
target,
value,
0,
hex"1111"
);
vm.etch(target, address(new Reverter()).code); vm.etch(target, address(new Reverter()).code);
vm.deal(address(caller), value); vm.deal(address(caller), value);
......
...@@ -13,7 +13,7 @@ import { OptimismMintableERC721 } from "../src/universal/OptimismMintableERC721. ...@@ -13,7 +13,7 @@ import { OptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.
import { L2ERC721Bridge } from "../src/L2/L2ERC721Bridge.sol"; import { L2ERC721Bridge } from "../src/L2/L2ERC721Bridge.sol";
contract TestERC721 is ERC721 { contract TestERC721 is ERC721 {
constructor() ERC721("Test", "TST") {} constructor() ERC721("Test", "TST") { }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
_mint(to, tokenId); _mint(to, tokenId);
...@@ -21,9 +21,12 @@ contract TestERC721 is ERC721 { ...@@ -21,9 +21,12 @@ contract TestERC721 is ERC721 {
} }
contract TestMintableERC721 is OptimismMintableERC721 { contract TestMintableERC721 is OptimismMintableERC721 {
constructor(address _bridge, address _remoteToken) constructor(
address _bridge,
address _remoteToken
)
OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST") OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST")
{} { }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
_mint(to, tokenId); _mint(to, tokenId);
...@@ -88,15 +91,8 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -88,15 +91,8 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
address(L1Bridge), address(L1Bridge),
abi.encodeCall( abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721, L2ERC721Bridge.finalizeBridgeERC721,
( (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
address(remoteToken), ),
address(localToken),
alice,
alice,
tokenId,
hex"5678"
)
),
1234 1234
) )
) )
...@@ -104,14 +100,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -104,14 +100,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated( emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
...@@ -180,7 +169,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -180,7 +169,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encodeCall( abi.encodeCall(
L1ERC721Bridge.finalizeBridgeERC721, L1ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678")
), ),
1234 1234
) )
) )
...@@ -188,25 +177,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -188,25 +177,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated( emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
bob,
tokenId,
hex"5678"
);
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L2Bridge.bridgeERC721To( L2Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
// Token is burned. // Token is burned.
vm.expectRevert("ERC721: invalid token ID"); vm.expectRevert("ERC721: invalid token ID");
...@@ -240,14 +215,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -240,14 +215,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
L2Bridge.bridgeERC721To( L2Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -261,14 +229,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -261,14 +229,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ERC721BridgeFinalized( emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
...@@ -277,14 +238,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -277,14 +238,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encode(L1Bridge) abi.encode(L1Bridge)
); );
vm.prank(address(L2Messenger)); vm.prank(address(L2Messenger));
L2Bridge.finalizeBridgeERC721( L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -310,12 +264,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -310,12 +264,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.prank(address(L2Messenger)); vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token interface is not compliant"); vm.expectRevert("L2ERC721Bridge: local token interface is not compliant");
L2Bridge.finalizeBridgeERC721( L2Bridge.finalizeBridgeERC721(
address(address(nonCompliantToken)), address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678"
address(address(0x01)),
alice,
alice,
tokenId,
hex"5678"
); );
} }
...@@ -324,34 +273,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -324,34 +273,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2Bridge.finalizeBridgeERC721( L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
/// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge. /// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge.
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L2Messenger), address(L2Messenger), abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encode(alice)
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(alice)
); );
vm.prank(address(L2Messenger)); vm.prank(address(L2Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2Bridge.finalizeBridgeERC721( L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
/// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the /// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the
...@@ -365,14 +298,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -365,14 +298,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
); );
vm.prank(address(L2Messenger)); vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token cannot be self"); vm.expectRevert("L2ERC721Bridge: local token cannot be self");
L2Bridge.finalizeBridgeERC721( L2Bridge.finalizeBridgeERC721(address(L2Bridge), address(remoteToken), alice, alice, tokenId, hex"5678");
address(L2Bridge),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
/// @dev Tests that `finalizeBridgeERC721` reverts when already finalized. /// @dev Tests that `finalizeBridgeERC721` reverts when already finalized.
...@@ -385,14 +311,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -385,14 +311,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
); );
vm.prank(address(L2Messenger)); vm.prank(address(L2Messenger));
vm.expectRevert("ERC721: token already minted"); vm.expectRevert("ERC721: token already minted");
L2Bridge.finalizeBridgeERC721( L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
} }
} }
......
...@@ -190,16 +190,10 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { ...@@ -190,16 +190,10 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer {
assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp); assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);
// check timestamp for the first block after the starting block // check timestamp for the first block after the starting block
assertEq( assertEq(oracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime);
oracle.computeL2Timestamp(startingBlockNumber + 1),
startingTimestamp + l2BlockTime
);
// check timestamp for some other block number // check timestamp for some other block number
assertEq( assertEq(oracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024);
oracle.computeL2Timestamp(startingBlockNumber + 96024),
startingTimestamp + l2BlockTime * 96024
);
} }
} }
...@@ -271,15 +265,8 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { ...@@ -271,15 +265,8 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = oracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(proposer);
vm.expectRevert( vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height");
"L2OutputOracle: block hash does not match the hash at the expected height" oracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number - 1);
);
oracle.proposeL2Output(
nonZeroHash,
nextBlockNumber,
bytes32(uint256(0x01)),
block.number - 1
);
} }
/// @dev Tests that `proposeL2Output` reverts when given a block number /// @dev Tests that `proposeL2Output` reverts when given a block number
...@@ -297,9 +284,7 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { ...@@ -297,9 +284,7 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer {
vm.prank(proposer); vm.prank(proposer);
// This will fail when foundry no longer returns zerod block hashes // This will fail when foundry no longer returns zerod block hashes
vm.expectRevert( vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height");
"L2OutputOracle: block hash does not match the hash at the expected height"
);
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1); oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);
} }
} }
...@@ -478,10 +463,7 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { ...@@ -478,10 +463,7 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
NextImpl nextImpl = new NextImpl(); NextImpl nextImpl = new NextImpl();
vm.startPrank(multisig); vm.startPrank(multisig);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 3));
address(nextImpl),
abi.encodeWithSelector(NextImpl.initialize.selector, 3)
);
assertEq(proxy.implementation(), address(nextImpl)); assertEq(proxy.implementation(), address(nextImpl));
// Verify that the NextImpl contract initialized its values according as expected // Verify that the NextImpl contract initialized its values according as expected
......
...@@ -33,13 +33,8 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -33,13 +33,8 @@ contract L2StandardBridge_Test is Bridge_Initializer {
assertEq(address(messagePasser).balance, 0); assertEq(address(messagePasser).balance, 0);
uint256 nonce = L2Messenger.messageNonce(); uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector( bytes memory message =
StandardBridge.finalizeBridgeETH.selector, abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex"");
alice,
alice,
100,
hex""
);
uint64 baseGas = L2Messenger.baseGas(message, 200_000); uint64 baseGas = L2Messenger.baseGas(message, 200_000);
bytes memory withdrawalData = abi.encodeWithSelector( bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector,
...@@ -70,13 +65,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -70,13 +65,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
// L2ToL1MessagePasser will emit a MessagePassed event // L2ToL1MessagePasser will emit a MessagePassed event
vm.expectEmit(true, true, true, true, address(messagePasser)); vm.expectEmit(true, true, true, true, address(messagePasser));
emit MessagePassed( emit MessagePassed(
nonce, nonce, address(L2Messenger), address(L1Messenger), 100, baseGas, withdrawalData, withdrawalHash
address(L2Messenger),
address(L1Messenger),
100,
baseGas,
withdrawalData,
withdrawalHash
); );
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
...@@ -100,15 +89,12 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -100,15 +89,12 @@ contract L2StandardBridge_Test is Bridge_Initializer {
vm.expectCall( vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER, Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector( abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector, L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData
address(L1Messenger),
baseGas,
withdrawalData
) )
); );
vm.prank(alice, alice); vm.prank(alice, alice);
(bool success, ) = address(L2Bridge).call{ value: 100 }(hex""); (bool success,) = address(L2Bridge).call{ value: 100 }(hex"");
assertEq(success, true); assertEq(success, true);
assertEq(address(messagePasser).balance, 100); assertEq(address(messagePasser).balance, 100);
} }
...@@ -161,23 +147,11 @@ contract PreBridgeERC20 is Bridge_Initializer { ...@@ -161,23 +147,11 @@ contract PreBridgeERC20 is Bridge_Initializer {
assertEq(ERC20(_l2Token).balanceOf(alice), 100); assertEq(ERC20(_l2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce(); uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector, StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex""
address(L1Token),
_l2Token,
alice,
alice,
100,
hex""
); );
uint64 baseGas = L2Messenger.baseGas(message, 1000); uint64 baseGas = L2Messenger.baseGas(message, 1000);
bytes memory withdrawalData = abi.encodeWithSelector( bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message
nonce,
address(L2Bridge),
address(L1Bridge),
0,
1000,
message
); );
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
...@@ -192,48 +166,29 @@ contract PreBridgeERC20 is Bridge_Initializer { ...@@ -192,48 +166,29 @@ contract PreBridgeERC20 is Bridge_Initializer {
if (_isLegacy) { if (_isLegacy) {
vm.expectCall( vm.expectCall(
address(L2Bridge), address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"")
abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"")
); );
} else { } else {
vm.expectCall( vm.expectCall(
address(L2Bridge), address(L2Bridge),
abi.encodeWithSelector( abi.encodeWithSelector(L2Bridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex"")
L2Bridge.bridgeERC20.selector,
_l2Token,
address(L1Token),
100,
1000,
hex""
)
); );
} }
vm.expectCall( vm.expectCall(
address(L2Messenger), address(L2Messenger),
abi.encodeWithSelector( abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000)
CrossDomainMessenger.sendMessage.selector,
address(L1Bridge),
message,
1000
)
); );
vm.expectCall( vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER, Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector( abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector, L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData
address(L1Messenger),
baseGas,
withdrawalData
) )
); );
// The L2Bridge should burn the tokens // The L2Bridge should burn the tokens
vm.expectCall( vm.expectCall(_l2Token, abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100));
_l2Token,
abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)
);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex""); emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex"");
...@@ -243,13 +198,7 @@ contract PreBridgeERC20 is Bridge_Initializer { ...@@ -243,13 +198,7 @@ contract PreBridgeERC20 is Bridge_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit MessagePassed( emit MessagePassed(
nonce, nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash
address(L2Messenger),
address(L1Messenger),
0,
baseGas,
withdrawalData,
withdrawalHash
); );
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
...@@ -318,23 +267,11 @@ contract PreBridgeERC20To is Bridge_Initializer { ...@@ -318,23 +267,11 @@ contract PreBridgeERC20To is Bridge_Initializer {
assertEq(ERC20(L2Token).balanceOf(alice), 100); assertEq(ERC20(L2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce(); uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector, StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex""
address(L1Token),
_l2Token,
alice,
bob,
100,
hex""
); );
uint64 baseGas = L2Messenger.baseGas(message, 1000); uint64 baseGas = L2Messenger.baseGas(message, 1000);
bytes memory withdrawalData = abi.encodeWithSelector( bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message
nonce,
address(L2Bridge),
address(L1Bridge),
0,
1000,
message
); );
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
...@@ -355,13 +292,7 @@ contract PreBridgeERC20To is Bridge_Initializer { ...@@ -355,13 +292,7 @@ contract PreBridgeERC20To is Bridge_Initializer {
vm.expectEmit(true, true, true, true, address(messagePasser)); vm.expectEmit(true, true, true, true, address(messagePasser));
emit MessagePassed( emit MessagePassed(
nonce, nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash
address(L2Messenger),
address(L1Messenger),
0,
baseGas,
withdrawalData,
withdrawalHash
); );
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
...@@ -374,56 +305,31 @@ contract PreBridgeERC20To is Bridge_Initializer { ...@@ -374,56 +305,31 @@ contract PreBridgeERC20To is Bridge_Initializer {
if (_isLegacy) { if (_isLegacy) {
vm.expectCall( vm.expectCall(
address(L2Bridge), address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"")
abi.encodeWithSelector(
L2Bridge.withdrawTo.selector,
_l2Token,
bob,
100,
1000,
hex""
)
); );
} else { } else {
vm.expectCall( vm.expectCall(
address(L2Bridge), address(L2Bridge),
abi.encodeWithSelector( abi.encodeWithSelector(
L2Bridge.bridgeERC20To.selector, L2Bridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex""
_l2Token,
address(L1Token),
bob,
100,
1000,
hex""
) )
); );
} }
vm.expectCall( vm.expectCall(
address(L2Messenger), address(L2Messenger),
abi.encodeWithSelector( abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000)
CrossDomainMessenger.sendMessage.selector,
address(L1Bridge),
message,
1000
)
); );
vm.expectCall( vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER, Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector( abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector, L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData
address(L1Messenger),
baseGas,
withdrawalData
) )
); );
// The L2Bridge should burn the tokens // The L2Bridge should burn the tokens
vm.expectCall( vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100));
address(L2Token),
abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)
);
vm.prank(alice, alice); vm.prank(alice, alice);
} }
...@@ -460,10 +366,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { ...@@ -460,10 +366,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
abi.encode(address(L2Bridge.OTHER_BRIDGE())) abi.encode(address(L2Bridge.OTHER_BRIDGE()))
); );
vm.expectCall( vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100));
address(L2Token),
abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)
);
// Should emit both the bedrock and legacy events // Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(L2Bridge));
......
...@@ -40,7 +40,9 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -40,7 +40,9 @@ contract L2ToL1MessagePasserTest is CommonTest {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
uint256 nonce = messagePasser.messageNonce(); uint256 nonce = messagePasser.messageNonce();
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
...@@ -72,28 +74,13 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -72,28 +74,13 @@ contract L2ToL1MessagePasserTest is CommonTest {
/// log when called by a contract. /// log when called by a contract.
function test_initiateWithdrawal_fromContract_succeeds() external { function test_initiateWithdrawal_fromContract_succeeds() external {
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction( Types.WithdrawalTransaction(messagePasser.messageNonce(), address(this), address(4), 100, 64000, hex"")
messagePasser.messageNonce(),
address(this),
address(4),
100,
64000,
hex""
)
); );
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit MessagePassed( emit MessagePassed(messagePasser.messageNonce(), address(this), address(4), 100, 64000, hex"", withdrawalHash);
messagePasser.messageNonce(),
address(this),
address(4),
100,
64000,
hex"",
withdrawalHash
);
vm.deal(address(this), 2**64); vm.deal(address(this), 2 ** 64);
messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex""); messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex"");
} }
...@@ -108,10 +95,9 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -108,10 +95,9 @@ contract L2ToL1MessagePasserTest is CommonTest {
// EOA emulation // EOA emulation
vm.prank(alice, alice); vm.prank(alice, alice);
vm.deal(alice, 2**64); vm.deal(alice, 2 ** 64);
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash =
Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data) Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data));
);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash); emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);
...@@ -126,11 +112,7 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -126,11 +112,7 @@ contract L2ToL1MessagePasserTest is CommonTest {
/// @dev Tests that `burn` succeeds and destroys the ETH held in the contract. /// @dev Tests that `burn` succeeds and destroys the ETH held in the contract.
function test_burn_succeeds() external { function test_burn_succeeds() external {
messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }( messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(NON_ZERO_ADDRESS, NON_ZERO_GASLIMIT, NON_ZERO_DATA);
NON_ZERO_ADDRESS,
NON_ZERO_GASLIMIT,
NON_ZERO_DATA
);
assertEq(address(messagePasser).balance, NON_ZERO_VALUE); assertEq(address(messagePasser).balance, NON_ZERO_VALUE);
vm.expectEmit(true, false, false, false); vm.expectEmit(true, false, false, false);
......
...@@ -15,7 +15,7 @@ contract LibPosition_Test is Test { ...@@ -15,7 +15,7 @@ contract LibPosition_Test is Test {
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal view returns (uint64) { function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal view returns (uint64) {
// Index at depth bound: [0, 2 ** _depth-1] // Index at depth bound: [0, 2 ** _depth-1]
if (_depth > 0) { if (_depth > 0) {
return uint64(bound(_indexAtDepth, 0, 2**(_depth - 1))); return uint64(bound(_indexAtDepth, 0, 2 ** (_depth - 1)));
} else { } else {
return 0; return 0;
} }
...@@ -29,7 +29,8 @@ contract LibPosition_Test is Test { ...@@ -29,7 +29,8 @@ contract LibPosition_Test is Test {
assertEq(position.depth(), _depth); assertEq(position.depth(), _depth);
} }
/// @notice Tests that the `indexAtDepth` function correctly shifts out the `indexAtDepth` from a packed `Position` type. /// @notice Tests that the `indexAtDepth` function correctly shifts out the `indexAtDepth` from a packed `Position`
/// type.
function testFuzz_indexAtDepth_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public { function testFuzz_indexAtDepth_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
_depth = uint8(bound(_depth, 0, MAX_DEPTH)); _depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth); _indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...@@ -76,9 +77,7 @@ contract LibPosition_Test is Test { ...@@ -76,9 +77,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `traceAncestor` function correctly computes the position of the /// @notice Tests that the `traceAncestor` function correctly computes the position of the
/// highest ancestor that commits to the same trace index. /// highest ancestor that commits to the same trace index.
function testFuzz_traceAncestor_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) function testFuzz_traceAncestor_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
public
{
_depth = uint8(bound(_depth, 1, MAX_DEPTH)); _depth = uint8(bound(_depth, 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth); _indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...@@ -94,11 +93,7 @@ contract LibPosition_Test is Test { ...@@ -94,11 +93,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative /// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
/// to a given position. /// to a given position.
function testFuzz_rightIndex_correctness_succeeds( function testFuzz_rightIndex_correctness_succeeds(uint64 _maxDepth, uint8 _depth, uint64 _indexAtDepth) public {
uint64 _maxDepth,
uint8 _depth,
uint64 _indexAtDepth
) public {
// Max depth bound: [1, 63] // Max depth bound: [1, 63]
// The max game depth MUST be at least 1. // The max game depth MUST be at least 1.
_maxDepth = uint8(bound(_maxDepth, 1, MAX_DEPTH)); _maxDepth = uint8(bound(_maxDepth, 1, MAX_DEPTH));
......
...@@ -34,7 +34,8 @@ contract MIPS_Test is Test { ...@@ -34,7 +34,8 @@ contract MIPS_Test is Test {
step: 1, step: 1,
registers: registers registers: registers
}); });
bytes memory proof = hex"3c10bfff3610fff0341100013c08ffff3508fffd34090003010950202d420001ae020008ae11000403e000080000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618db8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory proof =
hex"3c10bfff3610fff0341100013c08ffff3508fffd34090003010950202d420001ae020008ae11000403e000080000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618db8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
bytes32 postState = mips.step(encodeState(state), proof); bytes32 postState = mips.step(encodeState(state), proof);
assertTrue(postState != bytes32(0)); assertTrue(postState != bytes32(0));
...@@ -42,7 +43,7 @@ contract MIPS_Test is Test { ...@@ -42,7 +43,7 @@ contract MIPS_Test is Test {
function encodeState(MIPS.State memory state) internal pure returns (bytes memory) { function encodeState(MIPS.State memory state) internal pure returns (bytes memory) {
bytes memory registers; bytes memory registers;
for (uint i = 0; i < state.registers.length; i++) { for (uint256 i = 0; i < state.registers.length; i++) {
registers = bytes.concat(registers, abi.encodePacked(state.registers[i])); registers = bytes.concat(registers, abi.encodePacked(state.registers[i]));
} }
return abi.encodePacked( return abi.encodePacked(
......
...@@ -10,12 +10,9 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -10,12 +10,9 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b6579326262"; bytes memory key = hex"6b6579326262";
bytes memory val = hex"6176616c32"; bytes memory val = hex"6176616c32";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[ proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
0 proof[1] =
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386"; hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[
1
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[2] = hex"ca83206262856176616c32"; proof[2] = hex"ca83206262856176616c32";
assertEq(val, MerkleTrie.get(key, proof, root)); assertEq(val, MerkleTrie.get(key, proof, root));
...@@ -24,18 +21,12 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -24,18 +21,12 @@ contract MerkleTrie_get_Test is CommonTest {
function test_get_validProof2_succeeds() external { function test_get_validProof2_succeeds() external {
bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f; bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
bytes memory key = hex"6b6579316161"; bytes memory key = hex"6b6579316161";
bytes bytes memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[ proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
0 proof[1] =
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386"; hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[ proof[2] = hex"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
1
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[
2
] = hex"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
assertEq(val, MerkleTrie.get(key, proof, root)); assertEq(val, MerkleTrie.get(key, proof, root));
} }
...@@ -43,12 +34,10 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -43,12 +34,10 @@ contract MerkleTrie_get_Test is CommonTest {
function test_get_validProof3_succeeds() external { function test_get_validProof3_succeeds() external {
bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed; bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;
bytes memory key = hex"6b6579316161"; bytes memory key = hex"6b6579316161";
bytes bytes memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
bytes[] memory proof = new bytes[](1); bytes[] memory proof = new bytes[](1);
proof[ proof[0] =
0 hex"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
] = hex"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
assertEq(val, MerkleTrie.get(key, proof, root)); assertEq(val, MerkleTrie.get(key, proof, root));
} }
...@@ -66,18 +55,14 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -66,18 +55,14 @@ contract MerkleTrie_get_Test is CommonTest {
function test_get_validProof5_succeeds() external { function test_get_validProof5_succeeds() external {
bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89; bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;
bytes memory key = hex"6b657931"; bytes memory key = hex"6b657931";
bytes bytes memory val =
memory val = hex"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67"; hex"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[ proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
0 proof[1] =
] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779"; hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[ proof[2] =
1 hex"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
] = hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[
2
] = hex"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
assertEq(val, MerkleTrie.get(key, proof, root)); assertEq(val, MerkleTrie.get(key, proof, root));
} }
...@@ -87,12 +72,9 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -87,12 +72,9 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b657932"; bytes memory key = hex"6b657932";
bytes memory val = hex"73686f7274"; bytes memory val = hex"73686f7274";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[ proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
0 proof[1] =
] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779"; hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[
1
] = hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[2] = hex"df808080808080c9823262856176616c338080808080808080808573686f7274"; proof[2] = hex"df808080808080c9823262856176616c338080808080808080808573686f7274";
assertEq(val, MerkleTrie.get(key, proof, root)); assertEq(val, MerkleTrie.get(key, proof, root));
...@@ -103,15 +85,11 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -103,15 +85,11 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b657933"; bytes memory key = hex"6b657933";
bytes memory val = hex"31323334353637383930313233343536373839303132333435363738393031"; bytes memory val = hex"31323334353637383930313233343536373839303132333435363738393031";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[ proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
0 proof[1] =
] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779"; hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[ proof[2] =
1 hex"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031";
] = hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[
2
] = hex"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031";
assertEq(val, MerkleTrie.get(key, proof, root)); assertEq(val, MerkleTrie.get(key, proof, root));
} }
...@@ -156,12 +134,9 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -156,12 +134,9 @@ contract MerkleTrie_get_Test is CommonTest {
bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f; bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
bytes memory key = hex"6b657932"; bytes memory key = hex"6b657932";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[ proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
0 proof[1] =
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386"; hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[
1
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[2] = hex"ca83206262856176616c32"; proof[2] = hex"ca83206262856176616c32";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
...@@ -172,9 +147,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -172,9 +147,7 @@ contract MerkleTrie_get_Test is CommonTest {
bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f; bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
bytes memory key = hex"616e7972616e646f6d6b6579"; bytes memory key = hex"616e7972616e646f6d6b6579";
bytes[] memory proof = new bytes[](1); bytes[] memory proof = new bytes[](1);
proof[ proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
0
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
...@@ -185,9 +158,8 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -185,9 +158,8 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b6579316161"; bytes memory key = hex"6b6579316161";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[0] = hex"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f"; proof[0] = hex"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f";
proof[ proof[1] =
1 hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
] = hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
proof[2] = hex"d687206e6f746865728d33343938683472697568677765"; proof[2] = hex"d687206e6f746865728d33343938683472697568677765";
vm.expectRevert("MerkleTrie: invalid internal node hash"); vm.expectRevert("MerkleTrie: invalid internal node hash");
...@@ -199,15 +171,11 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -199,15 +171,11 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b6579326262"; bytes memory key = hex"6b6579326262";
bytes[] memory proof = new bytes[](5); bytes[] memory proof = new bytes[](5);
proof[0] = hex"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2"; proof[0] = hex"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2";
proof[ proof[1] =
1 hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
] = hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080"; proof[2] = hex"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[ proof[3] =
2 hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
] = hex"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[
3
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[4] = hex"ca83206262856176616c32"; proof[4] = hex"ca83206262856176616c32";
vm.expectRevert("RLPReader: decoded item type for list is not a list item"); vm.expectRevert("RLPReader: decoded item type for list is not a list item");
...@@ -231,9 +199,8 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -231,9 +199,8 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"aa"; bytes memory key = hex"aa";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[0] = hex"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157"; proof[0] = hex"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157";
proof[ proof[1] =
1 hex"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080";
] = hex"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080";
proof[2] = hex"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f"; proof[2] = hex"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f";
vm.expectRevert("MerkleTrie: invalid internal node hash"); vm.expectRevert("MerkleTrie: invalid internal node hash");
...@@ -278,9 +245,8 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -278,9 +245,8 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"aa"; bytes memory key = hex"aa";
bytes[] memory proof = new bytes[](3); bytes[] memory proof = new bytes[](3);
proof[0] = hex"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905"; proof[0] = hex"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905";
proof[ proof[1] =
1 hex"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080";
] = hex"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080";
proof[2] = hex"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af"; proof[2] = hex"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
...@@ -303,8 +269,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -303,8 +269,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored. /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_validProofs_succeeds(bytes4) external { function testFuzz_get_validProofs_succeeds(bytes4) external {
// Generate a test case with a valid proof of inclusion for the k/v pair in the trie. // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.
(bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("valid");
.getMerkleTrieFuzzCase("valid");
// Assert that our expected value is equal to our actual value. // Assert that our expected value is equal to our actual value.
assertEq(val, MerkleTrie.get(key, proof, root)); assertEq(val, MerkleTrie.get(key, proof, root));
...@@ -313,9 +278,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -313,9 +278,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored. /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_invalidRoot_reverts(bytes4) external { function testFuzz_get_invalidRoot_reverts(bytes4) external {
// Get a random test case with a valid trie / proof // Get a random test case with a valid trie / proof
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("valid");
"valid"
);
bytes32 rootHash = keccak256(abi.encodePacked(root)); bytes32 rootHash = keccak256(abi.encodePacked(root));
vm.expectRevert("MerkleTrie: invalid root hash"); vm.expectRevert("MerkleTrie: invalid root hash");
...@@ -326,9 +289,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -326,9 +289,7 @@ contract MerkleTrie_get_Test is CommonTest {
function testFuzz_get_extraProofElements_reverts(bytes4) external { function testFuzz_get_extraProofElements_reverts(bytes4) external {
// Generate an invalid test case with an extra proof element attached to an otherwise // Generate an invalid test case with an extra proof element attached to an otherwise
// valid proof of inclusion for the passed k/v. // valid proof of inclusion for the passed k/v.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("extra_proof_elems");
"extra_proof_elems"
);
vm.expectRevert("MerkleTrie: value node must be last node in proof (leaf)"); vm.expectRevert("MerkleTrie: value node must be last node in proof (leaf)");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
...@@ -337,9 +298,8 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -337,9 +298,8 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored. /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external { function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {
// Generate an invalid test case where a long proof element is incorrect for the root. // Generate an invalid test case where a long proof element is incorrect for the root.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) =
"invalid_large_internal_hash" ffi.getMerkleTrieFuzzCase("invalid_large_internal_hash");
);
vm.expectRevert("MerkleTrie: invalid large internal hash"); vm.expectRevert("MerkleTrie: invalid large internal hash");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
...@@ -348,9 +308,8 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -348,9 +308,8 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored. /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external { function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {
// Generate an invalid test case where a small proof element is incorrect for the root. // Generate an invalid test case where a small proof element is incorrect for the root.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) =
"invalid_internal_node_hash" ffi.getMerkleTrieFuzzCase("invalid_internal_node_hash");
);
vm.expectRevert("MerkleTrie: invalid internal node hash"); vm.expectRevert("MerkleTrie: invalid internal node hash");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
...@@ -359,9 +318,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -359,9 +318,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored. /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_corruptedProof_reverts(bytes4) external { function testFuzz_get_corruptedProof_reverts(bytes4) external {
// Generate an invalid test case where the proof is malformed. // Generate an invalid test case where the proof is malformed.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("corrupted_proof");
"corrupted_proof"
);
vm.expectRevert("RLPReader: decoded item type for list is not a list item"); vm.expectRevert("RLPReader: decoded item type for list is not a list item");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
...@@ -371,9 +328,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -371,9 +328,7 @@ contract MerkleTrie_get_Test is CommonTest {
function testFuzz_get_invalidDataRemainder_reverts(bytes4) external { function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {
// Generate an invalid test case where a random element of the proof has more bytes than the // Generate an invalid test case where a random element of the proof has more bytes than the
// length designates within the RLP list encoding. // length designates within the RLP list encoding.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("invalid_data_remainder");
"invalid_data_remainder"
);
vm.expectRevert("RLPReader: list item has an invalid data remainder"); vm.expectRevert("RLPReader: list item has an invalid data remainder");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
...@@ -383,9 +338,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -383,9 +338,7 @@ contract MerkleTrie_get_Test is CommonTest {
function testFuzz_get_prefixedValidKey_reverts(bytes4) external { function testFuzz_get_prefixedValidKey_reverts(bytes4) external {
// Get a random test case with a valid trie / proof and a valid key that is prefixed // Get a random test case with a valid trie / proof and a valid key that is prefixed
// with random bytes // with random bytes
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("prefixed_valid_key");
"prefixed_valid_key"
);
// Ambiguous revert check- all that we care is that it *does* fail. This case may // Ambiguous revert check- all that we care is that it *does* fail. This case may
// fail within different branches. // fail within different branches.
...@@ -396,9 +349,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -396,9 +349,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored. /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_emptyKey_reverts(bytes4) external { function testFuzz_get_emptyKey_reverts(bytes4) external {
// Get a random test case with a valid trie / proof and an empty key // Get a random test case with a valid trie / proof and an empty key
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("empty_key");
"empty_key"
);
vm.expectRevert("MerkleTrie: empty key"); vm.expectRevert("MerkleTrie: empty key");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
...@@ -407,9 +358,7 @@ contract MerkleTrie_get_Test is CommonTest { ...@@ -407,9 +358,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored. /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_partialProof_reverts(bytes4) external { function testFuzz_get_partialProof_reverts(bytes4) external {
// Get a random test case with a valid trie / partially correct proof // Get a random test case with a valid trie / partially correct proof
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase( (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("partial_proof");
"partial_proof"
);
vm.expectRevert("MerkleTrie: ran out of proof elements"); vm.expectRevert("MerkleTrie: ran out of proof elements");
MerkleTrie.get(key, proof, root); MerkleTrie.get(key, proof, root);
......
...@@ -2,10 +2,7 @@ ...@@ -2,10 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Bridge_Initializer } from "./CommonTest.t.sol"; import { Bridge_Initializer } from "./CommonTest.t.sol";
import { import { ILegacyMintableERC20, IOptimismMintableERC20 } from "../src/universal/IOptimismMintableERC20.sol";
ILegacyMintableERC20,
IOptimismMintableERC20
} from "../src/universal/IOptimismMintableERC20.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
contract OptimismMintableERC20_Test is Bridge_Initializer { contract OptimismMintableERC20_Test is Bridge_Initializer {
...@@ -87,10 +84,8 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { ...@@ -87,10 +84,8 @@ contract OptimismMintableERC20_Test is Bridge_Initializer {
assertEq(iface2, type(ILegacyMintableERC20).interfaceId); assertEq(iface2, type(ILegacyMintableERC20).interfaceId);
assert(L2Token.supportsInterface(iface2)); assert(L2Token.supportsInterface(iface2));
bytes4 iface3 = L2Token.remoteToken.selector ^ bytes4 iface3 =
L2Token.bridge.selector ^ L2Token.remoteToken.selector ^ L2Token.bridge.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;
L2Token.mint.selector ^
L2Token.burn.selector;
assertEq(iface3, type(IOptimismMintableERC20).interfaceId); assertEq(iface3, type(IOptimismMintableERC20).interfaceId);
assert(L2Token.supportsInterface(iface3)); assert(L2Token.supportsInterface(iface3));
} }
......
...@@ -6,11 +6,7 @@ import { LibRLP } from "./RLP.t.sol"; ...@@ -6,11 +6,7 @@ import { LibRLP } from "./RLP.t.sol";
contract OptimismMintableTokenFactory_Test is Bridge_Initializer { contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);
event OptimismMintableERC20Created( event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
address indexed localToken,
address indexed remoteToken,
address deployer
);
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
......
...@@ -2,16 +2,11 @@ ...@@ -2,16 +2,11 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
IERC721Enumerable
} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { ERC721Bridge_Initializer } from "./CommonTest.t.sol"; import { ERC721Bridge_Initializer } from "./CommonTest.t.sol";
import { import { OptimismMintableERC721, IOptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.sol";
OptimismMintableERC721,
IOptimismMintableERC721
} from "../src/universal/OptimismMintableERC721.sol";
contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
ERC721 internal L1Token; ERC721 internal L1Token;
......
...@@ -10,11 +10,7 @@ import { OptimismMintableERC721Factory } from "../src/universal/OptimismMintable ...@@ -10,11 +10,7 @@ import { OptimismMintableERC721Factory } from "../src/universal/OptimismMintable
contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
OptimismMintableERC721Factory internal factory; OptimismMintableERC721Factory internal factory;
event OptimismMintableERC721Created( event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
address indexed localToken,
address indexed remoteToken,
address deployer
);
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
...@@ -41,9 +37,8 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { ...@@ -41,9 +37,8 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
// Create the token. // Create the token.
vm.prank(alice); vm.prank(alice);
OptimismMintableERC721 created = OptimismMintableERC721( OptimismMintableERC721 created =
factory.createOptimismMintableERC721(address(1234), "L2Token", "L2T") OptimismMintableERC721(factory.createOptimismMintableERC721(address(1234), "L2Token", "L2T"));
);
// Token address should be correct. // Token address should be correct.
assertEq(address(created), predicted); assertEq(address(created), predicted);
......
...@@ -100,9 +100,9 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -100,9 +100,9 @@ contract OptimismPortal_Test is Portal_Initializer {
emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex""); emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex"");
// give alice money and send as an eoa // give alice money and send as an eoa
vm.deal(alice, 2**64); vm.deal(alice, 2 ** 64);
vm.prank(alice, alice); vm.prank(alice, alice);
(bool s, ) = address(op).call{ value: 100 }(hex""); (bool s,) = address(op).call{ value: 100 }(hex"");
assert(s); assert(s);
assertEq(address(op).balance, 100); assertEq(address(op).balance, 100);
...@@ -134,21 +134,12 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -134,21 +134,12 @@ contract OptimismPortal_Test is Portal_Initializer {
/// @dev Tests that `depositTransaction` reverts when the gas limit is too small. /// @dev Tests that `depositTransaction` reverts when the gas limit is too small.
function test_depositTransaction_smallGasLimit_reverts() external { function test_depositTransaction_smallGasLimit_reverts() external {
vm.expectRevert("OptimismPortal: gas limit too small"); vm.expectRevert("OptimismPortal: gas limit too small");
op.depositTransaction({ op.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" });
_to: address(1),
_value: 0,
_gasLimit: 0,
_isCreation: false,
_data: hex""
});
} }
/// @dev Tests that `depositTransaction` succeeds for small, /// @dev Tests that `depositTransaction` succeeds for small,
/// but sufficient, gas limits. /// but sufficient, gas limits.
function testFuzz_depositTransaction_smallGasLimit_succeeds( function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external {
bytes memory _data,
bool _shouldFail
) external {
vm.assume(_data.length <= type(uint64).max); vm.assume(_data.length <= type(uint64).max);
uint64 gasLimit = op.minimumGasLimit(uint64(_data.length)); uint64 gasLimit = op.minimumGasLimit(uint64(_data.length));
...@@ -157,13 +148,7 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -157,13 +148,7 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectRevert("OptimismPortal: gas limit too small"); vm.expectRevert("OptimismPortal: gas limit too small");
} }
op.depositTransaction({ op.depositTransaction({ _to: address(0x40), _value: 0, _gasLimit: gasLimit, _isCreation: false, _data: _data });
_to: address(0x40),
_value: 0,
_gasLimit: gasLimit,
_isCreation: false,
_data: _data
});
} }
/// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes. /// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes.
...@@ -181,22 +166,10 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -181,22 +166,10 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.prank(address(this), address(this)); vm.prank(address(this), address(this));
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
emitTransactionDeposited( emitTransactionDeposited(
address(this), address(this), NON_ZERO_ADDRESS, ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
NON_ZERO_ADDRESS,
ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
); );
op.depositTransaction( op.depositTransaction(NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA);
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
);
} }
/// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with 0 value. /// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with 0 value.
...@@ -212,13 +185,7 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -212,13 +185,7 @@ contract OptimismPortal_Test is Portal_Initializer {
NON_ZERO_DATA NON_ZERO_DATA
); );
op.depositTransaction( op.depositTransaction(NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA);
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
);
} }
/// @dev Tests that `depositTransaction` succeeds for an EOA /// @dev Tests that `depositTransaction` succeeds for an EOA
...@@ -229,13 +196,7 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -229,13 +196,7 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
emitTransactionDeposited( emitTransactionDeposited(
address(this), address(this), ZERO_ADDRESS, ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA
ZERO_ADDRESS,
ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
NON_ZERO_DATA
); );
op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA); op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);
...@@ -265,21 +226,11 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -265,21 +226,11 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
emitTransactionDeposited( emitTransactionDeposited(
address(this), address(this), NON_ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
NON_ZERO_ADDRESS,
NON_ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
); );
op.depositTransaction{ value: NON_ZERO_VALUE }( op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
); );
assertEq(address(op).balance, NON_ZERO_VALUE); assertEq(address(op).balance, NON_ZERO_VALUE);
} }
...@@ -298,11 +249,7 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -298,11 +249,7 @@ contract OptimismPortal_Test is Portal_Initializer {
); );
op.depositTransaction{ value: NON_ZERO_VALUE }( op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
); );
} }
...@@ -313,22 +260,10 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -313,22 +260,10 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
emitTransactionDeposited( emitTransactionDeposited(
address(this), address(this), ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex""
ZERO_ADDRESS,
NON_ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
hex""
); );
op.depositTransaction{ value: NON_ZERO_VALUE }( op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex"");
ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
hex""
);
assertEq(address(op).balance, NON_ZERO_VALUE); assertEq(address(op).balance, NON_ZERO_VALUE);
} }
...@@ -345,13 +280,7 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -345,13 +280,7 @@ contract OptimismPortal_Test is Portal_Initializer {
NON_ZERO_DATA NON_ZERO_DATA
); );
op.depositTransaction{ value: NON_ZERO_VALUE }( op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);
ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
NON_ZERO_DATA
);
assertEq(address(op).balance, NON_ZERO_VALUE); assertEq(address(op).balance, NON_ZERO_VALUE);
} }
...@@ -361,9 +290,7 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -361,9 +290,7 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode( abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber)))
Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))
)
); );
// warp to the finalization period // warp to the finalization period
...@@ -428,8 +355,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -428,8 +355,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
data: hex"" data: hex""
}); });
// Get withdrawal proof data we can use for testing. // Get withdrawal proof data we can use for testing.
(_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) =
.getProveWithdrawalTransactionInputs(_defaultTx); ffi.getProveWithdrawalTransactionInputs(_defaultTx);
// Setup a dummy output root proof for reuse. // Setup a dummy output root proof for reuse.
_outputRootProof = Types.OutputRootProof({ _outputRootProof = Types.OutputRootProof({
...@@ -450,11 +377,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -450,11 +377,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp( vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
oracle.getL2Output(_proposedOutputIndex).timestamp +
oracle.FINALIZATION_PERIOD_SECONDS() +
1
);
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF); vm.deal(address(op), 0xFFFFFFFF);
} }
...@@ -487,12 +410,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -487,12 +410,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_onSelfCall_reverts() external { function test_proveWithdrawalTransaction_onSelfCall_reverts() external {
_defaultTx.target = address(op); _defaultTx.target = address(op);
vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract"); vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract");
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
} }
/// @dev Tests that `proveWithdrawalTransaction` reverts when /// @dev Tests that `proveWithdrawalTransaction` reverts when
...@@ -501,12 +419,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -501,12 +419,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Modify the version to invalidate the withdrawal proof. // Modify the version to invalidate the withdrawal proof.
_outputRootProof.version = bytes32(uint256(1)); _outputRootProof.version = bytes32(uint256(1));
vm.expectRevert("OptimismPortal: invalid output root proof"); vm.expectRevert("OptimismPortal: invalid output root proof");
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
} }
/// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing. /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing.
...@@ -514,12 +427,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -514,12 +427,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// modify the default test values to invalidate the proof. // modify the default test values to invalidate the proof.
_defaultTx.data = hex"abcd"; _defaultTx.data = hex"abcd";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
} }
/// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already
...@@ -527,20 +435,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -527,20 +435,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_replayProve_reverts() external { function test_proveWithdrawalTransaction_replayProve_reverts() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
vm.expectRevert("OptimismPortal: withdrawal hash has already been proven"); vm.expectRevert("OptimismPortal: withdrawal hash has already been proven");
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
} }
/// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already
...@@ -548,12 +446,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -548,12 +446,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external { function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`
// inside of the `provenWithdrawal`s mapping. // inside of the `provenWithdrawal`s mapping.
...@@ -575,31 +468,19 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -575,31 +468,19 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// our proof with a changed outputRoot // our proof with a changed outputRoot
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Ensure that the withdrawal was updated within the mapping // Ensure that the withdrawal was updated within the mapping
(, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash); (, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash);
assertEq(timestamp, block.timestamp); assertEq(timestamp, block.timestamp);
} }
/// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already
/// been proven and the output root, output index, and l2BlockNumber have changed. /// been proven and the output root, output index, and l2BlockNumber have changed.
function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() external {
external
{
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`
// inside of the `provenWithdrawal`s mapping. // inside of the `provenWithdrawal`s mapping.
...@@ -620,10 +501,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -620,10 +501,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Propose the same output root again, creating the same output at a different index + l2BlockNumber. // Propose the same output root again, creating the same output at a different index + l2BlockNumber.
vm.startPrank(op.L2_ORACLE().PROPOSER()); vm.startPrank(op.L2_ORACLE().PROPOSER());
op.L2_ORACLE().proposeL2Output( op.L2_ORACLE().proposeL2Output(
proposal.outputRoot, proposal.outputRoot, op.L2_ORACLE().nextBlockNumber(), blockhash(block.number), block.number
op.L2_ORACLE().nextBlockNumber(),
blockhash(block.number),
block.number
); );
vm.stopPrank(); vm.stopPrank();
...@@ -634,15 +512,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -634,15 +512,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// our proof with a changed outputRoot + a different output index // our proof with a changed outputRoot + a different output index
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex + 1,
_outputRootProof,
_withdrawalProof
);
// Ensure that the withdrawal was updated within the mapping // Ensure that the withdrawal was updated within the mapping
(, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash); (, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash);
assertEq(timestamp, block.timestamp); assertEq(timestamp, block.timestamp);
} }
...@@ -650,12 +523,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -650,12 +523,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external { function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds. /// @dev Tests that `finalizeWithdrawalTransaction` succeeds.
...@@ -664,12 +532,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -664,12 +532,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
...@@ -705,12 +568,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -705,12 +568,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Mock a call where the resulting output root is anything but the original output root. In // Mock a call where the resulting output root is anything but the original output root. In
// this case we just use bytes32(uint256(1)). // this case we just use bytes32(uint256(1)).
...@@ -734,27 +592,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -734,27 +592,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal // Prove our withdrawal
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock a startingTimestamp change on the L2 Oracle // Mock a startingTimestamp change on the L2 Oracle
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(op.L2_ORACLE()), abi.encodeWithSignature("startingTimestamp()"), abi.encode(block.timestamp + 1)
abi.encodeWithSignature("startingTimestamp()"),
abi.encode(block.timestamp + 1)
); );
// Attempt to finalize the withdrawal // Attempt to finalize the withdrawal
vm.expectRevert( vm.expectRevert("OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp");
"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp"
);
op.finalizeWithdrawalTransaction(_defaultTx); op.finalizeWithdrawalTransaction(_defaultTx);
// Ensure that bob's balance has remained the same // Ensure that bob's balance has remained the same
...@@ -769,12 +618,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -769,12 +618,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal // Prove our withdrawal
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
...@@ -785,18 +629,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -785,18 +629,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
address(op.L2_ORACLE()), address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode( abi.encode(
Types.OutputProposal( Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber))
bytes32(uint256(0)),
uint128(block.timestamp),
uint128(_proposedBlockNumber)
)
) )
); );
// Attempt to finalize the withdrawal // Attempt to finalize the withdrawal
vm.expectRevert( vm.expectRevert("OptimismPortal: output root proven is not the same as current output root");
"OptimismPortal: output root proven is not the same as current output root"
);
op.finalizeWithdrawalTransaction(_defaultTx); op.finalizeWithdrawalTransaction(_defaultTx);
// Ensure that bob's balance has remained the same // Ensure that bob's balance has remained the same
...@@ -811,12 +649,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -811,12 +649,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal // Prove our withdrawal
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
...@@ -826,13 +659,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -826,13 +659,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode( abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber)))
Types.OutputProposal(
_outputRoot,
uint128(block.timestamp + 1),
uint128(_proposedBlockNumber)
)
)
); );
// Attempt to finalize the withdrawal // Attempt to finalize the withdrawal
...@@ -850,12 +677,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -850,12 +677,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -873,21 +695,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -873,21 +695,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode( abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber)))
Types.OutputProposal(
_outputRoot,
uint128(recentTimestamp),
uint128(_proposedBlockNumber)
)
)
); );
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed");
op.finalizeWithdrawalTransaction(_defaultTx); op.finalizeWithdrawalTransaction(_defaultTx);
...@@ -898,12 +709,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -898,12 +709,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_finalizeWithdrawalTransaction_onReplay_reverts() external { function test_finalizeWithdrawalTransaction_onReplay_reverts() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -929,8 +735,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -929,8 +735,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
}); });
// Get updated proof inputs. // Get updated proof inputs.
(bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi (bytes32 stateRoot, bytes32 storageRoot,,, bytes[] memory withdrawalProof) =
.getProveWithdrawalTransactionInputs(insufficientGasTx); ffi.getProveWithdrawalTransactionInputs(insufficientGasTx);
Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({
version: bytes32(0), version: bytes32(0),
stateRoot: stateRoot, stateRoot: stateRoot,
...@@ -950,12 +756,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -950,12 +756,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
) )
); );
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof);
insufficientGasTx,
_proposedOutputIndex,
outputRootProof,
withdrawalProof
);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectRevert("SafeCall: Not enough gas"); vm.expectRevert("SafeCall: Not enough gas");
...@@ -993,23 +794,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -993,23 +794,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode( abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber)))
Types.OutputProposal(
outputRoot,
uint128(finalizedTimestamp),
uint128(_proposedBlockNumber)
)
)
); );
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(withdrawalHash, alice, address(this)); emit WithdrawalProven(withdrawalHash, alice, address(this));
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof);
_testTx,
_proposedBlockNumber,
outputRootProof,
withdrawalProof
);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectCall(address(this), _testTx.data); vm.expectCall(address(this), _testTx.data);
...@@ -1028,12 +818,14 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -1028,12 +818,14 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
vm.assume( vm.assume(
_target != address(op) && // Cannot call the optimism portal or a contract _target != address(op) // Cannot call the optimism portal or a contract
_target.code.length == 0 && // No accounts with code && _target.code.length == 0 // No accounts with code
_target != CONSOLE && // The console has no code but behaves like a contract && _target != CONSOLE // The console has no code but behaves like a contract
uint160(_target) > 9 // No precompiles (or zero address) && uint160(_target) > 9 // No precompiles (or zero address)
); );
// Total ETH supply is currently about 120M ETH. // Total ETH supply is currently about 120M ETH.
...@@ -1086,7 +878,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -1086,7 +878,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
proof, proof,
withdrawalProof withdrawalProof
); );
(bytes32 _root, , ) = op.provenWithdrawals(withdrawalHash); (bytes32 _root,,) = op.provenWithdrawals(withdrawalHash);
assertTrue(_root != bytes32(0)); assertTrue(_root != bytes32(0));
// Warp past the finalization period // Warp past the finalization period
...@@ -1154,10 +946,7 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { ...@@ -1154,10 +946,7 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
vm.startPrank(multisig); vm.startPrank(multisig);
// The value passed to the initialize must be larger than the last value // The value passed to the initialize must be larger than the last value
// that initialize was called with. // that initialize was called with.
proxy.upgradeToAndCall( proxy.upgradeToAndCall(address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 3));
address(nextImpl),
abi.encodeWithSelector(NextImpl.initialize.selector, 3)
);
assertEq(proxy.implementation(), address(nextImpl)); assertEq(proxy.implementation(), address(nextImpl));
// Verify that the NextImpl contract initialized its values according as expected // Verify that the NextImpl contract initialized its values according as expected
...@@ -1187,7 +976,9 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer { ...@@ -1187,7 +976,9 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
uint64 _prevBoughtGas, uint64 _prevBoughtGas,
uint128 _prevBaseFee, uint128 _prevBaseFee,
uint8 _blockDiff uint8 _blockDiff
) external { )
external
{
// Get the set system gas limit // Get the set system gas limit
uint64 gasLimit = systemConfig.gasLimit(); uint64 gasLimit = systemConfig.gasLimit();
// Bound resource config // Bound resource config
...@@ -1200,10 +991,7 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer { ...@@ -1200,10 +991,7 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
vm.assume(_baseFeeMaxChangeDenominator > 1); vm.assume(_baseFeeMaxChangeDenominator > 1);
vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit); vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit);
vm.assume(_elasticityMultiplier > 0); vm.assume(_elasticityMultiplier > 0);
vm.assume( vm.assume(((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) == _maxResourceLimit);
((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) ==
_maxResourceLimit
);
_prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit));
_blockDiff = uint8(bound(_blockDiff, 0, 3)); _blockDiff = uint8(bound(_blockDiff, 0, 3));
...@@ -1217,9 +1005,7 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer { ...@@ -1217,9 +1005,7 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
maximumBaseFee: _maximumBaseFee maximumBaseFee: _maximumBaseFee
}); });
vm.mockCall( vm.mockCall(
address(systemConfig), address(systemConfig), abi.encodeWithSelector(systemConfig.resourceConfig.selector), abi.encode(rcfg)
abi.encodeWithSelector(systemConfig.resourceConfig.selector),
abi.encode(rcfg)
); );
// Set the resource params // Set the resource params
......
...@@ -23,10 +23,7 @@ interface IMulticall3 { ...@@ -23,10 +23,7 @@ interface IMulticall3 {
bytes returnData; bytes returnData;
} }
function aggregate3(Call3[] calldata calls) function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);
external
payable
returns (Result[] memory returnData);
} }
library Multicall { library Multicall {
...@@ -38,17 +35,11 @@ library Multicall { ...@@ -38,17 +35,11 @@ library Multicall {
contract Optimist_Initializer is Test { contract Optimist_Initializer is Test {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Initialized(uint8); event Initialized(uint8);
event AttestationCreated( event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
string constant name = "Optimist name"; string constant name = "Optimist name";
string constant symbol = "OPTIMISTSYMBOL"; string constant symbol = "OPTIMISTSYMBOL";
string constant base_uri = string constant base_uri = "https://storageapi.fleek.co/6442819a1b05-bucket/optimist-nft/attributes";
"https://storageapi.fleek.co/6442819a1b05-bucket/optimist-nft/attributes";
AttestationStation attestationStation; AttestationStation attestationStation;
Optimist optimist; Optimist optimist;
OptimistAllowlist optimistAllowlist; OptimistAllowlist optimistAllowlist;
...@@ -70,21 +61,12 @@ contract Optimist_Initializer is Test { ...@@ -70,21 +61,12 @@ contract Optimist_Initializer is Test {
/// @notice BaseURI attestor sets the baseURI of the Optimist NFT. /// @notice BaseURI attestor sets the baseURI of the Optimist NFT.
function _attestBaseURI(string memory _baseUri) internal { function _attestBaseURI(string memory _baseUri) internal {
bytes32 baseURIAttestationKey = optimist.BASE_URI_ATTESTATION_KEY(); bytes32 baseURIAttestationKey = optimist.BASE_URI_ATTESTATION_KEY();
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
memory attestationData = new AttestationStation.AttestationData[](1); attestationData[0] =
attestationData[0] = AttestationStation.AttestationData( AttestationStation.AttestationData(address(optimist), baseURIAttestationKey, bytes(_baseUri));
address(optimist),
baseURIAttestationKey,
bytes(_baseUri)
);
vm.expectEmit(true, true, true, true, address(attestationStation)); vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated( emit AttestationCreated(carol_baseURIAttestor, address(optimist), baseURIAttestationKey, bytes(_baseUri));
carol_baseURIAttestor,
address(optimist),
baseURIAttestationKey,
bytes(_baseUri)
);
vm.prank(carol_baseURIAttestor); vm.prank(carol_baseURIAttestor);
attestationStation.attest(attestationData); attestationStation.attest(attestationData);
} }
...@@ -92,14 +74,10 @@ contract Optimist_Initializer is Test { ...@@ -92,14 +74,10 @@ contract Optimist_Initializer is Test {
/// @notice Allowlist attestor creates an attestation for an address. /// @notice Allowlist attestor creates an attestation for an address.
function _attestAllowlist(address _about) internal { function _attestAllowlist(address _about) internal {
bytes32 attestationKey = optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(); bytes32 attestationKey = optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY();
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value // we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({ attestationData[0] =
about: _about, AttestationStation.AttestationData({ about: _about, key: attestationKey, val: bytes("true") });
key: attestationKey,
val: bytes("true")
});
vm.expectEmit(true, true, true, true, address(attestationStation)); vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(alice_allowlistAttestor, _about, attestationKey, bytes("true")); emit AttestationCreated(alice_allowlistAttestor, _about, attestationKey, bytes("true"));
...@@ -113,14 +91,10 @@ contract Optimist_Initializer is Test { ...@@ -113,14 +91,10 @@ contract Optimist_Initializer is Test {
/// @notice Coinbase Quest attestor creates an attestation for an address. /// @notice Coinbase Quest attestor creates an attestation for an address.
function _attestCoinbaseQuest(address _about) internal { function _attestCoinbaseQuest(address _about) internal {
bytes32 attestationKey = optimistAllowlist.COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY(); bytes32 attestationKey = optimistAllowlist.COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY();
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value // we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({ attestationData[0] =
about: _about, AttestationStation.AttestationData({ about: _about, key: attestationKey, val: bytes("true") });
key: attestationKey,
val: bytes("true")
});
vm.expectEmit(true, true, true, true, address(attestationStation)); vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(ted_coinbaseAttestor, _about, attestationKey, bytes("true")); emit AttestationCreated(ted_coinbaseAttestor, _about, attestationKey, bytes("true"));
...@@ -145,15 +119,12 @@ contract Optimist_Initializer is Test { ...@@ -145,15 +119,12 @@ contract Optimist_Initializer is Test {
optimistInviter.setInviteCounts(addresses, 3); optimistInviter.setInviteCounts(addresses, 3);
// issue a new invite // issue a new invite
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper OptimistInviter.ClaimableInvite memory claimableInvite =
.getClaimableInviteWithNewNonce(inviter); optimistInviterHelper.getClaimableInviteWithNewNonce(inviter);
// EIP-712 sign with Inviter's private key // EIP-712 sign with Inviter's private key
(uint8 v, bytes32 r, bytes32 s) = vm.sign( (uint8 v, bytes32 r, bytes32 s) = vm.sign(inviterPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
inviterPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
bytes memory signature = abi.encodePacked(r, s, v); bytes memory signature = abi.encodePacked(r, s, v);
bytes32 hashedCommit = keccak256(abi.encode(_about, signature)); bytes32 hashedCommit = keccak256(abi.encode(_about, signature));
...@@ -492,10 +463,7 @@ contract OptimistTest is Optimist_Initializer { ...@@ -492,10 +463,7 @@ contract OptimistTest is Optimist_Initializer {
// expect approval amount to stil be 0 // expect approval amount to stil be 0
assertEq(optimist.getApproved(_getTokenId(bob)), address(0)); assertEq(optimist.getApproved(_getTokenId(bob)), address(0));
// isApprovedForAll should return false // isApprovedForAll should return false
assertEq( assertEq(optimist.isApprovedForAll(alice_allowlistAttestor, alice_allowlistAttestor), false);
optimist.isApprovedForAll(alice_allowlistAttestor, alice_allowlistAttestor),
false
);
} }
/// @notice Only owner should be able to burn token. /// @notice Only owner should be able to burn token.
...@@ -554,15 +522,12 @@ contract OptimistTest is Optimist_Initializer { ...@@ -554,15 +522,12 @@ contract OptimistTest is Optimist_Initializer {
optimistInviter.setInviteCounts(addresses, 3); optimistInviter.setInviteCounts(addresses, 3);
// issue a new invite // issue a new invite
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper OptimistInviter.ClaimableInvite memory claimableInvite =
.getClaimableInviteWithNewNonce(inviter); optimistInviterHelper.getClaimableInviteWithNewNonce(inviter);
// EIP-712 sign with Inviter's private key // EIP-712 sign with Inviter's private key
(uint8 v, bytes32 r, bytes32 s) = vm.sign( (uint8 v, bytes32 r, bytes32 s) = vm.sign(inviterPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
inviterPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
bytes memory signature = abi.encodePacked(r, s, v); bytes memory signature = abi.encodePacked(r, s, v);
bytes32 hashedCommit = keccak256(abi.encode(bob, signature)); bytes32 hashedCommit = keccak256(abi.encode(bob, signature));
...@@ -579,12 +544,7 @@ contract OptimistTest is Optimist_Initializer { ...@@ -579,12 +544,7 @@ contract OptimistTest is Optimist_Initializer {
// First call is to claim the invite, receiving the attestation // First call is to claim the invite, receiving the attestation
calls[0] = IMulticall3.Call3({ calls[0] = IMulticall3.Call3({
target: address(optimistInviter), target: address(optimistInviter),
callData: abi.encodeWithSelector( callData: abi.encodeWithSelector(optimistInviter.claimInvite.selector, bob, claimableInvite, signature),
optimistInviter.claimInvite.selector,
bob,
claimableInvite,
signature
),
allowFailure: false allowFailure: false
}); });
......
...@@ -10,12 +10,8 @@ import { OptimistInviterHelper } from "./Helpers.sol"; ...@@ -10,12 +10,8 @@ import { OptimistInviterHelper } from "./Helpers.sol";
import { OptimistConstants } from "../src/periphery/op-nft/libraries/OptimistConstants.sol"; import { OptimistConstants } from "../src/periphery/op-nft/libraries/OptimistConstants.sol";
contract OptimistAllowlist_Initializer is Test { contract OptimistAllowlist_Initializer is Test {
event AttestationCreated( event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
address internal alice_allowlistAttestor; address internal alice_allowlistAttestor;
address internal sally_coinbaseQuestAttestor; address internal sally_coinbaseQuestAttestor;
address internal ted; address internal ted;
...@@ -49,8 +45,7 @@ contract OptimistAllowlist_Initializer is Test { ...@@ -49,8 +45,7 @@ contract OptimistAllowlist_Initializer is Test {
} }
function attestAllowlist(address _about) internal { function attestAllowlist(address _about) internal {
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value // we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({ attestationData[0] = AttestationStation.AttestationData({
about: _about, about: _about,
...@@ -62,8 +57,7 @@ contract OptimistAllowlist_Initializer is Test { ...@@ -62,8 +57,7 @@ contract OptimistAllowlist_Initializer is Test {
} }
function attestCoinbaseQuest(address _about) internal { function attestCoinbaseQuest(address _about) internal {
AttestationStation.AttestationData[] AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value // we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({ attestationData[0] = AttestationStation.AttestationData({
about: _about, about: _about,
...@@ -84,14 +78,11 @@ contract OptimistAllowlist_Initializer is Test { ...@@ -84,14 +78,11 @@ contract OptimistAllowlist_Initializer is Test {
optimistInviter.setInviteCounts(addresses, 3); optimistInviter.setInviteCounts(addresses, 3);
// issue a new invite // issue a new invite
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper OptimistInviter.ClaimableInvite memory claimableInvite =
.getClaimableInviteWithNewNonce(bob); optimistInviterHelper.getClaimableInviteWithNewNonce(bob);
// EIP-712 sign with Bob's private key // EIP-712 sign with Bob's private key
bytes memory signature = _getSignature( bytes memory signature = _getSignature(bobPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
bobPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
bytes32 hashedCommit = keccak256(abi.encode(claimer, signature)); bytes32 hashedCommit = keccak256(abi.encode(claimer, signature));
...@@ -107,11 +98,7 @@ contract OptimistAllowlist_Initializer is Test { ...@@ -107,11 +98,7 @@ contract OptimistAllowlist_Initializer is Test {
} }
/// @notice Get signature as a bytes blob, since SignatureChecker takes arbitrary signature blobs. /// @notice Get signature as a bytes blob, since SignatureChecker takes arbitrary signature blobs.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
internal
pure
returns (bytes memory)
{
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest); (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v); bytes memory signature = abi.encodePacked(r, s, v);
...@@ -173,11 +160,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer { ...@@ -173,11 +160,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
function test_isAllowedToMint_fromWrongAllowlistAttestor_fails() external { function test_isAllowedToMint_fromWrongAllowlistAttestor_fails() external {
// Ted is not the allowlist attestor // Ted is not the allowlist attestor
vm.prank(ted); vm.prank(ted);
attestationStation.attest( attestationStation.attest(bob, optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(), bytes("true"));
bob,
optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(),
bytes("true")
);
assertFalse(optimistAllowlist.isAllowedToMint(bob)); assertFalse(optimistAllowlist.isAllowedToMint(bob));
} }
...@@ -185,11 +168,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer { ...@@ -185,11 +168,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
function test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() external { function test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() external {
// Ted is not the coinbase quest attestor // Ted is not the coinbase quest attestor
vm.prank(ted); vm.prank(ted);
attestationStation.attest( attestationStation.attest(bob, optimistAllowlist.COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY(), bytes("true"));
bob,
optimistAllowlist.COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY(),
bytes("true")
);
assertFalse(optimistAllowlist.isAllowedToMint(bob)); assertFalse(optimistAllowlist.isAllowedToMint(bob));
} }
...@@ -197,11 +176,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer { ...@@ -197,11 +176,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
/// minting. /// minting.
function test_isAllowedToMint_fromWrongOptimistInviter_fails() external { function test_isAllowedToMint_fromWrongOptimistInviter_fails() external {
vm.prank(ted); vm.prank(ted);
attestationStation.attest( attestationStation.attest(bob, OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY, bytes("true"));
bob,
OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY,
bytes("true")
);
assertFalse(optimistAllowlist.isAllowedToMint(bob)); assertFalse(optimistAllowlist.isAllowedToMint(bob));
} }
...@@ -215,11 +190,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer { ...@@ -215,11 +190,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
// A invalid attestation, as Ted is not allowlist attestor // A invalid attestation, as Ted is not allowlist attestor
vm.prank(ted); vm.prank(ted);
attestationStation.attest( attestationStation.attest(bob, optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(), bytes("true"));
bob,
optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(),
bytes("true")
);
// Since Bob has at least one valid attestation, he should be allowed to mint // Since Bob has at least one valid attestation, he should be allowed to mint
assertTrue(optimistAllowlist.isAllowedToMint(bob)); assertTrue(optimistAllowlist.isAllowedToMint(bob));
......
...@@ -15,12 +15,7 @@ contract OptimistInviter_Initializer is Test { ...@@ -15,12 +15,7 @@ contract OptimistInviter_Initializer is Test {
event InviteClaimed(address indexed issuer, address indexed claimer); event InviteClaimed(address indexed issuer, address indexed claimer);
event Initialized(uint8 version); event Initialized(uint8 version);
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event AttestationCreated( event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
bytes32 EIP712_DOMAIN_TYPEHASH; bytes32 EIP712_DOMAIN_TYPEHASH;
...@@ -62,9 +57,8 @@ contract OptimistInviter_Initializer is Test { ...@@ -62,9 +57,8 @@ contract OptimistInviter_Initializer is Test {
vm.deal(ted, 1 ether); vm.deal(ted, 1 ether);
vm.deal(eve, 1 ether); vm.deal(eve, 1 ether);
EIP712_DOMAIN_TYPEHASH = keccak256( EIP712_DOMAIN_TYPEHASH =
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
);
_initializeContracts(); _initializeContracts();
} }
...@@ -94,19 +88,13 @@ contract OptimistInviter_Initializer is Test { ...@@ -94,19 +88,13 @@ contract OptimistInviter_Initializer is Test {
/// @notice Returns true if claimer has the proper attestation from OptimistInviter to mint. /// @notice Returns true if claimer has the proper attestation from OptimistInviter to mint.
function _hasMintAttestation(address _claimer) internal view returns (bool) { function _hasMintAttestation(address _claimer) internal view returns (bool) {
bytes memory attestation = attestationStation.attestations( bytes memory attestation = attestationStation.attestations(
address(optimistInviter), address(optimistInviter), _claimer, OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
_claimer,
OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
); );
return attestation.length > 0; return attestation.length > 0;
} }
/// @notice Get signature as a bytes blob, since SignatureChecker takes arbitrary signature blobs. /// @notice Get signature as a bytes blob, since SignatureChecker takes arbitrary signature blobs.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
internal
pure
returns (bytes memory)
{
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest); (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v); bytes memory signature = abi.encodePacked(r, s, v);
...@@ -119,14 +107,13 @@ contract OptimistInviter_Initializer is Test { ...@@ -119,14 +107,13 @@ contract OptimistInviter_Initializer is Test {
internal internal
returns (OptimistInviter.ClaimableInvite memory, bytes memory) returns (OptimistInviter.ClaimableInvite memory, bytes memory)
{ {
return return _issueInviteWithEIP712Domain(
_issueInviteWithEIP712Domain( _privateKey,
_privateKey, bytes("OptimistInviter"),
bytes("OptimistInviter"), bytes(optimistInviter.EIP712_VERSION()),
bytes(optimistInviter.EIP712_VERSION()), block.chainid,
block.chainid, address(optimistInviter)
address(optimistInviter) );
);
} }
/// @notice Signs a claimable invite with the given private key and returns the signature using /// @notice Signs a claimable invite with the given private key and returns the signature using
...@@ -138,22 +125,21 @@ contract OptimistInviter_Initializer is Test { ...@@ -138,22 +125,21 @@ contract OptimistInviter_Initializer is Test {
bytes memory _eip712Version, bytes memory _eip712Version,
uint256 _eip712Chainid, uint256 _eip712Chainid,
address _eip712VerifyingContract address _eip712VerifyingContract
) internal returns (OptimistInviter.ClaimableInvite memory, bytes memory) { )
internal
returns (OptimistInviter.ClaimableInvite memory, bytes memory)
{
address issuer = vm.addr(_issuerPrivateKey); address issuer = vm.addr(_issuerPrivateKey);
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper OptimistInviter.ClaimableInvite memory claimableInvite =
.getClaimableInviteWithNewNonce(issuer); optimistInviterHelper.getClaimableInviteWithNewNonce(issuer);
return ( return (
claimableInvite, claimableInvite,
_getSignature( _getSignature(
_issuerPrivateKey, _issuerPrivateKey,
optimistInviterHelper.getDigestWithEIP712Domain( optimistInviterHelper.getDigestWithEIP712Domain(
claimableInvite, claimableInvite, _eip712Name, _eip712Version, _eip712Chainid, _eip712VerifyingContract
_eip712Name, )
_eip712Version,
_eip712Chainid,
_eip712VerifyingContract
) )
)
); );
} }
...@@ -170,24 +156,22 @@ contract OptimistInviter_Initializer is Test { ...@@ -170,24 +156,22 @@ contract OptimistInviter_Initializer is Test {
/// @notice Signs a claimable invite with the given private key. The claimer commits then claims /// @notice Signs a claimable invite with the given private key. The claimer commits then claims
/// the invite. Checks that all expected events are emitted and that state is updated /// the invite. Checks that all expected events are emitted and that state is updated
/// correctly. Returns the signature and invite for use in tests. /// correctly. Returns the signature and invite for use in tests.
function _issueThenClaimShouldSucceed(uint256 _issuerPrivateKey, address _claimer) function _issueThenClaimShouldSucceed(
uint256 _issuerPrivateKey,
address _claimer
)
internal internal
returns (OptimistInviter.ClaimableInvite memory, bytes memory) returns (OptimistInviter.ClaimableInvite memory, bytes memory)
{ {
address issuer = vm.addr(_issuerPrivateKey); address issuer = vm.addr(_issuerPrivateKey);
uint256 prevInviteCount = _getInviteCount(issuer); uint256 prevInviteCount = _getInviteCount(issuer);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) =
OptimistInviter.ClaimableInvite memory claimableInvite, _issueInviteAs(_issuerPrivateKey);
bytes memory signature
) = _issueInviteAs(_issuerPrivateKey);
_commitInviteAs(_claimer, signature); _commitInviteAs(_claimer, signature);
// The hash(claimer ++ signature) should be committed // The hash(claimer ++ signature) should be committed
assertEq( assertEq(optimistInviter.commitmentTimestamps(keccak256(abi.encode(_claimer, signature))), block.timestamp);
optimistInviter.commitmentTimestamps(keccak256(abi.encode(_claimer, signature))),
block.timestamp
);
_passMinCommitmentPeriod(); _passMinCommitmentPeriod();
...@@ -227,10 +211,7 @@ contract OptimistInviter_Initializer is Test { ...@@ -227,10 +211,7 @@ contract OptimistInviter_Initializer is Test {
vm.expectEmit(true, true, true, true, address(attestationStation)); vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated( emit AttestationCreated(
address(optimistInviter), address(optimistInviter), _to, optimistInviter.CAN_INVITE_ATTESTATION_KEY(), bytes("true")
_to,
optimistInviter.CAN_INVITE_ATTESTATION_KEY(),
bytes("true")
); );
vm.prank(alice_inviteGranter); vm.prank(alice_inviteGranter);
...@@ -258,18 +239,12 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -258,18 +239,12 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
vm.expectEmit(true, true, true, true, address(attestationStation)); vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated( emit AttestationCreated(
address(optimistInviter), address(optimistInviter), bob, optimistInviter.CAN_INVITE_ATTESTATION_KEY(), bytes("true")
bob,
optimistInviter.CAN_INVITE_ATTESTATION_KEY(),
bytes("true")
); );
vm.expectEmit(true, true, true, true, address(attestationStation)); vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated( emit AttestationCreated(
address(optimistInviter), address(optimistInviter), sally, optimistInviter.CAN_INVITE_ATTESTATION_KEY(), bytes("true")
sally,
optimistInviter.CAN_INVITE_ATTESTATION_KEY(),
bytes("true")
); );
vm.expectEmit(true, true, true, true, address(attestationStation)); vm.expectEmit(true, true, true, true, address(attestationStation));
...@@ -348,10 +323,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -348,10 +323,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// @notice Bob issues signature, and Ted commits the invite for Sally. Eve claims for Sally. /// @notice Bob issues signature, and Ted commits the invite for Sally. Eve claims for Sally.
function test_claimInvite_claimForSomeoneElse_succeeds() external { function test_claimInvite_claimForSomeoneElse_succeeds() external {
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteAs(bobPrivateKey);
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteAs(bobPrivateKey);
vm.prank(ted); vm.prank(ted);
optimistInviter.commitInvite(keccak256(abi.encode(sally, signature))); optimistInviter.commitInvite(keccak256(abi.encode(sally, signature)));
...@@ -379,10 +351,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -379,10 +351,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() external { function test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() external {
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteAs(bobPrivateKey);
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteAs(bobPrivateKey);
_commitInviteAs(sally, signature); _commitInviteAs(sally, signature);
...@@ -397,16 +366,9 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -397,16 +366,9 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// @notice Signature issued for previous versions of the contract should fail. /// @notice Signature issued for previous versions of the contract should fail.
function test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() external { function test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() external {
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteWithEIP712Domain(
OptimistInviter.ClaimableInvite memory claimableInvite, bobPrivateKey, "OptimismInviter", "0.9.1", block.chainid, address(optimistInviter)
bytes memory signature );
) = _issueInviteWithEIP712Domain(
bobPrivateKey,
"OptimismInviter",
"0.9.1",
block.chainid,
address(optimistInviter)
);
_commitInviteAs(sally, signature); _commitInviteAs(sally, signature);
_passMinCommitmentPeriod(); _passMinCommitmentPeriod();
...@@ -420,16 +382,9 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -420,16 +382,9 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// should fail. /// should fail.
function test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() external { function test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() external {
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteWithEIP712Domain(
OptimistInviter.ClaimableInvite memory claimableInvite, bobPrivateKey, "OptimismInviter", bytes(optimistInviter.EIP712_VERSION()), 1, address(optimistInviter)
bytes memory signature );
) = _issueInviteWithEIP712Domain(
bobPrivateKey,
"OptimismInviter",
bytes(optimistInviter.EIP712_VERSION()),
1,
address(optimistInviter)
);
_commitInviteAs(sally, signature); _commitInviteAs(sally, signature);
_passMinCommitmentPeriod(); _passMinCommitmentPeriod();
...@@ -443,16 +398,9 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -443,16 +398,9 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// on a different address should fail. /// on a different address should fail.
function test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() external { function test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() external {
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteWithEIP712Domain(
OptimistInviter.ClaimableInvite memory claimableInvite, bobPrivateKey, "OptimismInviter", bytes(optimistInviter.EIP712_VERSION()), block.chainid, address(0xBEEF)
bytes memory signature );
) = _issueInviteWithEIP712Domain(
bobPrivateKey,
"OptimismInviter",
bytes(optimistInviter.EIP712_VERSION()),
block.chainid,
address(0xBEEF)
);
_commitInviteAs(sally, signature); _commitInviteAs(sally, signature);
_passMinCommitmentPeriod(); _passMinCommitmentPeriod();
...@@ -466,10 +414,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -466,10 +414,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_replayingUsedNonce_reverts() external { function test_claimInvite_replayingUsedNonce_reverts() external {
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) =
OptimistInviter.ClaimableInvite memory claimableInvite, _issueThenClaimShouldSucceed(bobPrivateKey, sally);
bytes memory signature
) = _issueThenClaimShouldSucceed(bobPrivateKey, sally);
// Sally tries to claim the invite using the same signature // Sally tries to claim the invite using the same signature
vm.expectRevert("OptimistInviter: nonce has already been used"); vm.expectRevert("OptimistInviter: nonce has already been used");
...@@ -491,13 +437,10 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -491,13 +437,10 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_usingERC1271Wallet_succeeds() external { function test_claimInvite_usingERC1271Wallet_succeeds() external {
_grantInvitesTo(address(carolERC1271Wallet)); _grantInvitesTo(address(carolERC1271Wallet));
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper OptimistInviter.ClaimableInvite memory claimableInvite =
.getClaimableInviteWithNewNonce(address(carolERC1271Wallet)); optimistInviterHelper.getClaimableInviteWithNewNonce(address(carolERC1271Wallet));
bytes memory signature = _getSignature( bytes memory signature = _getSignature(carolPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
carolPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
// Sally tries to claim the invite // Sally tries to claim the invite
_commitInviteAs(sally, signature); _commitInviteAs(sally, signature);
...@@ -520,10 +463,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -520,10 +463,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// claim the Bob's invite without committing the signature first. /// claim the Bob's invite without committing the signature first.
function test_claimInvite_withoutCommittingHash_reverts() external { function test_claimInvite_withoutCommittingHash_reverts() external {
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteAs(bobPrivateKey);
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteAs(bobPrivateKey);
vm.expectRevert("OptimistInviter: claimer and signature have not been committed yet"); vm.expectRevert("OptimistInviter: claimer and signature have not been committed yet");
vm.prank(sally); vm.prank(sally);
...@@ -534,10 +474,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -534,10 +474,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_withIncorrectSignature_reverts() external { function test_claimInvite_withIncorrectSignature_reverts() external {
_grantInvitesTo(carol); _grantInvitesTo(carol);
_grantInvitesTo(bob); _grantInvitesTo(bob);
( (OptimistInviter.ClaimableInvite memory bobClaimableInvite, bytes memory bobSignature) =
OptimistInviter.ClaimableInvite memory bobClaimableInvite, _issueInviteAs(bobPrivateKey);
bytes memory bobSignature
) = _issueInviteAs(bobPrivateKey);
(, bytes memory carolSignature) = _issueInviteAs(carolPrivateKey); (, bytes memory carolSignature) = _issueInviteAs(carolPrivateKey);
_commitInviteAs(sally, bobSignature); _commitInviteAs(sally, bobSignature);
...@@ -554,10 +492,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -554,10 +492,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// fail. /// fail.
function test_claimInvite_whenIssuerNeverReceivedInvites_reverts() external { function test_claimInvite_whenIssuerNeverReceivedInvites_reverts() external {
// Bob was never granted any invites, but issues an invite for Eve // Bob was never granted any invites, but issues an invite for Eve
( (OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteAs(bobPrivateKey);
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteAs(bobPrivateKey);
_commitInviteAs(sally, signature); _commitInviteAs(sally, signature);
_passMinCommitmentPeriod(); _passMinCommitmentPeriod();
...@@ -580,10 +515,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -580,10 +515,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
assertEq(_getInviteCount(bob), 0); assertEq(_getInviteCount(bob), 0);
( (OptimistInviter.ClaimableInvite memory claimableInvite4, bytes memory signature4) =
OptimistInviter.ClaimableInvite memory claimableInvite4, _issueInviteAs(bobPrivateKey);
bytes memory signature4
) = _issueInviteAs(bobPrivateKey);
_commitInviteAs(eve, signature4); _commitInviteAs(eve, signature4);
_passMinCommitmentPeriod(); _passMinCommitmentPeriod();
......
...@@ -53,7 +53,9 @@ contract PreimageOracle_Test is Test { ...@@ -53,7 +53,9 @@ contract PreimageOracle_Test is Test {
bytes32 word, bytes32 word,
uint256 size, uint256 size,
uint256 partOffset uint256 partOffset
) public { )
public
{
// Bound the size to [0, 32] // Bound the size to [0, 32]
size = bound(size, 0, 32); size = bound(size, 0, 32);
// Bound the part offset to [0, size + 8] // Bound the part offset to [0, size + 8]
......
...@@ -29,8 +29,7 @@ contract Proxy_Test is Test { ...@@ -29,8 +29,7 @@ contract Proxy_Test is Test {
address alice = address(64); address alice = address(64);
bytes32 internal constant IMPLEMENTATION_KEY = bytes32 internal constant IMPLEMENTATION_KEY = bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1);
bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1);
bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1); bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1);
...@@ -155,10 +154,7 @@ contract Proxy_Test is Test { ...@@ -155,10 +154,7 @@ contract Proxy_Test is Test {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit Upgraded(address(simpleStorage)); emit Upgraded(address(simpleStorage));
vm.prank(alice); vm.prank(alice);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(address(simpleStorage), abi.encodeWithSelector(simpleStorage.set.selector, 1, 1));
address(simpleStorage),
abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
);
// The call should have impacted the state // The call should have impacted the state
uint256 result = SimpleStorage(address(proxy)).get(1); uint256 result = SimpleStorage(address(proxy)).get(1);
...@@ -191,10 +187,7 @@ contract Proxy_Test is Test { ...@@ -191,10 +187,7 @@ contract Proxy_Test is Test {
// The attempt to `upgradeToAndCall` // The attempt to `upgradeToAndCall`
// should revert when it is not called by the owner. // should revert when it is not called by the owner.
vm.expectRevert(); vm.expectRevert();
proxy.upgradeToAndCall( proxy.upgradeToAndCall(address(simpleStorage), abi.encodeWithSelector(simpleStorage.set.selector, 1, 1));
address(simpleStorage),
abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
);
} }
function test_upgradeToAndCall_isPayable_succeeds() external { function test_upgradeToAndCall_isPayable_succeeds() external {
...@@ -204,8 +197,7 @@ contract Proxy_Test is Test { ...@@ -204,8 +197,7 @@ contract Proxy_Test is Test {
// value. // value.
vm.prank(alice); vm.prank(alice);
proxy.upgradeToAndCall{ value: 1 ether }( proxy.upgradeToAndCall{ value: 1 ether }(
address(simpleStorage), address(simpleStorage), abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
); );
// The implementation address should be correct // The implementation address should be correct
...@@ -267,10 +259,7 @@ contract Proxy_Test is Test { ...@@ -267,10 +259,7 @@ contract Proxy_Test is Test {
(bool success, bytes memory returndata) = address(proxy).call(hex""); (bool success, bytes memory returndata) = address(proxy).call(hex"");
assertEq(success, false); assertEq(success, false);
bytes memory err = abi.encodeWithSignature( bytes memory err = abi.encodeWithSignature("Error(string)", "Proxy: implementation not initialized");
"Error(string)",
"Proxy: implementation not initialized"
);
assertEq(returndata, err); assertEq(returndata, err);
} }
......
...@@ -86,14 +86,8 @@ contract ProxyAdmin_Test is Test { ...@@ -86,14 +86,8 @@ contract ProxyAdmin_Test is Test {
function test_proxyType_succeeds() external { function test_proxyType_succeeds() external {
assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967)); assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));
assertEq( assertEq(uint256(admin.proxyType(address(chugsplash))), uint256(ProxyAdmin.ProxyType.CHUGSPLASH));
uint256(admin.proxyType(address(chugsplash))), assertEq(uint256(admin.proxyType(address(resolved))), uint256(ProxyAdmin.ProxyType.RESOLVED));
uint256(ProxyAdmin.ProxyType.CHUGSPLASH)
);
assertEq(
uint256(admin.proxyType(address(resolved))),
uint256(ProxyAdmin.ProxyType.RESOLVED)
);
} }
function test_erc1967GetProxyImplementation_succeeds() external { function test_erc1967GetProxyImplementation_succeeds() external {
...@@ -222,11 +216,7 @@ contract ProxyAdmin_Test is Test { ...@@ -222,11 +216,7 @@ contract ProxyAdmin_Test is Test {
function upgradeAndCall(address payable _proxy) internal { function upgradeAndCall(address payable _proxy) internal {
vm.prank(alice); vm.prank(alice);
admin.upgradeAndCall( admin.upgradeAndCall(_proxy, address(implementation), abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1));
_proxy,
address(implementation),
abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)
);
address impl = admin.getProxyImplementation(_proxy); address impl = admin.getProxyImplementation(_proxy);
assertEq(impl, address(implementation)); assertEq(impl, address(implementation));
......
...@@ -9,60 +9,38 @@ library LibRLP { ...@@ -9,60 +9,38 @@ library LibRLP {
using Bytes32AddressLib for bytes32; using Bytes32AddressLib for bytes32;
function computeAddress(address deployer, uint256 nonce) internal pure returns (address) { function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {
// The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80,
// A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. // computed via 0x80 + 0.
if (nonce == 0x00) // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix
return // that comes before it.
keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))) if (nonce == 0x00) {
.fromLast20Bytes(); return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))).fromLast20Bytes();
if (nonce <= 0x7f) }
return if (nonce <= 0x7f) {
keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))) return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))).fromLast20Bytes();
.fromLast20Bytes(); }
// Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix
if (nonce <= type(uint8).max) // of 0x80 + length.
return if (nonce <= type(uint8).max) {
keccak256( return keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))
abi.encodePacked( .fromLast20Bytes();
bytes1(0xd7), }
bytes1(0x94), if (nonce <= type(uint16).max) {
deployer, return keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))
bytes1(0x81), .fromLast20Bytes();
uint8(nonce) }
) if (nonce <= type(uint24).max) {
).fromLast20Bytes(); return keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))
if (nonce <= type(uint16).max) .fromLast20Bytes();
return }
keccak256(
abi.encodePacked(
bytes1(0xd8),
bytes1(0x94),
deployer,
bytes1(0x82),
uint16(nonce)
)
).fromLast20Bytes();
if (nonce <= type(uint24).max)
return
keccak256(
abi.encodePacked(
bytes1(0xd9),
bytes1(0x94),
deployer,
bytes1(0x83),
uint24(nonce)
)
).fromLast20Bytes();
// More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp
// 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)
// 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)
// 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)
// We assume nobody can have a nonce large enough to require more than 32 bytes. // We assume nobody can have a nonce large enough to require more than 32 bytes.
return return keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))
keccak256( .fromLast20Bytes();
abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))
).fromLast20Bytes();
} }
} }
...@@ -24,16 +24,12 @@ contract RLPReader_readBytes_Test is CommonTest { ...@@ -24,16 +24,12 @@ contract RLPReader_readBytes_Test is CommonTest {
} }
function test_readBytes_invalidStringLength_reverts() external { function test_readBytes_invalidStringLength_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be > than length of string length (long string)");
"RLPReader: length of content must be > than length of string length (long string)"
);
RLPReader.readBytes(hex"b9"); RLPReader.readBytes(hex"b9");
} }
function test_readBytes_invalidListLength_reverts() external { function test_readBytes_invalidListLength_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be > than length of list length (long list)");
"RLPReader: length of content must be > than length of list length (long list)"
);
RLPReader.readBytes(hex"ff"); RLPReader.readBytes(hex"ff");
} }
...@@ -43,9 +39,7 @@ contract RLPReader_readBytes_Test is CommonTest { ...@@ -43,9 +39,7 @@ contract RLPReader_readBytes_Test is CommonTest {
} }
function test_readBytes_invalidPrefix_reverts() external { function test_readBytes_invalidPrefix_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)");
"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)"
);
RLPReader.readBytes(hex"810a"); RLPReader.readBytes(hex"810a");
} }
} }
...@@ -109,9 +103,7 @@ contract RLPReader_readList_Test is CommonTest { ...@@ -109,9 +103,7 @@ contract RLPReader_readList_Test is CommonTest {
function test_readList_listLongerThan32Elements_reverts() external { function test_readList_listLongerThan32Elements_reverts() external {
vm.expectRevert(stdError.indexOOBError); vm.expectRevert(stdError.indexOOBError);
RLPReader.readList( RLPReader.readList(hex"e1454545454545454545454545454545454545454545454545454545454545454545");
hex"e1454545454545454545454545454545454545454545454545454545454545454545"
);
} }
function test_readList_listOfLists_succeeds() external { function test_readList_listOfLists_succeeds() external {
...@@ -143,64 +135,44 @@ contract RLPReader_readList_Test is CommonTest { ...@@ -143,64 +135,44 @@ contract RLPReader_readList_Test is CommonTest {
} }
function test_readList_invalidShortList_reverts() external { function test_readList_invalidShortList_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than list length (short list)");
"RLPReader: length of content must be greater than list length (short list)"
);
RLPReader.readList(hex"efdebd"); RLPReader.readList(hex"efdebd");
} }
function test_readList_longStringLength_reverts() external { function test_readList_longStringLength_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than list length (short list)");
"RLPReader: length of content must be greater than list length (short list)"
);
RLPReader.readList(hex"efb83600"); RLPReader.readList(hex"efb83600");
} }
function test_readList_notLongEnough_reverts() external { function test_readList_notLongEnough_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than list length (short list)");
"RLPReader: length of content must be greater than list length (short list)" RLPReader.readList(hex"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
);
RLPReader.readList(
hex"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
);
} }
function test_readList_int32Overflow_reverts() external { function test_readList_int32Overflow_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than total length (long string)");
"RLPReader: length of content must be greater than total length (long string)"
);
RLPReader.readList(hex"bf0f000000000000021111"); RLPReader.readList(hex"bf0f000000000000021111");
} }
function test_readList_int32Overflow2_reverts() external { function test_readList_int32Overflow2_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than total length (long list)");
"RLPReader: length of content must be greater than total length (long list)"
);
RLPReader.readList(hex"ff0f000000000000021111"); RLPReader.readList(hex"ff0f000000000000021111");
} }
function test_readList_incorrectLengthInArray_reverts() external { function test_readList_incorrectLengthInArray_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must not have any leading zeros (long string)");
"RLPReader: length of content must not have any leading zeros (long string)" RLPReader.readList(hex"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0");
);
RLPReader.readList(
hex"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0"
);
} }
function test_readList_leadingZerosInLongLengthArray1_reverts() external { function test_readList_leadingZerosInLongLengthArray1_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must not have any leading zeros (long string)");
"RLPReader: length of content must not have any leading zeros (long string)"
);
RLPReader.readList( RLPReader.readList(
hex"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" hex"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
); );
} }
function test_readList_leadingZerosInLongLengthArray2_reverts() external { function test_readList_leadingZerosInLongLengthArray2_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must not have any leading zeros (long string)");
"RLPReader: length of content must not have any leading zeros (long string)"
);
RLPReader.readList(hex"b800"); RLPReader.readList(hex"b800");
} }
...@@ -222,9 +194,7 @@ contract RLPReader_readList_Test is CommonTest { ...@@ -222,9 +194,7 @@ contract RLPReader_readList_Test is CommonTest {
} }
function test_readList_invalidValue_reverts() external { function test_readList_invalidValue_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than string length (short string)");
"RLPReader: length of content must be greater than string length (short string)"
);
RLPReader.readList(hex"91"); RLPReader.readList(hex"91");
} }
...@@ -234,30 +204,22 @@ contract RLPReader_readList_Test is CommonTest { ...@@ -234,30 +204,22 @@ contract RLPReader_readList_Test is CommonTest {
} }
function test_readList_notEnoughContentForString1_reverts() external { function test_readList_notEnoughContentForString1_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than total length (long string)");
"RLPReader: length of content must be greater than total length (long string)"
);
RLPReader.readList(hex"ba010000aabbccddeeff"); RLPReader.readList(hex"ba010000aabbccddeeff");
} }
function test_readList_notEnoughContentForString2_reverts() external { function test_readList_notEnoughContentForString2_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than total length (long string)");
"RLPReader: length of content must be greater than total length (long string)"
);
RLPReader.readList(hex"b840ffeeddccbbaa99887766554433221100"); RLPReader.readList(hex"b840ffeeddccbbaa99887766554433221100");
} }
function test_readList_notEnoughContentForList1_reverts() external { function test_readList_notEnoughContentForList1_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than total length (long list)");
"RLPReader: length of content must be greater than total length (long list)"
);
RLPReader.readList(hex"f90180"); RLPReader.readList(hex"f90180");
} }
function test_readList_notEnoughContentForList2_reverts() external { function test_readList_notEnoughContentForList2_reverts() external {
vm.expectRevert( vm.expectRevert("RLPReader: length of content must be greater than total length (long list)");
"RLPReader: length of content must be greater than total length (long list)"
);
RLPReader.readList(hex"ffffffffffffffffff0001020304050607"); RLPReader.readList(hex"ffffffffffffffffff0001020304050607");
} }
......
...@@ -23,9 +23,7 @@ contract ResolvedDelegateProxy_Test is Test { ...@@ -23,9 +23,7 @@ contract ResolvedDelegateProxy_Test is Test {
addressManager.setAddress("SimpleImplementation", address(impl)); addressManager.setAddress("SimpleImplementation", address(impl));
// Set up the proxy. // Set up the proxy.
proxy = SimpleImplementation( proxy = SimpleImplementation(address(new ResolvedDelegateProxy(addressManager, "SimpleImplementation")));
address(new ResolvedDelegateProxy(addressManager, "SimpleImplementation"))
);
} }
/// @dev Tests that the proxy properly bubbles up returndata when the delegatecall succeeds. /// @dev Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.
...@@ -45,9 +43,7 @@ contract ResolvedDelegateProxy_Test is Test { ...@@ -45,9 +43,7 @@ contract ResolvedDelegateProxy_Test is Test {
/// address manager is not set. /// address manager is not set.
function test_fallback_addressManagerNotSet_reverts() public { function test_fallback_addressManagerNotSet_reverts() public {
AddressManager am = new AddressManager(); AddressManager am = new AddressManager();
SimpleImplementation p = SimpleImplementation( SimpleImplementation p = SimpleImplementation(address(new ResolvedDelegateProxy(am, "SimpleImplementation")));
address(new ResolvedDelegateProxy(am, "SimpleImplementation"))
);
vm.expectRevert("ResolvedDelegateProxy: target address must be initialized"); vm.expectRevert("ResolvedDelegateProxy: target address must be initialized");
p.foo(0); p.foo(0);
......
...@@ -29,22 +29,13 @@ contract MeterUser is ResourceMetering { ...@@ -29,22 +29,13 @@ contract MeterUser is ResourceMetering {
return _resourceConfig(); return _resourceConfig();
} }
function _resourceConfig() function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory) {
internal
view
override
returns (ResourceMetering.ResourceConfig memory)
{
return innerConfig; return innerConfig;
} }
function use(uint64 _amount) public metered(_amount) {} function use(uint64 _amount) public metered(_amount) { }
function set( function set(uint128 _prevBaseFee, uint64 _prevBoughtGas, uint64 _prevBlockNum) public {
uint128 _prevBaseFee,
uint64 _prevBoughtGas,
uint64 _prevBlockNum
) public {
params = ResourceMetering.ResourceParams({ params = ResourceMetering.ResourceParams({
prevBaseFee: _prevBaseFee, prevBaseFee: _prevBaseFee,
prevBoughtGas: _prevBoughtGas, prevBoughtGas: _prevBoughtGas,
...@@ -145,12 +136,12 @@ contract ResourceMetering_Test is Test { ...@@ -145,12 +136,12 @@ contract ResourceMetering_Test is Test {
meter.use(target * elasticityMultiplier); meter.use(target * elasticityMultiplier);
(, uint64 prevBoughtGas, ) = meter.params(); (, uint64 prevBoughtGas,) = meter.params();
assertEq(prevBoughtGas, target * elasticityMultiplier); assertEq(prevBoughtGas, target * elasticityMultiplier);
vm.roll(initialBlockNum + 1); vm.roll(initialBlockNum + 1);
meter.use(0); meter.use(0);
(uint128 postBaseFee, , ) = meter.params(); (uint128 postBaseFee,,) = meter.params();
assertEq(postBaseFee, 2125000000); assertEq(postBaseFee, 2125000000);
} }
...@@ -165,7 +156,7 @@ contract ResourceMetering_Test is Test { ...@@ -165,7 +156,7 @@ contract ResourceMetering_Test is Test {
meter.setParams(rcfg); meter.setParams(rcfg);
meter.use(target * elasticityMultiplier); meter.use(target * elasticityMultiplier);
(, uint64 prevBoughtGas, ) = meter.params(); (, uint64 prevBoughtGas,) = meter.params();
assertEq(prevBoughtGas, target * elasticityMultiplier); assertEq(prevBoughtGas, target * elasticityMultiplier);
vm.roll(initialBlockNum + 2); vm.roll(initialBlockNum + 2);
...@@ -207,11 +198,7 @@ contract CustomMeterUser is ResourceMetering { ...@@ -207,11 +198,7 @@ contract CustomMeterUser is ResourceMetering {
uint256 public startGas; uint256 public startGas;
uint256 public endGas; uint256 public endGas;
constructor( constructor(uint128 _prevBaseFee, uint64 _prevBoughtGas, uint64 _prevBlockNum) {
uint128 _prevBaseFee,
uint64 _prevBoughtGas,
uint64 _prevBlockNum
) {
params = ResourceMetering.ResourceParams({ params = ResourceMetering.ResourceParams({
prevBaseFee: _prevBaseFee, prevBaseFee: _prevBaseFee,
prevBoughtGas: _prevBoughtGas, prevBoughtGas: _prevBoughtGas,
...@@ -219,12 +206,7 @@ contract CustomMeterUser is ResourceMetering { ...@@ -219,12 +206,7 @@ contract CustomMeterUser is ResourceMetering {
}); });
} }
function _resourceConfig() function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) {
internal
pure
override
returns (ResourceMetering.ResourceConfig memory)
{
return Constants.DEFAULT_RESOURCE_CONFIG(); return Constants.DEFAULT_RESOURCE_CONFIG();
} }
...@@ -250,15 +232,13 @@ contract ArtifactResourceMetering_Test is Test { ...@@ -250,15 +232,13 @@ contract ArtifactResourceMetering_Test is Test {
string internal outfile; string internal outfile;
// keccak256(abi.encodeWithSignature("Error(string)", "ResourceMetering: cannot buy more gas than available gas limit")) // keccak256(abi.encodeWithSignature("Error(string)", "ResourceMetering: cannot buy more gas than available gas
bytes32 internal cannotBuyMoreGas = // limit"))
0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429; bytes32 internal cannotBuyMoreGas = 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;
// keccak256(abi.encodeWithSignature("Panic(uint256)", 0x11)) // keccak256(abi.encodeWithSignature("Panic(uint256)", 0x11))
bytes32 internal overflowErr = bytes32 internal overflowErr = 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;
0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;
// keccak256(hex"") // keccak256(hex"")
bytes32 internal emptyReturnData = bytes32 internal emptyReturnData = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
/// @dev Sets up the tests with constants from the ResourceMetering contract. /// @dev Sets up the tests with constants from the ResourceMetering contract.
function setUp() public { function setUp() public {
...@@ -272,7 +252,7 @@ contract ArtifactResourceMetering_Test is Test { ...@@ -272,7 +252,7 @@ contract ArtifactResourceMetering_Test is Test {
targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier); targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);
outfile = string.concat(vm.projectRoot(), "/.resource-metering.csv"); outfile = string.concat(vm.projectRoot(), "/.resource-metering.csv");
try vm.removeFile(outfile) {} catch {} try vm.removeFile(outfile) { } catch { }
} }
/// @dev Generates a CSV file. No more than the L1 block gas limit should /// @dev Generates a CSV file. No more than the L1 block gas limit should
...@@ -348,9 +328,7 @@ contract ArtifactResourceMetering_Test is Test { ...@@ -348,9 +328,7 @@ contract ArtifactResourceMetering_Test is Test {
// Call the metering code and catch the various // Call the metering code and catch the various
// types of errors. // types of errors.
uint256 gasConsumed = 0; uint256 gasConsumed = 0;
try meter.use{ gas: 30_000_000 }(requestedGas) returns ( try meter.use{ gas: 30_000_000 }(requestedGas) returns (uint256 _gasConsumed) {
uint256 _gasConsumed
) {
gasConsumed = _gasConsumed; gasConsumed = _gasConsumed;
} catch (bytes memory err) { } catch (bytes memory err) {
bytes32 hash = keccak256(err); bytes32 hash = keccak256(err);
......
...@@ -9,12 +9,7 @@ import { SafeCall } from "../src/libraries/SafeCall.sol"; ...@@ -9,12 +9,7 @@ import { SafeCall } from "../src/libraries/SafeCall.sol";
contract SafeCall_Test is CommonTest { contract SafeCall_Test is CommonTest {
/// @dev Tests that the `send` function succeeds. /// @dev Tests that the `send` function succeeds.
function testFuzz_send_succeeds( function testFuzz_send_succeeds(address from, address to, uint256 gas, uint64 value) external {
address from,
address to,
uint256 gas,
uint64 value
) external {
vm.assume(from.balance == 0); vm.assume(from.balance == 0);
vm.assume(to.balance == 0); vm.assume(to.balance == 0);
// no precompiles (mainnet) // no precompiles (mainnet)
...@@ -49,13 +44,7 @@ contract SafeCall_Test is CommonTest { ...@@ -49,13 +44,7 @@ contract SafeCall_Test is CommonTest {
} }
/// @dev Tests that `call` succeeds. /// @dev Tests that `call` succeeds.
function testFuzz_call_succeeds( function testFuzz_call_succeeds(address from, address to, uint256 gas, uint64 value, bytes memory data) external {
address from,
address to,
uint256 gas,
uint64 value,
bytes memory data
) external {
vm.assume(from.balance == 0); vm.assume(from.balance == 0);
vm.assume(to.balance == 0); vm.assume(to.balance == 0);
// no precompiles (mainnet) // no precompiles (mainnet)
...@@ -96,7 +85,9 @@ contract SafeCall_Test is CommonTest { ...@@ -96,7 +85,9 @@ contract SafeCall_Test is CommonTest {
uint64 minGas, uint64 minGas,
uint64 value, uint64 value,
bytes memory data bytes memory data
) external { )
external
{
vm.assume(from.balance == 0); vm.assume(from.balance == 0);
vm.assume(to.balance == 0); vm.assume(to.balance == 0);
// no precompiles (mainnet) // no precompiles (mainnet)
...@@ -145,12 +136,7 @@ contract SafeCall_Test is CommonTest { ...@@ -145,12 +136,7 @@ contract SafeCall_Test is CommonTest {
if (i < 65_907) { if (i < 65_907) {
assertFalse(caller.makeSafeCall(i, 25_000)); assertFalse(caller.makeSafeCall(i, 25_000));
} else { } else {
vm.expectCallMinGas( vm.expectCallMinGas(address(caller), 0, 25_000, abi.encodeWithSelector(caller.setA.selector, 1));
address(caller),
0,
25_000,
abi.encodeWithSelector(caller.setA.selector, 1)
);
assertTrue(caller.makeSafeCall(i, 25_000)); assertTrue(caller.makeSafeCall(i, 25_000));
} }
...@@ -170,12 +156,7 @@ contract SafeCall_Test is CommonTest { ...@@ -170,12 +156,7 @@ contract SafeCall_Test is CommonTest {
if (i < 15_278_606) { if (i < 15_278_606) {
assertFalse(caller.makeSafeCall(i, 15_000_000)); assertFalse(caller.makeSafeCall(i, 15_000_000));
} else { } else {
vm.expectCallMinGas( vm.expectCallMinGas(address(caller), 0, 15_000_000, abi.encodeWithSelector(caller.setA.selector, 1));
address(caller),
0,
15_000_000,
abi.encodeWithSelector(caller.setA.selector, 1)
);
assertTrue(caller.makeSafeCall(i, 15_000_000)); assertTrue(caller.makeSafeCall(i, 15_000_000));
} }
...@@ -188,23 +169,11 @@ contract SimpleSafeCaller { ...@@ -188,23 +169,11 @@ contract SimpleSafeCaller {
uint256 public a; uint256 public a;
function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) { function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {
return return SafeCall.call(address(this), gas, 0, abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas));
SafeCall.call(
address(this),
gas,
0,
abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)
);
} }
function makeSafeCallMinGas(uint64 minGas) external returns (bool) { function makeSafeCallMinGas(uint64 minGas) external returns (bool) {
return return SafeCall.callWithMinGas(address(this), minGas, 0, abi.encodeWithSelector(this.setA.selector, 1));
SafeCall.callWithMinGas(
address(this),
minGas,
0,
abi.encodeWithSelector(this.setA.selector, 1)
);
} }
function setA(uint256 _a) external { function setA(uint256 _a) external {
......
...@@ -20,8 +20,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer { ...@@ -20,8 +20,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
super.setUp(); super.setUp();
vm.etch( vm.etch(
Predeploys.SEQUENCER_FEE_WALLET, Predeploys.SEQUENCER_FEE_WALLET,
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)) address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code
.code
); );
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
} }
...@@ -41,7 +40,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer { ...@@ -41,7 +40,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
uint256 balance = address(vault).balance; uint256 balance = address(vault).balance;
vm.prank(alice); vm.prank(alice);
(bool success, ) = address(vault).call{ value: 100 }(hex""); (bool success,) = address(vault).call{ value: 100 }(hex"");
assertEq(success, true); assertEq(success, true);
assertEq(address(vault).balance, balance + 100); assertEq(address(vault).balance, balance + 100);
...@@ -52,9 +51,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer { ...@@ -52,9 +51,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
function test_withdraw_notEnough_reverts() external { function test_withdraw_notEnough_reverts() external {
assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT()); assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());
vm.expectRevert( vm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount");
"FeeVault: withdrawal amount must be greater than minimum withdrawal amount"
);
vault.withdraw(); vault.withdraw();
} }
...@@ -69,23 +66,13 @@ contract SequencerFeeVault_Test is FeeVault_Initializer { ...@@ -69,23 +66,13 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal( emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L1);
address(vault).balance,
vault.RECIPIENT(),
address(this),
FeeVault.WithdrawalNetwork.L1
);
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall( vm.expectCall(
Predeploys.L2_STANDARD_BRIDGE, Predeploys.L2_STANDARD_BRIDGE,
address(vault).balance, address(vault).balance,
abi.encodeWithSelector( abi.encodeWithSelector(StandardBridge.bridgeETHTo.selector, vault.l1FeeWallet(), 35_000, bytes(""))
StandardBridge.bridgeETHTo.selector,
vault.l1FeeWallet(),
35_000,
bytes("")
)
); );
vault.withdraw(); vault.withdraw();
...@@ -103,8 +90,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer { ...@@ -103,8 +90,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
super.setUp(); super.setUp();
vm.etch( vm.etch(
Predeploys.SEQUENCER_FEE_WALLET, Predeploys.SEQUENCER_FEE_WALLET,
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L2)) address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L2)).code
.code
); );
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
} }
...@@ -120,12 +106,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer { ...@@ -120,12 +106,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal( emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L2);
address(vault).balance,
vault.RECIPIENT(),
address(this),
FeeVault.WithdrawalNetwork.L2
);
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall(recipient, address(vault).balance, bytes("")); vm.expectCall(recipient, address(vault).balance, bytes(""));
...@@ -152,9 +133,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer { ...@@ -152,9 +133,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall(recipient, address(vault).balance, bytes("")); vm.expectCall(recipient, address(vault).balance, bytes(""));
vm.expectRevert( vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient");
"FeeVault: failed to send ETH to L2 fee recipient"
);
vault.withdraw(); vault.withdraw();
assertEq(vault.totalProcessed(), 0); assertEq(vault.totalProcessed(), 0);
} }
......
...@@ -3,47 +3,43 @@ pragma solidity 0.8.15; ...@@ -3,47 +3,43 @@ pragma solidity 0.8.15;
import { StandardBridge } from "../src/universal/StandardBridge.sol"; import { StandardBridge } from "../src/universal/StandardBridge.sol";
import { CommonTest } from "./CommonTest.t.sol"; import { CommonTest } from "./CommonTest.t.sol";
import { import { OptimismMintableERC20, ILegacyMintableERC20 } from "../src/universal/OptimismMintableERC20.sol";
OptimismMintableERC20,
ILegacyMintableERC20
} from "../src/universal/OptimismMintableERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// @title StandardBridgeTester /// @title StandardBridgeTester
/// @notice Simple wrapper around the StandardBridge contract that exposes /// @notice Simple wrapper around the StandardBridge contract that exposes
/// internal functions so they can be more easily tested directly. /// internal functions so they can be more easily tested directly.
contract StandardBridgeTester is StandardBridge { contract StandardBridgeTester is StandardBridge {
constructor(address payable _messenger, address payable _otherBridge) constructor(
address payable _messenger,
address payable _otherBridge
)
StandardBridge(StandardBridge(_otherBridge)) StandardBridge(StandardBridge(_otherBridge))
{} { }
function isOptimismMintableERC20(address _token) external view returns (bool) { function isOptimismMintableERC20(address _token) external view returns (bool) {
return _isOptimismMintableERC20(_token); return _isOptimismMintableERC20(_token);
} }
function isCorrectTokenPair(address _mintableToken, address _otherToken) function isCorrectTokenPair(address _mintableToken, address _otherToken) external view returns (bool) {
external
view
returns (bool)
{
return _isCorrectTokenPair(_mintableToken, _otherToken); return _isCorrectTokenPair(_mintableToken, _otherToken);
} }
receive() external payable override {} receive() external payable override { }
} }
/// @title LegacyMintable /// @title LegacyMintable
/// @notice Simple implementation of the legacy OptimismMintableERC20. /// @notice Simple implementation of the legacy OptimismMintableERC20.
contract LegacyMintable is ERC20, ILegacyMintableERC20 { contract LegacyMintable is ERC20, ILegacyMintableERC20 {
constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {} constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) { }
function l1Token() external pure returns (address) { function l1Token() external pure returns (address) {
return address(0); return address(0);
} }
function mint(address _to, uint256 _amount) external pure {} function mint(address _to, uint256 _amount) external pure { }
function burn(address _from, uint256 _amount) external pure {} function burn(address _from, uint256 _amount) external pure { }
/// @notice Implements ERC165. This implementation should not be changed as /// @notice Implements ERC165. This implementation should not be changed as
/// it is how the actual legacy optimism mintable token does the /// it is how the actual legacy optimism mintable token does the
...@@ -51,9 +47,8 @@ contract LegacyMintable is ERC20, ILegacyMintableERC20 { ...@@ -51,9 +47,8 @@ contract LegacyMintable is ERC20, ILegacyMintableERC20 {
/// assuming different compiler version is no problem. /// assuming different compiler version is no problem.
function supportsInterface(bytes4 _interfaceId) external pure returns (bool) { function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165 bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^ bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^ ILegacyMintableERC20.mint.selector
ILegacyMintableERC20.mint.selector ^ ^ ILegacyMintableERC20.burn.selector;
ILegacyMintableERC20.burn.selector;
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface; return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
} }
} }
......
...@@ -44,16 +44,16 @@ contract SystemConfig_Init is CommonTest { ...@@ -44,16 +44,16 @@ contract SystemConfig_Init is CommonTest {
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
( (
alice, // _owner, alice, // _owner,
overhead, // _overhead, overhead, // _overhead,
scalar, // _scalar, scalar, // _scalar,
batcherHash, // _batcherHash batcherHash, // _batcherHash
gasLimit, // _gasLimit, gasLimit, // _gasLimit,
unsafeBlockSigner, // _unsafeBlockSigner, unsafeBlockSigner, // _unsafeBlockSigner,
Constants.DEFAULT_RESOURCE_CONFIG(), // _config, Constants.DEFAULT_RESOURCE_CONFIG(), // _config,
0, // _startBlock 0, // _startBlock
batchInbox, // _batchInbox batchInbox, // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: l1CrossDomainMessenger, l1CrossDomainMessenger: l1CrossDomainMessenger,
l1ERC721Bridge: l1ERC721Bridge, l1ERC721Bridge: l1ERC721Bridge,
l1StandardBridge: l1StandardBridge, l1StandardBridge: l1StandardBridge,
...@@ -116,16 +116,16 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -116,16 +116,16 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
( (
alice, // _owner, alice, // _owner,
overhead, // _overhead, overhead, // _overhead,
scalar, // _scalar, scalar, // _scalar,
batcherHash, // _batcherHash batcherHash, // _batcherHash
gasLimit, // _gasLimit, gasLimit, // _gasLimit,
unsafeBlockSigner, // _unsafeBlockSigner, unsafeBlockSigner, // _unsafeBlockSigner,
Constants.DEFAULT_RESOURCE_CONFIG(), // _config, Constants.DEFAULT_RESOURCE_CONFIG(), // _config,
startBlock, // _startBlock startBlock, // _startBlock
batchInbox, // _batchInbox batchInbox, // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: l1CrossDomainMessenger, l1CrossDomainMessenger: l1CrossDomainMessenger,
l1ERC721Bridge: l1ERC721Bridge, l1ERC721Bridge: l1ERC721Bridge,
l1StandardBridge: l1StandardBridge, l1StandardBridge: l1StandardBridge,
...@@ -156,16 +156,16 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Init { ...@@ -156,16 +156,16 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Init {
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
( (
alice, // _owner, alice, // _owner,
2100, // _overhead, 2100, // _overhead,
1000000, // _scalar, 1000000, // _scalar,
bytes32(hex"abcd"), // _batcherHash, bytes32(hex"abcd"), // _batcherHash,
minimumGasLimit - 1, // _gasLimit, minimumGasLimit - 1, // _gasLimit,
address(1), // _unsafeBlockSigner, address(1), // _unsafeBlockSigner,
Constants.DEFAULT_RESOURCE_CONFIG(), // _config, Constants.DEFAULT_RESOURCE_CONFIG(), // _config,
0, // _startBlock 0, // _startBlock
address(0), // _batchInbox address(0), // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: address(0), l1CrossDomainMessenger: address(0),
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
...@@ -196,16 +196,16 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Init { ...@@ -196,16 +196,16 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Init {
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
( (
alice, // _owner, alice, // _owner,
overhead, // _overhead, overhead, // _overhead,
scalar, // _scalar, scalar, // _scalar,
batcherHash, // _batcherHash batcherHash, // _batcherHash
gasLimit, // _gasLimit, gasLimit, // _gasLimit,
unsafeBlockSigner, // _unsafeBlockSigner, unsafeBlockSigner, // _unsafeBlockSigner,
Constants.DEFAULT_RESOURCE_CONFIG(), // _config, Constants.DEFAULT_RESOURCE_CONFIG(), // _config,
1, // _startBlock 1, // _startBlock
batchInbox, // _batchInbox batchInbox, // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: l1CrossDomainMessenger, l1CrossDomainMessenger: l1CrossDomainMessenger,
l1ERC721Bridge: l1ERC721Bridge, l1ERC721Bridge: l1ERC721Bridge,
l1StandardBridge: l1StandardBridge, l1StandardBridge: l1StandardBridge,
...@@ -318,11 +318,7 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { ...@@ -318,11 +318,7 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
} }
contract SystemConfig_Setters_Test is SystemConfig_Init { contract SystemConfig_Setters_Test is SystemConfig_Init {
event ConfigUpdate( event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data);
uint256 indexed version,
SystemConfig.UpdateType indexed updateType,
bytes data
);
/// @dev Tests that `setBatcherHash` updates the batcher hash successfully. /// @dev Tests that `setBatcherHash` updates the batcher hash successfully.
function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external { function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {
...@@ -337,11 +333,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -337,11 +333,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
/// @dev Tests that `setGasConfig` updates the overhead and scalar successfully. /// @dev Tests that `setGasConfig` updates the overhead and scalar successfully.
function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external { function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ConfigUpdate( emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar));
0,
SystemConfig.UpdateType.GAS_CONFIG,
abi.encode(newOverhead, newScalar)
);
vm.prank(sysConf.owner()); vm.prank(sysConf.owner());
sysConf.setGasConfig(newOverhead, newScalar); sysConf.setGasConfig(newOverhead, newScalar);
...@@ -352,9 +344,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -352,9 +344,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
/// @dev Tests that `setGasLimit` updates the gas limit successfully. /// @dev Tests that `setGasLimit` updates the gas limit successfully.
function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external { function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {
uint64 minimumGasLimit = sysConf.minimumGasLimit(); uint64 minimumGasLimit = sysConf.minimumGasLimit();
newGasLimit = uint64( newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max)));
bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))
);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit)); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));
...@@ -367,11 +357,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -367,11 +357,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
/// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully. /// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully.
function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external { function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ConfigUpdate( emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner));
0,
SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,
abi.encode(newUnsafeSigner)
);
vm.prank(sysConf.owner()); vm.prank(sysConf.owner());
sysConf.setUnsafeBlockSigner(newUnsafeSigner); sysConf.setUnsafeBlockSigner(newUnsafeSigner);
......
...@@ -25,12 +25,7 @@ contract RelayActor is StdUtils { ...@@ -25,12 +25,7 @@ contract RelayActor is StdUtils {
Vm vm; Vm vm;
bool doFail; bool doFail;
constructor( constructor(OptimismPortal _op, L1CrossDomainMessenger _xdm, Vm _vm, bool _doFail) {
OptimismPortal _op,
L1CrossDomainMessenger _xdm,
Vm _vm,
bool _doFail
) {
op = _op; op = _op;
xdm = _xdm; xdm = _xdm;
vm = _vm; vm = _vm;
...@@ -39,11 +34,7 @@ contract RelayActor is StdUtils { ...@@ -39,11 +34,7 @@ contract RelayActor is StdUtils {
/// @notice Relays a message to the `L1CrossDomainMessenger` with a random `version`, /// @notice Relays a message to the `L1CrossDomainMessenger` with a random `version`,
/// and `_message`. /// and `_message`.
function relay( function relay(uint8 _version, uint8 _value, bytes memory _message) external {
uint8 _version,
uint8 _value,
bytes memory _message
) external {
address target = address(0x04); // ID precompile address target = address(0x04); // ID precompile
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -65,20 +56,13 @@ contract RelayActor is StdUtils { ...@@ -65,20 +56,13 @@ contract RelayActor is StdUtils {
// If the message should succeed, supply it `baseGas`. If not, supply it an amount of // If the message should succeed, supply it `baseGas`. If not, supply it an amount of
// gas that is too low to complete the call. // gas that is too low to complete the call.
uint256 gas = doFail uint256 gas = doFail ? bound(minGasLimit, 60_000, 80_000) : xdm.baseGas(_message, minGasLimit);
? bound(minGasLimit, 60_000, 80_000)
: xdm.baseGas(_message, minGasLimit);
// Compute the cross domain message hash and store it in `hashes`. // Compute the cross domain message hash and store it in `hashes`.
// The `relayMessage` function will always encode the message as a version 1 // The `relayMessage` function will always encode the message as a version 1
// message after checking that the V0 hash has not already been relayed. // message after checking that the V0 hash has not already been relayed.
bytes32 _hash = Hashing.hashCrossDomainMessageV1( bytes32 _hash = Hashing.hashCrossDomainMessageV1(
Encoding.encodeVersionedNonce(0, _version), Encoding.encodeVersionedNonce(0, _version), sender, target, _value, minGasLimit, _message
sender,
target,
_value,
minGasLimit,
_message
); );
hashes.push(_hash); hashes.push(_hash);
numHashes += 1; numHashes += 1;
...@@ -92,16 +76,9 @@ contract RelayActor is StdUtils { ...@@ -92,16 +76,9 @@ contract RelayActor is StdUtils {
if (!doFail) { if (!doFail) {
vm.expectCallMinGas(address(0x04), _value, minGasLimit, _message); vm.expectCallMinGas(address(0x04), _value, minGasLimit, _message);
} }
try try xdm.relayMessage{ gas: gas, value: _value }(
xdm.relayMessage{ gas: gas, value: _value }( Encoding.encodeVersionedNonce(0, _version), sender, target, _value, minGasLimit, _message
Encoding.encodeVersionedNonce(0, _version), ) { } catch {
sender,
target,
_value,
minGasLimit,
_message
)
{} catch {
// If any of these calls revert, set `reverted` to true to fail the invariant test. // If any of these calls revert, set `reverted` to true to fail the invariant test.
// NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls
// to this function. // to this function.
......
...@@ -22,7 +22,9 @@ contract Hash_CrossDomainHasher { ...@@ -22,7 +22,9 @@ contract Hash_CrossDomainHasher {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
// generate the versioned nonce // generate the versioned nonce
uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version); uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);
...@@ -46,26 +48,16 @@ contract Hash_CrossDomainHasher { ...@@ -46,26 +48,16 @@ contract Hash_CrossDomainHasher {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
// generate the versioned nonce with the version set to 0 // generate the versioned nonce with the version set to 0
uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0); uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);
// hash the cross domain message using the unversioned and versioned functions for // hash the cross domain message using the unversioned and versioned functions for
// comparison // comparison
bytes32 sampleHash1 = Hashing.hashCrossDomainMessage( bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);
encodedNonce, bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(_target, _sender, _data, encodedNonce);
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(
_target,
_sender,
_data,
encodedNonce
);
// check that the output of both functions matches // check that the output of both functions matches
if (sampleHash1 != sampleHash2) { if (sampleHash1 != sampleHash2) {
...@@ -83,28 +75,16 @@ contract Hash_CrossDomainHasher { ...@@ -83,28 +75,16 @@ contract Hash_CrossDomainHasher {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes memory _data bytes memory _data
) external { )
external
{
// generate the versioned nonce with the version set to 1 // generate the versioned nonce with the version set to 1
uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1); uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);
// hash the cross domain message using the unversioned and versioned functions for // hash the cross domain message using the unversioned and versioned functions for
// comparison // comparison
bytes32 sampleHash1 = Hashing.hashCrossDomainMessage( bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);
encodedNonce, bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(encodedNonce, _sender, _target, _value, _gasLimit, _data);
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(
encodedNonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
// check that the output of both functions matches // check that the output of both functions matches
if (sampleHash1 != sampleHash2) { if (sampleHash1 != sampleHash2) {
......
...@@ -20,7 +20,9 @@ contract L2OutputOracle_Proposer { ...@@ -20,7 +20,9 @@ contract L2OutputOracle_Proposer {
uint256 _l2BlockNumber, uint256 _l2BlockNumber,
bytes32 _l1BlockHash, bytes32 _l1BlockHash,
uint256 _l1BlockNumber uint256 _l1BlockNumber
) external { )
external
{
// Act as the proposer and propose a new output. // Act as the proposer and propose a new output.
vm.prank(oracle.PROPOSER()); vm.prank(oracle.PROPOSER());
oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber); oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);
......
...@@ -33,12 +33,7 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering { ...@@ -33,12 +33,7 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
return _resourceConfig(); return _resourceConfig();
} }
function _resourceConfig() function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) {
internal
pure
override
returns (ResourceMetering.ResourceConfig memory)
{
ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();
return rcfg; return rcfg;
} }
...@@ -50,7 +45,10 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering { ...@@ -50,7 +45,10 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
uint64 _gasLimit, uint64 _gasLimit,
bool _isCreation, bool _isCreation,
bytes memory _data bytes memory _data
) public payable { )
public
payable
{
vm.assume((!_isCreation || _to == address(0)) && _data.length <= 120_000); vm.assume((!_isCreation || _to == address(0)) && _data.length <= 120_000);
uint256 preDepositvalue = bound(_value, 0, type(uint128).max); uint256 preDepositvalue = bound(_value, 0, type(uint128).max);
...@@ -60,15 +58,11 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering { ...@@ -60,15 +58,11 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
uint256 preDepositBalance = address(this).balance; uint256 preDepositBalance = address(this).balance;
uint256 value = bound(preDepositvalue, 0, preDepositBalance); uint256 value = bound(preDepositvalue, 0, preDepositBalance);
(, uint64 cachedPrevBoughtGas, ) = ResourceMetering(address(portal)).params(); (, uint64 cachedPrevBoughtGas,) = ResourceMetering(address(portal)).params();
ResourceMetering.ResourceConfig memory rcfg = resourceConfig(); ResourceMetering.ResourceConfig memory rcfg = resourceConfig();
uint256 maxResourceLimit = uint64(rcfg.maxResourceLimit); uint256 maxResourceLimit = uint64(rcfg.maxResourceLimit);
uint64 gasLimit = uint64( uint64 gasLimit = uint64(
bound( bound(_gasLimit, portal.minimumGasLimit(uint64(_data.length)), maxResourceLimit - cachedPrevBoughtGas)
_gasLimit,
portal.minimumGasLimit(uint64(_data.length)),
maxResourceLimit - cachedPrevBoughtGas
)
); );
try portal.depositTransaction{ value: value }(_to, value, gasLimit, _isCreation, _data) { try portal.depositTransaction{ value: value }(_to, value, gasLimit, _isCreation, _data) {
...@@ -104,8 +98,8 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer { ...@@ -104,8 +98,8 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer {
data: hex"" data: hex""
}); });
// Get withdrawal proof data we can use for testing. // Get withdrawal proof data we can use for testing.
(_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) =
.getProveWithdrawalTransactionInputs(_defaultTx); ffi.getProveWithdrawalTransactionInputs(_defaultTx);
// Setup a dummy output root proof for reuse. // Setup a dummy output root proof for reuse.
_outputRootProof = Types.OutputRootProof({ _outputRootProof = Types.OutputRootProof({
...@@ -123,11 +117,7 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer { ...@@ -123,11 +117,7 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer {
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp( vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
oracle.getL2Output(_proposedOutputIndex).timestamp +
oracle.FINALIZATION_PERIOD_SECONDS() +
1
);
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF); vm.deal(address(op), 0xFFFFFFFF);
} }
...@@ -164,12 +154,7 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { ...@@ -164,12 +154,7 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {
super.setUp(); super.setUp();
// Prove the withdrawal transaction // Prove the withdrawal transaction
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Set the target contract to the portal proxy // Set the target contract to the portal proxy
targetContract(address(op)); targetContract(address(op));
...@@ -193,12 +178,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness ...@@ -193,12 +178,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness
super.setUp(); super.setUp();
// Prove the withdrawal transaction // Prove the withdrawal transaction
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Warp past the finalization period. // Warp past the finalization period.
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
...@@ -228,12 +208,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant ...@@ -228,12 +208,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant
super.setUp(); super.setUp();
// Prove the withdrawal transaction // Prove the withdrawal transaction
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Warp past the finalization period. // Warp past the finalization period.
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
......
...@@ -35,12 +35,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering { ...@@ -35,12 +35,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
return _resourceConfig(); return _resourceConfig();
} }
function _resourceConfig() function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) {
internal
pure
override
returns (ResourceMetering.ResourceConfig memory)
{
ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();
return rcfg; return rcfg;
} }
...@@ -54,8 +49,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering { ...@@ -54,8 +49,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
uint256 cachedPrevBlockNum = uint256(params.prevBlockNum); uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);
ResourceMetering.ResourceConfig memory rcfg = resourceConfig(); ResourceMetering.ResourceConfig memory rcfg = resourceConfig();
uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) / uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);
uint256(rcfg.elasticityMultiplier);
// check that the last block's base fee hasn't dropped below the minimum // check that the last block's base fee hasn't dropped below the minimum
if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) { if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {
...@@ -72,11 +66,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering { ...@@ -72,11 +66,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
// raise or lower the baseFee after this block, respectively // raise or lower the baseFee after this block, respectively
uint256 gasToBurn; uint256 gasToBurn;
if (_raiseBaseFee) { if (_raiseBaseFee) {
gasToBurn = bound( gasToBurn = bound(_gasToBurn, uint256(targetResourceLimit), uint256(rcfg.maxResourceLimit));
_gasToBurn,
uint256(targetResourceLimit),
uint256(rcfg.maxResourceLimit)
);
} else { } else {
gasToBurn = bound(_gasToBurn, 0, targetResourceLimit); gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);
} }
...@@ -92,39 +82,35 @@ contract ResourceMetering_User is StdUtils, ResourceMetering { ...@@ -92,39 +82,35 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
// empty blocks in between), ensure this block's baseFee increased, but not by // empty blocks in between), ensure this block's baseFee increased, but not by
// more than the max amount per block // more than the max amount per block
if ( if (
(cachedPrevBoughtGas > uint256(targetResourceLimit)) && (cachedPrevBoughtGas > uint256(targetResourceLimit))
(uint256(params.prevBlockNum) - cachedPrevBlockNum == 1) && (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)
) { ) {
failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee); failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);
failedMaxRaiseBaseFeePerBlock = failedMaxRaiseBaseFeePerBlock =
failedMaxRaiseBaseFeePerBlock || failedMaxRaiseBaseFeePerBlock || ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);
((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);
} }
// If the last block used less than the target amount of gas, (or was empty), // If the last block used less than the target amount of gas, (or was empty),
// ensure that: this block's baseFee was decreased, but not by more than the max amount // ensure that: this block's baseFee was decreased, but not by more than the max amount
if ( if (
(cachedPrevBoughtGas < uint256(targetResourceLimit)) || (cachedPrevBoughtGas < uint256(targetResourceLimit))
(uint256(params.prevBlockNum) - cachedPrevBlockNum > 1) || (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)
) { ) {
// Invariant: baseFee should decrease // Invariant: baseFee should decrease
failedLowerBaseFee = failedLowerBaseFee = failedLowerBaseFee || (uint256(params.prevBaseFee) > cachedPrevBaseFee);
failedLowerBaseFee ||
(uint256(params.prevBaseFee) > cachedPrevBaseFee);
if (params.prevBlockNum - cachedPrevBlockNum == 1) { if (params.prevBlockNum - cachedPrevBlockNum == 1) {
// No empty blocks // No empty blocks
// Invariant: baseFee should not have decreased by more than the maximum amount // Invariant: baseFee should not have decreased by more than the maximum amount
failedMaxLowerBaseFeePerBlock = failedMaxLowerBaseFeePerBlock = failedMaxLowerBaseFeePerBlock
failedMaxLowerBaseFeePerBlock || || ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);
((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);
} else if (params.prevBlockNum - cachedPrevBlockNum > 1) { } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {
// We have at least one empty block // We have at least one empty block
// Update the maxBaseFeeChange to account for multiple blocks having passed // Update the maxBaseFeeChange to account for multiple blocks having passed
unchecked { unchecked {
maxBaseFeeChange = uint256( maxBaseFeeChange = uint256(
int256(cachedPrevBaseFee) - int256(cachedPrevBaseFee)
Arithmetic.clamp( - Arithmetic.clamp(
Arithmetic.cdexp( Arithmetic.cdexp(
int256(cachedPrevBaseFee), int256(cachedPrevBaseFee),
int256(uint256(rcfg.baseFeeMaxChangeDenominator)), int256(uint256(rcfg.baseFeeMaxChangeDenominator)),
...@@ -142,14 +128,13 @@ contract ResourceMetering_User is StdUtils, ResourceMetering { ...@@ -142,14 +128,13 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee; underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;
// Invariant: baseFee should not have decreased by more than the maximum amount // Invariant: baseFee should not have decreased by more than the maximum amount
failedMaxLowerBaseFeePerBlock = failedMaxLowerBaseFeePerBlock = failedMaxLowerBaseFeePerBlock
failedMaxLowerBaseFeePerBlock || || ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);
((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);
} }
} }
} }
function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {} function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) { }
} }
contract ResourceMetering_Invariant is StdInvariant, Test { contract ResourceMetering_Invariant is StdInvariant, Test {
......
...@@ -80,12 +80,7 @@ contract SafeCaller_Actor is StdUtils { ...@@ -80,12 +80,7 @@ contract SafeCaller_Actor is StdUtils {
FAILS = _fails; FAILS = _fails;
} }
function performSafeCallMinGas( function performSafeCallMinGas(uint64 gas, uint64 minGas, address to, uint8 value) external {
uint64 gas,
uint64 minGas,
address to,
uint8 value
) external {
// Only send to EOAs - we exclude the console as it has no code but reverts when called // Only send to EOAs - we exclude the console as it has no code but reverts when called
// with a selector that doesn't exist due to the foundry hook. // with a selector that doesn't exist due to the foundry hook.
vm.assume(to.code.length == 0 && to != 0x000000000000000000636F6e736F6c652e6c6f67); vm.assume(to.code.length == 0 && to != 0x000000000000000000636F6e736F6c652e6c6f67);
...@@ -108,11 +103,7 @@ contract SafeCaller_Actor is StdUtils { ...@@ -108,11 +103,7 @@ contract SafeCaller_Actor is StdUtils {
msg.sender, msg.sender,
gas, gas,
value, value,
abi.encodeWithSelector( abi.encodeWithSelector(SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector, to, minGas)
SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector,
to,
minGas
)
); );
if (success && FAILS) numCalls++; if (success && FAILS) numCalls++;
......
...@@ -20,16 +20,16 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test { ...@@ -20,16 +20,16 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test {
abi.encodeCall( abi.encodeCall(
configImpl.initialize, configImpl.initialize,
( (
address(0xbeef), // owner address(0xbeef), // owner
2100, // overhead 2100, // overhead
1000000, // scalar 1000000, // scalar
bytes32(hex"abcd"), // batcher hash bytes32(hex"abcd"), // batcher hash
30_000_000, // gas limit 30_000_000, // gas limit
address(1), // unsafe block signer address(1), // unsafe block signer
Constants.DEFAULT_RESOURCE_CONFIG(), // resource config Constants.DEFAULT_RESOURCE_CONFIG(), // resource config
0, //_startBlock 0, //_startBlock
address(0), // _batchInbox address(0), // _batchInbox
SystemConfig.Addresses({ // _addrs SystemConfig.Addresses({ // _addrs
l1CrossDomainMessenger: address(0), l1CrossDomainMessenger: address(0),
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
...@@ -52,10 +52,7 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test { ...@@ -52,10 +52,7 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test {
// that can modify the gas limit within the SystemConfig. // that can modify the gas limit within the SystemConfig.
bytes4[] memory selectors = new bytes4[](1); bytes4[] memory selectors = new bytes4[](1);
selectors[0] = config.setGasLimit.selector; selectors[0] = config.setGasLimit.selector;
FuzzSelector memory selector = FuzzSelector({ FuzzSelector memory selector = FuzzSelector({ addr: address(config), selectors: selectors });
addr: address(config),
selectors: selectors
});
targetSelector(selector); targetSelector(selector);
} }
......
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