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 {
}
/// @notice Deploy the AddressManager
function deployAddressManager() broadcast() public returns (address) {
function deployAddressManager() public broadcast returns (address) {
AddressManager manager = new AddressManager();
require(manager.owner() == msg.sender);
......@@ -131,7 +131,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the ProxyAdmin
function deployProxyAdmin() broadcast() public returns (address) {
function deployProxyAdmin() public broadcast returns (address) {
ProxyAdmin admin = new ProxyAdmin({
_owner: msg.sender
});
......@@ -150,7 +150,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L1StandardBridgeProxy
function deployL1StandardBridgeProxy() broadcast() public returns (address) {
function deployL1StandardBridgeProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
L1ChugSplashProxy proxy = new L1ChugSplashProxy(proxyAdmin);
......@@ -163,7 +163,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L2OutputOracleProxy
function deployL2OutputOracleProxy() broadcast() public returns (address) {
function deployL2OutputOracleProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
......@@ -178,7 +178,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L1CrossDomainMessengerProxy
function deployL1CrossDomainMessengerProxy() broadcast() public returns (address) {
function deployL1CrossDomainMessengerProxy() public broadcast returns (address) {
AddressManager addressManager = AddressManager(mustGetAddress("AddressManager"));
string memory contractName = "OVM_L1CrossDomainMessenger";
ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, contractName);
......@@ -197,7 +197,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the OptimismPortalProxy
function deployOptimismPortalProxy() broadcast() public returns (address) {
function deployOptimismPortalProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
......@@ -213,7 +213,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the OptimismMintableERC20FactoryProxy
function deployOptimismMintableERC20FactoryProxy() broadcast() public returns (address) {
function deployOptimismMintableERC20FactoryProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
......@@ -229,7 +229,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L1ERC721BridgeProxy
function deployL1ERC721BridgeProxy() broadcast() public returns (address) {
function deployL1ERC721BridgeProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
......@@ -245,7 +245,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the SystemConfigProxy
function deploySystemConfigProxy() broadcast() public returns (address) {
function deploySystemConfigProxy() public broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
......@@ -261,7 +261,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the DisputeGameFactoryProxy
function deployDisputeGameFactoryProxy() onlyDevnet broadcast() public returns (address) {
function deployDisputeGameFactoryProxy() public onlyDevnet broadcast returns (address) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
......@@ -277,7 +277,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L1CrossDomainMessenger
function deployL1CrossDomainMessenger() broadcast() public returns (address) {
function deployL1CrossDomainMessenger() public broadcast returns (address) {
L1CrossDomainMessenger messenger = new L1CrossDomainMessenger();
require(address(messenger.PORTAL()) == address(0));
......@@ -293,7 +293,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the OptimismPortal
function deployOptimismPortal() broadcast() public returns (address) {
function deployOptimismPortal() public broadcast returns (address) {
OptimismPortal portal = new OptimismPortal();
require(address(portal.L2_ORACLE()) == address(0));
......@@ -308,7 +308,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L2OutputOracle
function deployL2OutputOracle() broadcast() public returns (address) {
function deployL2OutputOracle() public broadcast returns (address) {
L2OutputOracle oracle = new L2OutputOracle({
_submissionInterval: cfg.l2OutputOracleSubmissionInterval(),
_l2BlockTime: cfg.l2BlockTime(),
......@@ -335,7 +335,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the OptimismMintableERC20Factory
function deployOptimismMintableERC20Factory() broadcast() public returns (address) {
function deployOptimismMintableERC20Factory() public broadcast returns (address) {
address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(l1StandardBridgeProxy);
......@@ -348,7 +348,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the DisputeGameFactory
function deployDisputeGameFactory() onlyDevnet broadcast() public returns (address) {
function deployDisputeGameFactory() public onlyDevnet broadcast returns (address) {
DisputeGameFactory factory = new DisputeGameFactory();
save("DisputeGameFactory", address(factory));
console.log("DisputeGameFactory deployed at %s", address(factory));
......@@ -357,7 +357,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the BlockOracle
function deployBlockOracle() onlyDevnet broadcast() public returns (address) {
function deployBlockOracle() public onlyDevnet broadcast returns (address) {
BlockOracle oracle = new BlockOracle();
save("BlockOracle", address(oracle));
console.log("BlockOracle deployed at %s", address(oracle));
......@@ -366,7 +366,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the PreimageOracle
function deployPreimageOracle() onlyDevnet broadcast() public returns (address) {
function deployPreimageOracle() public onlyDevnet broadcast returns (address) {
PreimageOracle preimageOracle = new PreimageOracle();
save("PreimageOracle", address(preimageOracle));
console.log("PreimageOracle deployed at %s", address(preimageOracle));
......@@ -375,7 +375,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy Mips
function deployMips() onlyDevnet broadcast() public returns (address) {
function deployMips() public onlyDevnet broadcast returns (address) {
MIPS mips = new MIPS(IPreimageOracle(mustGetAddress("PreimageOracle")));
save("Mips", address(mips));
console.log("MIPS deployed at %s", address(mips));
......@@ -384,8 +384,9 @@ contract Deploy is Deployer {
}
/// @notice Deploy the SystemConfig
function deploySystemConfig() broadcast() public returns (address) {
function deploySystemConfig() public broadcast returns (address) {
SystemConfig config = new SystemConfig();
bytes32 batcherHash = bytes32(uint256(uint160(cfg.batchSenderAddress())));
require(config.owner() == address(0xdEaD));
require(config.overhead() == 0);
......@@ -417,7 +418,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L1StandardBridge
function deployL1StandardBridge() broadcast() public returns (address) {
function deployL1StandardBridge() public broadcast returns (address) {
L1StandardBridge bridge = new L1StandardBridge();
require(address(bridge.MESSENGER()) == address(0));
......@@ -432,7 +433,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the L1ERC721Bridge
function deployL1ERC721Bridge() broadcast() public returns (address) {
function deployL1ERC721Bridge() public broadcast returns (address) {
L1ERC721Bridge bridge = new L1ERC721Bridge();
require(address(bridge.MESSENGER()) == address(0));
......@@ -445,7 +446,7 @@ contract Deploy is Deployer {
}
/// @notice Transfer ownership of the address manager to the ProxyAdmin
function transferAddressManagerOwnership() broadcast() public {
function transferAddressManagerOwnership() public broadcast {
AddressManager addressManager = AddressManager(mustGetAddress("AddressManager"));
address owner = addressManager.owner();
address proxyAdmin = mustGetAddress("ProxyAdmin");
......@@ -458,7 +459,7 @@ contract Deploy is Deployer {
}
/// @notice Initialize the DisputeGameFactory
function initializeDisputeGameFactory() onlyDevnet broadcast() public {
function initializeDisputeGameFactory() public onlyDevnet broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy");
address disputeGameFactory = mustGetAddress("DisputeGameFactory");
......@@ -466,10 +467,7 @@ contract Deploy is Deployer {
proxyAdmin.upgradeAndCall({
_proxy: payable(disputeGameFactoryProxy),
_implementation: disputeGameFactory,
_data: abi.encodeCall(
DisputeGameFactory.initialize,
(msg.sender)
)
_data: abi.encodeCall(DisputeGameFactory.initialize, (msg.sender))
});
string memory version = DisputeGameFactory(disputeGameFactoryProxy).version();
......@@ -477,7 +475,7 @@ contract Deploy is Deployer {
}
/// @notice Initialize the SystemConfig
function initializeSystemConfig() broadcast() public {
function initializeSystemConfig() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address systemConfigProxy = mustGetAddress("SystemConfigProxy");
address systemConfig = mustGetAddress("SystemConfig");
......@@ -539,7 +537,7 @@ contract Deploy is Deployer {
}
/// @notice Initialize the L1StandardBridge
function initializeL1StandardBridge() broadcast() public {
function initializeL1StandardBridge() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
address l1StandardBridge = mustGetAddress("L1StandardBridge");
......@@ -554,10 +552,7 @@ contract Deploy is Deployer {
proxyAdmin.upgradeAndCall({
_proxy: payable(l1StandardBridgeProxy),
_implementation: l1StandardBridge,
_data: abi.encodeCall(
L1StandardBridge.initialize,
(L1CrossDomainMessenger(l1CrossDomainMessengerProxy))
)
_data: abi.encodeCall(L1StandardBridge.initialize, (L1CrossDomainMessenger(l1CrossDomainMessengerProxy)))
});
string memory version = L1StandardBridge(payable(l1StandardBridgeProxy)).version();
......@@ -573,11 +568,10 @@ contract Deploy is Deployer {
// during predeployment simulation on OP Mainnet if there is a bug.
bytes32 slot0 = vm.load(address(bridge), bytes32(uint256(0)));
require(slot0 == bytes32(uint256(2)));
}
/// @notice Initialize the L1ERC721Bridge
function initializeL1ERC721Bridge() broadcast() public {
function initializeL1ERC721Bridge() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1ERC721BridgeProxy = mustGetAddress("L1ERC721BridgeProxy");
address l1ERC721Bridge = mustGetAddress("L1ERC721Bridge");
......@@ -586,10 +580,7 @@ contract Deploy is Deployer {
proxyAdmin.upgradeAndCall({
_proxy: payable(l1ERC721BridgeProxy),
_implementation: l1ERC721Bridge,
_data: abi.encodeCall(
L1ERC721Bridge.initialize,
(L1CrossDomainMessenger(l1CrossDomainMessengerProxy))
)
_data: abi.encodeCall(L1ERC721Bridge.initialize, (L1CrossDomainMessenger(l1CrossDomainMessengerProxy)))
});
L1ERC721Bridge bridge = L1ERC721Bridge(l1ERC721BridgeProxy);
......@@ -601,7 +592,7 @@ contract Deploy is Deployer {
}
/// @notice Ininitialize the OptimismMintableERC20Factory
function initializeOptimismMintableERC20Factory() broadcast() public {
function initializeOptimismMintableERC20Factory() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address optimismMintableERC20FactoryProxy = mustGetAddress("OptimismMintableERC20FactoryProxy");
address optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20Factory");
......@@ -620,7 +611,7 @@ contract Deploy is Deployer {
}
/// @notice initializeL1CrossDomainMessenger
function initializeL1CrossDomainMessenger() broadcast() public {
function initializeL1CrossDomainMessenger() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger");
......@@ -638,18 +629,14 @@ contract Deploy is Deployer {
proxyAdmin.setImplementationName(l1CrossDomainMessengerProxy, contractName);
}
require(
keccak256(bytes(proxyAdmin.implementationName(l1CrossDomainMessengerProxy))) == keccak256(bytes(contractName))
keccak256(bytes(proxyAdmin.implementationName(l1CrossDomainMessengerProxy)))
== keccak256(bytes(contractName))
);
proxyAdmin.upgradeAndCall({
_proxy: payable(l1CrossDomainMessengerProxy),
_implementation: l1CrossDomainMessenger,
_data: abi.encodeCall(
L1CrossDomainMessenger.initialize,
(
OptimismPortal(payable(optimismPortalProxy))
)
)
_data: abi.encodeCall(L1CrossDomainMessenger.initialize, (OptimismPortal(payable(optimismPortalProxy))))
});
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxy);
......@@ -663,7 +650,7 @@ contract Deploy is Deployer {
}
/// @notice Initialize the L2OutputOracle
function initializeL2OutputOracle() broadcast() public {
function initializeL2OutputOracle() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy");
address l2OutputOracle = mustGetAddress("L2OutputOracle");
......@@ -701,7 +688,7 @@ contract Deploy is Deployer {
}
/// @notice Initialize the OptimismPortal
function initializeOptimismPortal() broadcast() public {
function initializeOptimismPortal() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address optimismPortalProxy = mustGetAddress("OptimismPortalProxy");
address optimismPortal = mustGetAddress("OptimismPortal");
......@@ -718,12 +705,7 @@ contract Deploy is Deployer {
_implementation: optimismPortal,
_data: abi.encodeCall(
OptimismPortal.initialize,
(
L2OutputOracle(l2OutputOracleProxy),
guardian,
SystemConfig(systemConfigProxy),
false
)
(L2OutputOracle(l2OutputOracleProxy), guardian, SystemConfig(systemConfigProxy), false)
)
});
......@@ -738,7 +720,7 @@ contract Deploy is Deployer {
}
/// @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"));
address owner = proxyAdmin.owner();
address finalSystemOwner = cfg.finalSystemOwner();
......@@ -749,7 +731,7 @@ contract Deploy is Deployer {
}
/// @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"));
address owner = disputeGameFactory.owner();
address finalSystemOwner = cfg.finalSystemOwner();
......@@ -760,7 +742,7 @@ contract Deploy is Deployer {
}
/// @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
string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json");
bytes32 mipsAbsolutePrestate;
......@@ -777,11 +759,15 @@ contract Deploy is Deployer {
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
for (uint8 i; i < 2; i++) {
Claim absolutePrestate = Claim.wrap(i == 0 ? bytes32(cfg.faultGameAbsolutePrestate()) : mipsAbsolutePrestate);
IBigStepper faultVm = IBigStepper(i == 0 ? address(new AlphabetVM(absolutePrestate)) : mustGetAddress("Mips"));
Claim absolutePrestate =
Claim.wrap(i == 0 ? bytes32(cfg.faultGameAbsolutePrestate()) : mipsAbsolutePrestate);
IBigStepper faultVm =
IBigStepper(i == 0 ? address(new AlphabetVM(absolutePrestate)) : mustGetAddress("Mips"));
GameType gameType = GameType.wrap(i);
if (address(factory.gameImpls(gameType)) == address(0)) {
factory.setImplementation(gameType, new FaultDisputeGame({
factory.setImplementation(
gameType,
new FaultDisputeGame({
_gameType: gameType,
_absolutePrestate: absolutePrestate,
_maxGameDepth: i == 0 ? 4 : cfg.faultGameMaxDepth(), // The max depth of the alphabet game is always 4
......@@ -789,8 +775,13 @@ contract Deploy is Deployer {
_vm: faultVm,
_l2oo: L2OutputOracle(mustGetAddress("L2OutputOracleProxy")),
_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 {
} catch {
try vm.parseJsonUint(_json, "$.l1StartingBlockTag") returns (uint256 tag) {
return _getBlockByTag(vm.toString(tag));
} catch {}
} catch { }
}
}
revert("l1StartingBlockTag must be a bytes32, string or uint256 or cannot fetch l1StartingBlockTag");
......
......@@ -39,7 +39,7 @@ contract DeployL2 is Deployer {
}
/// @notice Deploy the EAS implementation.
function deployEAS() broadcast() public returns (address) {
function deployEAS() public broadcast returns (address) {
EAS eas = new EAS();
ISchemaRegistry registry = eas.getSchemaRegistry();
......@@ -55,7 +55,7 @@ contract DeployL2 is Deployer {
}
/// @notice Deploy the SchemaManager implementation.
function deploySchemaRegistry() broadcast() public returns (address) {
function deploySchemaRegistry() public broadcast returns (address) {
SchemaRegistry registry = new SchemaRegistry();
save("SchemaRegistry", address(registry));
......@@ -67,4 +67,3 @@ contract DeployL2 is Deployer {
return address(registry);
}
}
......@@ -53,17 +53,17 @@ abstract contract Deployer is Script {
/// @notice The path to the temp deployments file
string internal tempDeploymentsPath;
/// @notice Error for when attempting to fetch a deployment and it does not exist
error DeploymentDoesNotExist(string);
/// @notice Error for when trying to save an invalid deployment
error InvalidDeployment(string);
/// @notice The storage slot that holds the address of the implementation.
/// 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.
/// bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
bytes32 internal constant OWNER_KEY =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
bytes32 internal constant OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/// @notice Create the global variables and set up the filesystem
function setUp() public virtual {
......@@ -76,7 +76,7 @@ abstract contract Deployer is Script {
deployPath = string.concat(root, "/broadcast/", deployScript, ".s.sol/", vm.toString(chainId), "/", deployFile);
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");
try vm.readFile(chainIdPath) returns (string memory localChainId) {
......@@ -89,7 +89,8 @@ abstract contract Deployer is Script {
console.log("Connected to network with chainid %s", chainId);
tempDeploymentsPath = string.concat(deploymentsDir, "/.deploy");
try vm.readFile(tempDeploymentsPath) returns (string memory) {} catch {
try vm.readFile(tempDeploymentsPath) returns (string memory) { }
catch {
vm.writeJson("{}", tempDeploymentsPath);
}
console.log("Storing temp deployment data in %s", tempDeploymentsPath);
......@@ -121,7 +122,7 @@ abstract contract Deployer is Script {
try vm.readFile(artifactPath) returns (string memory res) {
numDeployments = stdJson.readUint(string(res), "$.numDeployments");
vm.removeFile(artifactPath);
} catch {}
} catch { }
numDeployments++;
Artifact memory artifact = Artifact({
......@@ -142,10 +143,7 @@ abstract contract Deployer is Script {
string memory json = _serializeArtifact(artifact);
vm.writeJson({
json: json,
path: artifactPath
});
vm.writeJson({ json: json, path: artifactPath });
}
console.log("Synced temp deploy files, deleting %s", tempDeploymentsPath);
......@@ -154,7 +152,7 @@ abstract contract Deployer is Script {
/// @notice Returns the name of the deployment script. Children contracts
/// 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.
function newDeployments() external view returns (Deployment[] memory) {
......@@ -222,10 +220,7 @@ abstract contract Deployer is Script {
revert InvalidDeployment("AlreadyExists");
}
Deployment memory deployment = Deployment({
name: _name,
addr: payable(_deployed)
});
Deployment memory deployment = Deployment({ name: _name, addr: payable(_deployed) });
_namedDeployments[_name] = deployment;
_newDeployments.push(deployment);
_writeTemp(_name, _deployed);
......@@ -247,10 +242,7 @@ abstract contract Deployer is Script {
for (uint256 i; i < names.length; i++) {
string memory contractName = names[i];
address addr = stdJson.readAddress(json, string.concat("$.", contractName));
deployments[i] = Deployment({
name: contractName,
addr: payable(addr)
});
deployments[i] = Deployment({ name: contractName, addr: payable(addr) });
}
return deployments;
}
......@@ -260,7 +252,17 @@ abstract contract Deployer is Script {
string[] memory cmd = new string[](3);
cmd[0] = Executables.bash;
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);
return string(res);
}
......@@ -284,13 +286,16 @@ abstract contract Deployer is Script {
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.
function _stripSemver(string memory _name) internal returns (string memory) {
string[] memory cmd = new string[](3);
cmd[0] = Executables.bash;
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);
return string(res);
}
......@@ -326,7 +331,8 @@ abstract contract Deployer is Script {
cmd[2] = string.concat(Executables.forge, " config --json | ", Executables.jq, " -r .out");
bytes memory res = vm.ffi(cmd);
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;
}
......@@ -342,7 +348,15 @@ abstract contract Deployer is Script {
string[] memory cmd = new string[](3);
cmd[0] = Executables.bash;
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);
string memory receipt = string(res);
return receipt;
......@@ -400,10 +414,7 @@ abstract contract Deployer is Script {
/// @notice Adds a deployment to the temp deployments file
function _writeTemp(string memory _name, address _deployed) internal {
vm.writeJson({
json: stdJson.serialize("", _name, _deployed),
path: tempDeploymentsPath
});
vm.writeJson({ json: stdJson.serialize("", _name, _deployed), path: tempDeploymentsPath });
}
/// @notice Turns an Artifact into a json serialized string
......@@ -471,15 +482,9 @@ abstract contract Deployer is Script {
string memory path = string.concat(deploymentsDir, "/", _name, ".json");
try vm.readFile(path) returns (string memory json) {
bytes memory addr = stdJson.parseRaw(json, "$.address");
return Deployment({
addr: abi.decode(addr, (address)),
name: _name
});
return Deployment({ addr: abi.decode(addr, (address)), name: _name });
} catch {
return Deployment({
addr: payable(address(0)),
name: ""
});
return Deployment({ addr: payable(address(0)), name: "" });
}
}
}
......@@ -54,13 +54,7 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init {
uint256 numClaims = uint256(vm.load(address(gameProxy), bytes32(uint256(1))));
IFaultDisputeGame.ClaimData[] memory gameData = new IFaultDisputeGame.ClaimData[](numClaims);
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({
parentIndex: parentIndex,
......
......@@ -31,20 +31,20 @@ contract FeeVaultWithdrawal is Script {
address vault = vaults[i];
bool shouldCall = canWithdrawal(vault);
if (shouldCall) {
calls.push(IMulticall3.Call3({
calls.push(
IMulticall3.Call3({
target: vault,
allowFailure: false,
callData: abi.encodeWithSelector(FeeVault.withdraw.selector)
}));
})
);
address recipient = FeeVault(payable(vault)).RECIPIENT();
uint256 balance = vault.balance;
log(balance, recipient, vault);
} else {
string memory logline = string.concat(
vm.toString(vault),
" does not have a large enough balance to withdraw."
);
string memory logline =
string.concat(vm.toString(vault), " does not have a large enough balance to withdraw.");
console.log(logline);
}
}
......@@ -67,12 +67,7 @@ contract FeeVaultWithdrawal is Script {
/// @notice Logs the information relevant to the user.
function log(uint256 _balance, address _recipient, address _vault) internal view {
string memory logline = string.concat(
"Withdrawing ",
vm.toString(_balance),
" to ",
vm.toString(_recipient),
" from ",
vm.toString(_vault)
"Withdrawing ", vm.toString(_balance), " to ", vm.toString(_recipient), " from ", vm.toString(_vault)
);
console.log(logline);
}
......
......@@ -31,11 +31,7 @@ contract SemverLock is Script {
commands = new string[](3);
commands[0] = "bash";
commands[1] = "-c";
commands[2] = string.concat(
"echo \"",
_files[i],
"\"| sed -E \'s|src/.*/(.+)\\.sol|\\1|\'"
);
commands[2] = string.concat("echo \"", _files[i], "\"| sed -E \'s|src/.*/(.+)\\.sol|\\1|\'");
string memory contractName = string(vm.ffi(commands));
commands[0] = "bash";
......@@ -44,14 +40,8 @@ contract SemverLock is Script {
string memory artifactsDir = string(vm.ffi(commands));
// Parse the artifact to get the contract's initcode hash.
bytes memory initCode = vm.getCode(string.concat(
artifactsDir,
"/",
contractName,
".sol/",
contractName,
".json"
));
bytes memory initCode =
vm.getCode(string.concat(artifactsDir, "/", contractName, ".sol/", contractName, ".json"));
// Serialize the source hash in JSON.
string memory j = vm.serializeBytes32(out, _files[i], keccak256(abi.encodePacked(fileContents, initCode)));
......
......@@ -35,7 +35,12 @@ interface IGnosisSafe {
function approveHash(bytes32 hashToApprove) external;
function approvedHashes(address, bytes32) external view returns (uint256);
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
view;
function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures) external view;
......@@ -53,7 +58,10 @@ interface IGnosisSafe {
address gasToken,
address refundReceiver,
uint256 _nonce
) external view returns (bytes memory);
)
external
view
returns (bytes memory);
function execTransaction(
address to,
uint256 value,
......@@ -65,15 +73,31 @@ interface IGnosisSafe {
address gasToken,
address refundReceiver,
bytes memory signatures
) external payable returns (bool success);
function execTransactionFromModule(address to, uint256 value, bytes memory data, Enum.Operation operation)
)
external
payable
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
returns (bool success, bytes memory returnData);
function getChainId() external view returns (uint256);
function getModulesPaginated(address start, uint256 pageSize)
function getModulesPaginated(
address start,
uint256 pageSize
)
external
view
returns (address[] memory array, address next);
......@@ -91,12 +115,22 @@ interface IGnosisSafe {
address gasToken,
address refundReceiver,
uint256 _nonce
) external view returns (bytes32);
)
external
view
returns (bytes32);
function isModuleEnabled(address module) external view returns (bool);
function isOwner(address owner) external view returns (bool);
function nonce() external view returns (uint256);
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 setGuard(address guard) external;
function setup(
......@@ -108,7 +142,8 @@ interface IGnosisSafe {
address paymentToken,
uint256 payment,
address paymentReceiver
) external;
)
external;
function signedMessages(bytes32) external view returns (uint256);
function simulateAndRevert(address targetContract, bytes memory calldataPayload) external;
function swapOwner(address prevOwner, address oldOwner, address newOwner) external;
......
......@@ -22,14 +22,14 @@ library LibSort {
let h := add(a, shl(5, n)) // High slot.
let s := 0x20
let w := not(31)
for { let i := add(a, s) } 1 {} {
for { let i := add(a, s) } 1 { } {
i := add(i, s)
if gt(i, h) { break }
let k := mload(i) // Key.
let j := add(i, w) // The slot before the current slot.
let v := mload(j) // The value of `j`.
if iszero(gt(v, k)) { continue }
for {} 1 {} {
for { } 1 { } {
mstore(add(j, s), v)
j := add(j, w) // `sub(j, 0x20)`.
v := mload(j)
......@@ -73,7 +73,7 @@ library LibSort {
// Let the stack be the start of the free memory.
let stack := mload(0x40)
for {} iszero(lt(n, 2)) {} {
for { } iszero(lt(n, 2)) { } {
// Push `l` and `h` to the stack.
// The `shl` by 5 is equivalent to multiplying by `0x20`.
let l := add(a, s)
......@@ -94,7 +94,7 @@ library LibSort {
}
// If the array is reversed sorted.
if eq(j, l) {
for {} 1 {} {
for { } 1 { } {
let t := mload(l)
mstore(l, mload(h))
mstore(h, t)
......@@ -112,7 +112,7 @@ library LibSort {
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.
stack := sub(stack, 0x40)
let l := mload(stack)
......@@ -128,14 +128,14 @@ library LibSort {
mstore(i, mload(l))
mstore(l, t)
}
for {} 1 {} {
for { } 1 { } {
i := add(i, s)
if gt(i, h) { break }
let k := mload(i) // Key.
let j := add(i, w) // The slot before the current slot.
let v := mload(j) // The value of `j`.
if iszero(gt(v, k)) { continue }
for {} 1 {} {
for { } 1 { } {
mstore(add(j, s), v)
j := add(j, w)
v := mload(j)
......@@ -176,13 +176,13 @@ library LibSort {
// The value of the pivot slot.
let x := mload(p)
p := h
for { let i := l } 1 {} {
for {} 1 {} {
for { let i := l } 1 { } {
for { } 1 { } {
i := add(i, s)
if iszero(gt(x, mload(i))) { break }
}
let j := p
for {} 1 {} {
for { } 1 { } {
j := add(j, w)
if iszero(lt(x, mload(j))) { break }
}
......@@ -239,7 +239,7 @@ library LibSort {
let x := add(a, 0x20)
let y := add(a, 0x40)
let end := add(a, shl(5, add(mload(a), 1)))
for {} 1 {} {
for { } 1 { } {
if iszero(eq(mload(x), mload(y))) {
x := add(x, 0x20)
mstore(x, mload(y))
......@@ -264,31 +264,19 @@ library LibSort {
/// @dev Returns whether `a` contains `needle`,
/// and the index of the nearest element less than or equal to `needle`.
function searchSorted(uint256[] memory a, uint256 needle)
internal
pure
returns (bool found, uint256 index)
{
function searchSorted(uint256[] memory a, uint256 needle) internal pure returns (bool found, uint256 index) {
(found, index) = _searchSorted(a, needle, 0);
}
/// @dev Returns whether `a` contains `needle`,
/// and the index of the nearest element less than or equal to `needle`.
function searchSorted(int256[] memory a, int256 needle)
internal
pure
returns (bool found, uint256 index)
{
function searchSorted(int256[] memory a, int256 needle) internal pure returns (bool found, uint256 index) {
(found, index) = _searchSorted(_toUints(a), uint256(needle), 1 << 255);
}
/// @dev Returns whether `a` contains `needle`,
/// and the index of the nearest element less than or equal to `needle`.
function searchSorted(address[] memory a, address needle)
internal
pure
returns (bool found, uint256 index)
{
function searchSorted(address[] memory a, address needle) internal pure returns (bool found, uint256 index) {
(found, index) = _searchSorted(_toUints(a), uint256(uint160(needle)), 0);
}
......@@ -300,7 +288,7 @@ library LibSort {
let s := 0x20
let w := not(31)
let h := add(a, shl(5, mload(a)))
for { a := add(a, s) } 1 {} {
for { a := add(a, s) } 1 { } {
let t := mload(a)
mstore(a, mload(h))
mstore(h, t)
......@@ -329,7 +317,7 @@ library LibSort {
result := 1
if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} {
for { a := add(a, 0x20) } 1 { } {
let p := mload(a)
a := add(a, 0x20)
result := iszero(gt(p, mload(a)))
......@@ -346,7 +334,7 @@ library LibSort {
result := 1
if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} {
for { a := add(a, 0x20) } 1 { } {
let p := mload(a)
a := add(a, 0x20)
result := iszero(sgt(p, mload(a)))
......@@ -368,7 +356,7 @@ library LibSort {
result := 1
if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} {
for { a := add(a, 0x20) } 1 { } {
let p := mload(a)
a := add(a, 0x20)
result := lt(p, mload(a))
......@@ -385,7 +373,7 @@ library LibSort {
result := 1
if iszero(lt(mload(a), 2)) {
let end := add(a, shl(5, mload(a)))
for { a := add(a, 0x20) } 1 {} {
for { a := add(a, 0x20) } 1 { } {
let p := mload(a)
a := add(a, 0x20)
result := slt(p, mload(a))
......@@ -402,91 +390,55 @@ library LibSort {
/// @dev Returns the sorted set difference of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function difference(uint256[] memory a, uint256[] memory b)
internal
pure
returns (uint256[] memory c)
{
function difference(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) {
c = _difference(a, b, 0);
}
/// @dev Returns the sorted set difference between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function difference(int256[] memory a, int256[] memory b)
internal
pure
returns (int256[] memory c)
{
function difference(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) {
c = _toInts(_difference(_toUints(a), _toUints(b), 1 << 255));
}
/// @dev Returns the sorted set difference between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function difference(address[] memory a, address[] memory b)
internal
pure
returns (address[] memory c)
{
function difference(address[] memory a, address[] memory b) internal pure returns (address[] memory c) {
c = _toAddresses(_difference(_toUints(a), _toUints(b), 0));
}
/// @dev Returns the sorted set intersection between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function intersection(uint256[] memory a, uint256[] memory b)
internal
pure
returns (uint256[] memory c)
{
function intersection(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) {
c = _intersection(a, b, 0);
}
/// @dev Returns the sorted set intersection between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function intersection(int256[] memory a, int256[] memory b)
internal
pure
returns (int256[] memory c)
{
function intersection(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) {
c = _toInts(_intersection(_toUints(a), _toUints(b), 1 << 255));
}
/// @dev Returns the sorted set intersection between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function intersection(address[] memory a, address[] memory b)
internal
pure
returns (address[] memory c)
{
function intersection(address[] memory a, address[] memory b) internal pure returns (address[] memory c) {
c = _toAddresses(_intersection(_toUints(a), _toUints(b), 0));
}
/// @dev Returns the sorted set union of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function union(uint256[] memory a, uint256[] memory b)
internal
pure
returns (uint256[] memory c)
{
function union(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) {
c = _union(a, b, 0);
}
/// @dev Returns the sorted set union of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function union(int256[] memory a, int256[] memory b)
internal
pure
returns (int256[] memory c)
{
function union(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) {
c = _toInts(_union(_toUints(a), _toUints(b), 1 << 255));
}
/// @dev Returns the sorted set union between `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function union(address[] memory a, address[] memory b)
internal
pure
returns (address[] memory c)
{
function union(address[] memory a, address[] memory b) internal pure returns (address[] memory c) {
c = _toAddresses(_union(_toUints(a), _toUints(b), 0));
}
......@@ -535,7 +487,7 @@ library LibSort {
/// @solidity memory-safe-assembly
assembly {
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)
mstore(a, add(mload(a), w))
}
......@@ -544,7 +496,11 @@ library LibSort {
/// @dev Returns whether `a` contains `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
pure
returns (bool found, uint256 index)
......@@ -555,7 +511,7 @@ library LibSort {
let s := 0x20
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.
for { needle := add(signed, needle) } 1 {} {
for { needle := add(signed, needle) } 1 { } {
// Average of `l` and `h`.
m := add(shl(5, shr(6, add(l, h))), and(31, l))
let t := add(signed, mload(m))
......@@ -578,7 +534,11 @@ library LibSort {
/// @dev Returns the sorted set difference of `a` and `b`.
/// 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
pure
returns (uint256[] memory c)
......@@ -592,7 +552,7 @@ library LibSort {
a := add(a, s)
b := add(b, s)
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 v := mload(b)
if iszero(xor(u, v)) {
......@@ -608,7 +568,7 @@ library LibSort {
mstore(k, u)
a := add(a, s)
}
for {} iszero(gt(a, aEnd)) {} {
for { } iszero(gt(a, aEnd)) { } {
k := add(k, s)
mstore(k, mload(a))
a := add(a, s)
......@@ -620,7 +580,11 @@ library LibSort {
/// @dev Returns the sorted set intersection between `a` and `b`.
/// 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
pure
returns (uint256[] memory c)
......@@ -634,7 +598,7 @@ library LibSort {
a := add(a, s)
b := add(b, s)
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 v := mload(b)
if iszero(xor(u, v)) {
......@@ -657,11 +621,7 @@ library LibSort {
/// @dev Returns the sorted set union of `a` and `b`.
/// Note: Behaviour is undefined if inputs are not sorted and uniquified.
function _union(uint256[] memory a, uint256[] memory b, uint256 signed)
private
pure
returns (uint256[] memory c)
{
function _union(uint256[] memory a, uint256[] memory b, uint256 signed) private pure returns (uint256[] memory c) {
/// @solidity memory-safe-assembly
assembly {
let s := 0x20
......@@ -671,7 +631,7 @@ library LibSort {
a := add(a, s)
b := add(b, s)
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 v := mload(b)
if iszero(xor(u, v)) {
......@@ -691,12 +651,12 @@ library LibSort {
mstore(k, u)
a := add(a, s)
}
for {} iszero(gt(a, aEnd)) {} {
for { } iszero(gt(a, aEnd)) { } {
k := add(k, s)
mstore(k, mload(a))
a := add(a, s)
}
for {} iszero(gt(b, bEnd)) {} {
for { } iszero(gt(b, bEnd)) { } {
k := add(k, s)
mstore(k, mload(b))
b := add(b, s)
......
......@@ -68,7 +68,7 @@ contract DeleteOutput is SafeBuilder {
}
/// @notice Test coverage of the script.
function test_script_succeeds() skipWhenNotForking external {
function test_script_succeeds() external skipWhenNotForking {
uint256 _index = getLatestIndex();
require(_index != 0, "DeleteOutput: No outputs to delete.");
......@@ -103,10 +103,7 @@ contract DeleteOutput is SafeBuilder {
calls[0] = IMulticall3.Call3({
target: oracle,
allowFailure: false,
callData: abi.encodeCall(
L2OutputOracle.deleteL2Outputs,
(index)
)
callData: abi.encodeCall(L2OutputOracle.deleteL2Outputs, (index))
});
return abi.encodeCall(IMulticall3.aggregate3, (calls));
......
......@@ -21,12 +21,10 @@ import { ProxyAdmin } from "../../src/universal/ProxyAdmin.sol";
/// 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.
abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
////////////////////////////////////////////////////////////////
// State //
////////////////////////////////////////////////////////////////
/// @notice Interface for multicall3.
IMulticall3 internal constant multicall = IMulticall3(MULTICALL3_ADDRESS);
......@@ -38,10 +36,10 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
////////////////////////////////////////////////////////////////
/// @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
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.
function computeSafeTransactionHash(address _safe, address _proxyAdmin) public virtual returns (bytes32) {
......@@ -119,11 +117,7 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
// Send a transaction to approve the hash
safe.approveHash(hash);
logSimulationLink({
_to: address(safe),
_from: msg.sender,
_data: abi.encodeCall(safe.approveHash, (hash))
});
logSimulationLink({ _to: address(safe), _from: msg.sender, _data: abi.encodeCall(safe.approveHash, (hash)) });
uint256 threshold = safe.getThreshold();
address[] memory owners = safe.getOwners();
......@@ -206,4 +200,3 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
return signatures;
}
}
......@@ -28,31 +28,26 @@ contract EASUpgrader is SafeBuilder, Deployer {
mapping(uint256 => ContractSet) internal proxies;
/// @notice The expected versions for the contracts to be upgraded to.
string constant internal EAS_Version = "1.0.0";
string constant internal SchemaRegistry_Version = "1.0.0";
string internal constant EAS_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.
function setUp() public override {
super.setUp();
implementations[OP_GOERLI] = ContractSet({
EAS: getAddress("EAS"),
SchemaRegistry: getAddress("SchemaRegistry")
});
implementations[OP_GOERLI] =
ContractSet({ EAS: getAddress("EAS"), SchemaRegistry: getAddress("SchemaRegistry") });
proxies[OP_GOERLI] = ContractSet({
EAS: Predeploys.EAS,
SchemaRegistry: Predeploys.SCHEMA_REGISTRY
});
proxies[OP_GOERLI] = ContractSet({ EAS: Predeploys.EAS, SchemaRegistry: Predeploys.SCHEMA_REGISTRY });
}
/// @notice
function name() public override pure returns (string memory) {
function name() public pure override returns (string memory) {
return "EASUpgrader";
}
/// @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();
require(_versionHash(prox.EAS) == keccak256(bytes(EAS_Version)), "EAS");
require(_versionHash(prox.SchemaRegistry) == keccak256(bytes(SchemaRegistry_Version)), "SchemaRegistry");
......@@ -65,7 +60,7 @@ contract EASUpgrader is SafeBuilder, Deployer {
/// @notice Test coverage of the logic. Should only run on goerli but other chains
/// could be added.
function test_script_succeeds() skipWhenNotForking external {
function test_script_succeeds() external skipWhenNotForking {
address _safe;
address _proxyAdmin;
......@@ -96,7 +91,7 @@ contract EASUpgrader is SafeBuilder, Deployer {
/// @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
/// 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);
ContractSet memory impl = getImplementations();
......@@ -106,20 +101,14 @@ contract EASUpgrader is SafeBuilder, Deployer {
calls[0] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.EAS), impl.EAS)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.EAS), impl.EAS))
});
// Upgrade SchemaRegistry
calls[1] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.SchemaRegistry), impl.SchemaRegistry)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.SchemaRegistry), impl.SchemaRegistry))
});
return abi.encodeCall(IMulticall3.aggregate3, (calls));
......
......@@ -15,7 +15,6 @@ import { Semver } from "../../src/universal/Semver.sol";
/// @title PostSherlockL1
/// @notice Upgrade script for upgrading the L1 contracts after the sherlock audit.
contract PostSherlockL1 is SafeBuilder {
/// @notice Address of the ProxyAdmin, passed in via constructor of `run`.
ProxyAdmin internal PROXY_ADMIN;
......@@ -38,13 +37,13 @@ contract PostSherlockL1 is SafeBuilder {
mapping(uint256 => ContractSet) internal proxies;
/// @notice The expected versions for the contracts to be upgraded to.
string constant internal L1CrossDomainMessenger_Version = "1.4.0";
string constant internal L1StandardBridge_Version = "1.1.0";
string constant internal L2OutputOracle_Version = "1.3.0";
string constant internal OptimismMintableERC20Factory_Version = "1.1.0";
string constant internal OptimismPortal_Version = "1.6.0";
string constant internal SystemConfig_Version = "1.3.0";
string constant internal L1ERC721Bridge_Version = "1.1.1";
string internal constant L1CrossDomainMessenger_Version = "1.4.0";
string internal constant L1StandardBridge_Version = "1.1.0";
string internal constant L2OutputOracle_Version = "1.3.0";
string internal constant OptimismMintableERC20Factory_Version = "1.1.0";
string internal constant OptimismPortal_Version = "1.6.0";
string internal constant SystemConfig_Version = "1.3.0";
string internal constant L1ERC721Bridge_Version = "1.1.1";
/// @notice Place the contract addresses in storage so they can be used when building calldata.
function setUp() external {
......@@ -70,12 +69,18 @@ contract PostSherlockL1 is SafeBuilder {
}
/// @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();
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.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.SystemConfig) == keccak256(bytes(SystemConfig_Version)), "SystemConfig");
require(_versionHash(prox.L1ERC721Bridge) == keccak256(bytes(L1ERC721Bridge_Version)), "L1ERC721Bridge");
......@@ -86,18 +91,41 @@ contract PostSherlockL1 is SafeBuilder {
// Check that the codehashes of all implementations match the proxies set implementations.
ContractSet memory impl = getImplementations();
require(PROXY_ADMIN.getProxyImplementation(prox.L1CrossDomainMessenger).codehash == impl.L1CrossDomainMessenger.codehash, "L1CrossDomainMessenger codehash");
require(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");
require(
PROXY_ADMIN.getProxyImplementation(prox.L1CrossDomainMessenger).codehash
== impl.L1CrossDomainMessenger.codehash,
"L1CrossDomainMessenger codehash"
);
require(
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
/// could be added.
function test_script_succeeds() skipWhenNotForking external {
function test_script_succeeds() external skipWhenNotForking {
address _safe;
address _proxyAdmin;
......@@ -130,7 +158,7 @@ contract PostSherlockL1 is SafeBuilder {
/// @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
/// 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);
ContractSet memory impl = getImplementations();
......@@ -141,8 +169,7 @@ contract PostSherlockL1 is SafeBuilder {
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L1CrossDomainMessenger), impl.L1CrossDomainMessenger)
ProxyAdmin.upgrade, (payable(prox.L1CrossDomainMessenger), impl.L1CrossDomainMessenger)
)
});
......@@ -150,20 +177,14 @@ contract PostSherlockL1 is SafeBuilder {
calls[1] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L1StandardBridge), impl.L1StandardBridge)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1StandardBridge), impl.L1StandardBridge))
});
// Upgrade the L2OutputOracle
calls[2] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L2OutputOracle), impl.L2OutputOracle)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2OutputOracle), impl.L2OutputOracle))
});
// Upgrade the OptimismMintableERC20Factory
......@@ -171,8 +192,7 @@ contract PostSherlockL1 is SafeBuilder {
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory)
ProxyAdmin.upgrade, (payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory)
)
});
......@@ -180,30 +200,21 @@ contract PostSherlockL1 is SafeBuilder {
calls[4] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.OptimismPortal), impl.OptimismPortal)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.OptimismPortal), impl.OptimismPortal))
});
// Upgrade the SystemConfig
calls[5] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.SystemConfig), impl.SystemConfig)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.SystemConfig), impl.SystemConfig))
});
// Upgrade the L1ERC721Bridge
calls[6] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L1ERC721Bridge), impl.L1ERC721Bridge)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1ERC721Bridge), impl.L1ERC721Bridge))
});
// Set the default resource config
......
......@@ -37,17 +37,17 @@ contract PostSherlockL2 is SafeBuilder {
mapping(uint256 => ContractSet) internal proxies;
/// @notice The expected versions for the contracts to be upgraded to.
string constant internal BaseFeeVault_Version = "1.1.0";
string constant internal GasPriceOracle_Version = "1.0.0";
string constant internal L1Block_Version = "1.0.0";
string constant internal L1FeeVault_Version = "1.1.0";
string constant internal L2CrossDomainMessenger_Version = "1.4.0";
string constant internal L2ERC721Bridge_Version = "1.1.0";
string constant internal L2StandardBridge_Version = "1.1.0";
string constant internal L2ToL1MessagePasser_Version = "1.0.0";
string constant internal SequencerFeeVault_Version = "1.1.0";
string constant internal OptimismMintableERC20Factory_Version = "1.1.0";
string constant internal OptimismMintableERC721Factory_Version = "1.2.0";
string internal constant BaseFeeVault_Version = "1.1.0";
string internal constant GasPriceOracle_Version = "1.0.0";
string internal constant L1Block_Version = "1.0.0";
string internal constant L1FeeVault_Version = "1.1.0";
string internal constant L2CrossDomainMessenger_Version = "1.4.0";
string internal constant L2ERC721Bridge_Version = "1.1.0";
string internal constant L2StandardBridge_Version = "1.1.0";
string internal constant L2ToL1MessagePasser_Version = "1.0.0";
string internal constant SequencerFeeVault_Version = "1.1.0";
string internal constant OptimismMintableERC20Factory_Version = "1.1.0";
string internal constant OptimismMintableERC721Factory_Version = "1.2.0";
/// @notice Place the contract addresses in storage so they can be used when building calldata.
function setUp() external {
......@@ -81,19 +81,33 @@ contract PostSherlockL2 is SafeBuilder {
}
/// @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();
require(_versionHash(prox.BaseFeeVault) == keccak256(bytes(BaseFeeVault_Version)), "BaseFeeVault");
require(_versionHash(prox.GasPriceOracle) == keccak256(bytes(GasPriceOracle_Version)), "GasPriceOracle");
require(_versionHash(prox.L1Block) == keccak256(bytes(L1Block_Version)), "L1Block");
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.L2StandardBridge) == keccak256(bytes(L2StandardBridge_Version)), "L2StandardBridge");
require(_versionHash(prox.L2ToL1MessagePasser) == keccak256(bytes(L2ToL1MessagePasser_Version)), "L2ToL1MessagePasser");
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");
require(
_versionHash(prox.L2ToL1MessagePasser) == keccak256(bytes(L2ToL1MessagePasser_Version)),
"L2ToL1MessagePasser"
);
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.
ContractSet memory impl = getImplementations();
......@@ -101,18 +115,29 @@ contract PostSherlockL2 is SafeBuilder {
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.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.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.OptimismMintableERC20Factory).codehash == impl.OptimismMintableERC20Factory.codehash);
require(PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC721Factory).codehash == impl.OptimismMintableERC721Factory.codehash);
require(
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
/// could be added.
function test_script_succeeds() skipWhenNotForking external {
function test_script_succeeds() external skipWhenNotForking {
address _safe;
address _proxyAdmin;
......@@ -143,7 +168,7 @@ contract PostSherlockL2 is SafeBuilder {
/// @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
/// 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);
ContractSet memory impl = getImplementations();
......@@ -153,40 +178,28 @@ contract PostSherlockL2 is SafeBuilder {
calls[0] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.BaseFeeVault), impl.BaseFeeVault)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.BaseFeeVault), impl.BaseFeeVault))
});
// Upgrade the GasPriceOracle
calls[1] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.GasPriceOracle), impl.GasPriceOracle)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.GasPriceOracle), impl.GasPriceOracle))
});
// Upgrade the L1Block predeploy
calls[2] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L1Block), impl.L1Block)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1Block), impl.L1Block))
});
// Upgrade the L1FeeVault
calls[3] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L1FeeVault), impl.L1FeeVault)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L1FeeVault), impl.L1FeeVault))
});
// Upgrade the L2CrossDomainMessenger
......@@ -194,8 +207,7 @@ contract PostSherlockL2 is SafeBuilder {
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L2CrossDomainMessenger), impl.L2CrossDomainMessenger)
ProxyAdmin.upgrade, (payable(prox.L2CrossDomainMessenger), impl.L2CrossDomainMessenger)
)
});
......@@ -203,40 +215,28 @@ contract PostSherlockL2 is SafeBuilder {
calls[5] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L2ERC721Bridge), impl.L2ERC721Bridge)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2ERC721Bridge), impl.L2ERC721Bridge))
});
// Upgrade the L2StandardBridge
calls[6] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L2StandardBridge), impl.L2StandardBridge)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2StandardBridge), impl.L2StandardBridge))
});
// Upgrade the L2ToL1MessagePasser
calls[7] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.L2ToL1MessagePasser), impl.L2ToL1MessagePasser)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.L2ToL1MessagePasser), impl.L2ToL1MessagePasser))
});
// Upgrade the SequencerFeeVault
calls[8] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.SequencerFeeVault), impl.SequencerFeeVault)
)
callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.SequencerFeeVault), impl.SequencerFeeVault))
});
// Upgrade the OptimismMintableERC20Factory
......@@ -244,8 +244,7 @@ contract PostSherlockL2 is SafeBuilder {
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory)
ProxyAdmin.upgrade, (payable(prox.OptimismMintableERC20Factory), impl.OptimismMintableERC20Factory)
)
});
......@@ -254,8 +253,7 @@ contract PostSherlockL2 is SafeBuilder {
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgrade,
(payable(prox.OptimismMintableERC721Factory), impl.OptimismMintableERC721Factory)
ProxyAdmin.upgrade, (payable(prox.OptimismMintableERC721Factory), impl.OptimismMintableERC721Factory)
)
});
......
......@@ -85,8 +85,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
uint256[MAX_GAP - 3] private __gap;
/// @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
function getSchemaRegistry() external pure returns (ISchemaRegistry) {
......@@ -101,9 +100,11 @@ contract EAS is IEAS, Semver, EIP712Verifier {
}
/// @inheritdoc IEAS
function attestByDelegation(
DelegatedAttestationRequest calldata delegatedRequest
) external payable returns (bytes32) {
function attestByDelegation(DelegatedAttestationRequest calldata delegatedRequest)
external
payable
returns (bytes32)
{
_verifyAttest(delegatedRequest);
AttestationRequestData[] memory data = new AttestationRequestData[](1);
......@@ -112,7 +113,11 @@ contract EAS is IEAS, Semver, EIP712Verifier {
}
/// @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
// all the returned UIDs into a single list.
bytes32[][] memory totalUids = new bytes32[][](multiRequests.length);
......@@ -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
// 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.
uint availableValue = msg.value;
uint256 availableValue = msg.value;
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
......@@ -135,13 +140,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
// Process the current batch of attestations.
MultiAttestationRequest calldata multiRequest = multiRequests[i];
AttestationsResult memory res = _attest(
multiRequest.schema,
multiRequest.data,
msg.sender,
availableValue,
last
);
AttestationsResult memory res =
_attest(multiRequest.schema, multiRequest.data, msg.sender, availableValue, last);
// Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch.
availableValue -= res.usedValue;
......@@ -158,9 +158,11 @@ contract EAS is IEAS, Semver, EIP712Verifier {
}
/// @inheritdoc IEAS
function multiAttestByDelegation(
MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests
) external payable returns (bytes32[] memory) {
function multiAttestByDelegation(MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests)
external
payable
returns (bytes32[] memory)
{
// 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.
bytes32[][] memory totalUids = new bytes32[][](multiDelegatedRequests.length);
......@@ -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
// 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.
uint availableValue = msg.value;
uint256 availableValue = msg.value;
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
......@@ -189,7 +191,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
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)) {
_verifyAttest(
DelegatedAttestationRequest({
......@@ -202,13 +205,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
}
// Process the current batch of attestations.
AttestationsResult memory res = _attest(
multiDelegatedRequest.schema,
data,
multiDelegatedRequest.attester,
availableValue,
last
);
AttestationsResult memory res =
_attest(multiDelegatedRequest.schema, data, multiDelegatedRequest.attester, availableValue, last);
// Ensure to deduct the ETH that was forwarded to the resolver during the processing of this batch.
availableValue -= res.usedValue;
......@@ -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
// 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.
uint availableValue = msg.value;
uint256 availableValue = msg.value;
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
......@@ -267,14 +265,15 @@ contract EAS is IEAS, Semver, EIP712Verifier {
}
/// @inheritdoc IEAS
function multiRevokeByDelegation(
MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests
) external payable {
function multiRevokeByDelegation(MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests)
external
payable
{
// 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
// 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.
uint availableValue = msg.value;
uint256 availableValue = msg.value;
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
......@@ -293,7 +292,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
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)) {
_verifyRevoke(
DelegatedRevocationRequest({
......@@ -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.
availableValue -= _revoke(
multiDelegatedRequest.schema,
data,
multiDelegatedRequest.revoker,
availableValue,
last
);
availableValue -=
_revoke(multiDelegatedRequest.schema, data, multiDelegatedRequest.revoker, availableValue, last);
}
}
......@@ -387,7 +382,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
address attester,
uint256 availableValue,
bool last
) private returns (AttestationsResult memory) {
)
private
returns (AttestationsResult memory)
{
uint256 length = data.length;
AttestationsResult memory res;
......@@ -478,7 +476,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
address revoker,
uint256 availableValue,
bool last
) private returns (uint256) {
)
private
returns (uint256)
{
// Ensure that a non-existing schema ID wasn't passed by accident.
SchemaRecord memory schemaRecord = _schemaRegistry.getSchema(schema);
if (schemaRecord.uid == EMPTY_UID) {
......@@ -509,7 +510,8 @@ contract EAS is IEAS, Semver, EIP712Verifier {
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.
if (!attestation.revocable) {
revert Irrevocable();
......@@ -545,7 +547,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
bool isRevocation,
uint256 availableValue,
bool last
) private returns (uint256) {
)
private
returns (uint256)
{
ISchemaResolver resolver = schemaRecord.resolver;
if (address(resolver) == address(0)) {
// Ensure that we don't accept payments if there is no resolver.
......@@ -601,7 +606,10 @@ contract EAS is IEAS, Semver, EIP712Verifier {
bool isRevocation,
uint256 availableValue,
bool last
) private returns (uint256) {
)
private
returns (uint256)
{
uint256 length = attestations.length;
if (length == 1) {
return _resolveAttestation(schemaRecord, attestations[0], values[0], isRevocation, availableValue, last);
......@@ -661,8 +669,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
/// @param bump A bump value to use in case of a UID conflict.
/// @return Attestation UID.
function _getUID(Attestation memory attestation, uint32 bump) private pure returns (bytes32) {
return
keccak256(
return keccak256(
abi.encodePacked(
attestation.schema,
attestation.recipient,
......
......@@ -11,7 +11,8 @@ struct AttestationRequestData {
bool revocable; // Whether the attestation is revocable.
bytes32 refUID; // The UID of the related attestation.
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.
......@@ -38,14 +39,16 @@ struct MultiAttestationRequest {
struct MultiDelegatedAttestationRequest {
bytes32 schema; // The unique identifier of the schema.
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.
}
/// @dev A struct representing the arguments of the revocation request.
struct RevocationRequestData {
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.
......@@ -72,7 +75,8 @@ struct MultiRevocationRequest {
struct MultiDelegatedRevocationRequest {
bytes32 schema; // The unique identifier of the schema.
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.
}
......@@ -152,9 +156,10 @@ interface IEAS {
///
/// @param delegatedRequest The arguments of the delegated attestation request.
/// @return The UID of the new attestation.
function attestByDelegation(
DelegatedAttestationRequest calldata delegatedRequest
) external payable returns (bytes32);
function attestByDelegation(DelegatedAttestationRequest calldata delegatedRequest)
external
payable
returns (bytes32);
/// @notice Attests to multiple schemas.
///
......@@ -194,7 +199,10 @@ interface IEAS {
/// @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.
/// @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.
///
......@@ -234,9 +242,10 @@ interface IEAS {
/// @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.
/// @return The UIDs of the new attestations.
function multiAttestByDelegation(
MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests
) external payable returns (bytes32[] memory);
function multiAttestByDelegation(MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests)
external
payable
returns (bytes32[] memory);
/// @notice Revokes an existing attestation to a specific schema.
///
......@@ -328,11 +337,12 @@ interface IEAS {
/// 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.
function multiRevokeByDelegation(
MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests
) external payable;
function multiRevokeByDelegation(MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests)
external
payable;
/// @notice Timestamps the specified bytes32 data.
/// @param data The data to timestamp.
......
......@@ -22,16 +22,12 @@ contract SchemaRegistry is ISchemaRegistry, Semver {
uint256[MAX_GAP - 1] private __gap;
/// @dev Creates a new SchemaRegistry instance.
constructor() Semver(1, 0, 1) {}
constructor() Semver(1, 0, 1) { }
/// @inheritdoc ISchemaRegistry
function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32) {
SchemaRecord memory schemaRecord = SchemaRecord({
uid: EMPTY_UID,
schema: schema,
resolver: resolver,
revocable: revocable
});
SchemaRecord memory schemaRecord =
SchemaRecord({ uid: EMPTY_UID, schema: schema, resolver: resolver, revocable: revocable });
bytes32 uid = _getUID(schemaRecord);
if (_registry[uid].uid != EMPTY_UID) {
......
......@@ -20,7 +20,8 @@ import { EIP712Signature, InvalidSignature, MAX_GAP, stringToBytes32, bytes32ToS
/// @notice The EIP712 typed signatures verifier for EAS delegated attestations.
abstract contract EIP712Verifier is EIP712 {
// 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;
// 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 {
function multiAttest(
Attestation[] calldata attestations,
uint256[] calldata values
) external payable returns (bool);
)
external
payable
returns (bool);
/// @notice Processes an attestation revocation and verifies if it can be revoked.
/// @param attestation The existing attestation to be revoked.
......@@ -36,5 +39,8 @@ interface ISchemaResolver {
function multiRevoke(
Attestation[] calldata attestations,
uint256[] calldata values
) external payable returns (bool);
)
external
payable
returns (bool);
}
......@@ -56,7 +56,12 @@ abstract contract SchemaResolver is ISchemaResolver, Semver {
function multiAttest(
Attestation[] calldata attestations,
uint256[] calldata values
) external payable onlyEAS returns (bool) {
)
external
payable
onlyEAS
returns (bool)
{
uint256 length = attestations.length;
// 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 {
function multiRevoke(
Attestation[] calldata attestations,
uint256[] calldata values
) external payable onlyEAS returns (bool) {
)
external
payable
onlyEAS
returns (bool)
{
uint256 length = attestations.length;
// 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 {
/// @notice A resolver callback that should be implemented by child contracts.
/// @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
/// both attest() and multiAttest() callbacks EAS-only callbacks and that in case of multi attestations, it'll
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the attestations
/// both attest() and multiAttest() callbacks EAS-only callbacks and that in case of multi attestations,
/// it'll
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the
/// attestations
/// in the batch.
/// @return Whether the attestation is valid.
function onAttest(Attestation calldata attestation, uint256 value) internal virtual returns (bool);
......@@ -137,8 +149,10 @@ abstract contract SchemaResolver is ISchemaResolver, Semver {
/// @notice Processes an attestation revocation and verifies if it can 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
/// both revoke() and multiRevoke() callbacks EAS-only callbacks and that in case of multi attestations, it'll
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the attestations
/// both revoke() and multiRevoke() callbacks EAS-only callbacks and that in case of multi attestations,
/// it'll
/// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the
/// attestations
/// in the batch.
/// @return Whether the attestation can be revoked.
function onRevoke(Attestation calldata attestation, uint256 value) internal virtual returns (bool);
......
......@@ -37,12 +37,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, Semver {
}
/// @inheritdoc CrossDomainMessenger
function _sendMessage(
address _to,
uint64 _gasLimit,
uint256 _value,
bytes memory _data
) internal override {
function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override {
PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);
}
......
......@@ -46,7 +46,10 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
address _to,
uint256 _tokenId,
bytes calldata _extraData
) external onlyOtherBridge {
)
external
onlyOtherBridge
{
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.
......@@ -76,18 +79,15 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
uint256 _tokenId,
uint32 _minGasLimit,
bytes calldata _extraData
) internal override {
)
internal
override
{
require(_remoteToken != address(0), "L1ERC721Bridge: remote token cannot be address(0)");
// Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)
bytes memory message = abi.encodeWithSelector(
L2ERC721Bridge.finalizeBridgeERC721.selector,
_remoteToken,
_localToken,
_from,
_to,
_tokenId,
_extraData
L2ERC721Bridge.finalizeBridgeERC721.selector, _remoteToken, _localToken, _from, _to, _tokenId, _extraData
);
// Lock token into bridge
......
......@@ -23,12 +23,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param to Address of the recipient on L2.
/// @param amount Amount of ETH deposited.
/// @param extraData Extra data attached to the deposit.
event ETHDepositInitiated(
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
/// @custom:legacy
/// @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.
......@@ -36,12 +31,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param to Address of the recipient on L1.
/// @param amount Amount of ETH withdrawn.
/// @param extraData Extra data attached to the withdrawal.
event ETHWithdrawalFinalized(
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
/// @custom:legacy
/// @notice Emitted whenever an ERC20 deposit is initiated.
......@@ -79,10 +69,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @custom:semver 1.2.0
/// @notice Constructs the L1StandardBridge contract.
constructor()
Semver(1, 2, 0)
StandardBridge(StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)))
{
constructor() Semver(1, 2, 0) StandardBridge(StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE))) {
initialize({ _messenger: CrossDomainMessenger(address(0)) });
}
......@@ -130,11 +117,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param _extraData Optional data to forward to L2.
/// 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.
function depositETHTo(
address _to,
uint32 _minGasLimit,
bytes calldata _extraData
) external payable {
function depositETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) external payable {
_initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);
}
......@@ -153,16 +136,12 @@ contract L1StandardBridge is StandardBridge, Semver {
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external virtual onlyEOA {
_initiateERC20Deposit(
_l1Token,
_l2Token,
msg.sender,
msg.sender,
_amount,
_minGasLimit,
_extraData
);
)
external
virtual
onlyEOA
{
_initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
}
/// @custom:legacy
......@@ -182,16 +161,11 @@ contract L1StandardBridge is StandardBridge, Semver {
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external virtual {
_initiateERC20Deposit(
_l1Token,
_l2Token,
msg.sender,
_to,
_amount,
_minGasLimit,
_extraData
);
)
external
virtual
{
_initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);
}
/// @custom:legacy
......@@ -205,7 +179,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes calldata _extraData
) external payable {
)
external
payable
{
finalizeBridgeETH(_from, _to, _amount, _extraData);
}
......@@ -224,7 +201,9 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes calldata _extraData
) external {
)
external
{
finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);
}
......@@ -240,12 +219,7 @@ contract L1StandardBridge is StandardBridge, Semver {
/// @param _to Address of the recipient on L2.
/// @param _minGasLimit Minimum gas limit for the deposit message on L2.
/// @param _extraData Optional data to forward to L2.
function _initiateETHDeposit(
address _from,
address _to,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
function _initiateETHDeposit(address _from, address _to, uint32 _minGasLimit, bytes memory _extraData) internal {
_initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);
}
......@@ -265,7 +239,9 @@ contract L1StandardBridge is StandardBridge, Semver {
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
)
internal
{
_initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);
}
......@@ -277,7 +253,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
)
internal
override
{
emit ETHDepositInitiated(_from, _to, _amount, _extraData);
super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);
}
......@@ -290,7 +269,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
)
internal
override
{
emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);
super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);
}
......@@ -305,7 +287,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
)
internal
override
{
emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
......@@ -320,7 +305,10 @@ contract L1StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
)
internal
override
{
emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
......
......@@ -54,10 +54,7 @@ contract L2OutputOracle is Initializable, Semver {
/// @param l2BlockNumber The L2 block number of the output root.
/// @param l1Timestamp The L1 timestamp when proposed.
event OutputProposed(
bytes32 indexed outputRoot,
uint256 indexed l2OutputIndex,
uint256 indexed l2BlockNumber,
uint256 l1Timestamp
bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp
);
/// @notice Emitted when outputs are deleted.
......@@ -75,23 +72,17 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _submissionInterval,
uint256 _l2BlockTime,
uint256 _finalizationPeriodSeconds
) Semver(1, 4, 0) {
)
Semver(1, 4, 0)
{
require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0");
require(
_submissionInterval > 0,
"L2OutputOracle: submission interval must be greater than 0"
);
require(_submissionInterval > 0, "L2OutputOracle: submission interval must be greater than 0");
SUBMISSION_INTERVAL = _submissionInterval;
L2_BLOCK_TIME = _l2BlockTime;
FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
initialize({
_startingBlockNumber: 0,
_startingTimestamp: 0,
_proposer: address(0),
_challenger: address(0)
});
initialize({ _startingBlockNumber: 0, _startingTimestamp: 0, _proposer: address(0), _challenger: address(0) });
}
/// @notice Initializer.
......@@ -104,7 +95,10 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _startingTimestamp,
address _proposer,
address _challenger
) public reinitializer(2) {
)
public
reinitializer(2)
{
require(
_startingTimestamp <= block.timestamp,
"L2OutputOracle: starting L2 timestamp must be less than current time"
......@@ -151,15 +145,11 @@ contract L2OutputOracle is Initializable, Semver {
/// All outputs after this output will also be deleted.
// solhint-disable-next-line ordering
function deleteL2Outputs(uint256 _l2OutputIndex) external {
require(
msg.sender == challenger,
"L2OutputOracle: only the challenger address can delete outputs"
);
require(msg.sender == challenger, "L2OutputOracle: only the challenger address can delete outputs");
// Make sure we're not *increasing* the length of the array.
require(
_l2OutputIndex < l2Outputs.length,
"L2OutputOracle: cannot delete outputs after the latest output index"
_l2OutputIndex < l2Outputs.length, "L2OutputOracle: cannot delete outputs after the latest output index"
);
// Do not allow deleting any outputs that have already been finalized.
......@@ -190,11 +180,11 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _l2BlockNumber,
bytes32 _l1BlockHash,
uint256 _l1BlockNumber
) external payable {
require(
msg.sender == proposer,
"L2OutputOracle: only the proposer address can propose new outputs"
);
)
external
payable
{
require(msg.sender == proposer, "L2OutputOracle: only the proposer address can propose new outputs");
require(
_l2BlockNumber == nextBlockNumber(),
......@@ -206,10 +196,7 @@ contract L2OutputOracle is Initializable, Semver {
"L2OutputOracle: cannot propose L2 output in the future"
);
require(
_outputRoot != bytes32(0),
"L2OutputOracle: L2 output proposal cannot be the zero hash"
);
require(_outputRoot != bytes32(0), "L2OutputOracle: L2 output proposal cannot be the zero hash");
if (_l1BlockHash != bytes32(0)) {
// This check allows the proposer to propose an output based on a given L1 block,
......@@ -240,11 +227,7 @@ contract L2OutputOracle is Initializable, Semver {
/// @notice Returns an output by index. Needed to return a struct instead of a tuple.
/// @param _l2OutputIndex Index of the output to return.
/// @return The output at the given index.
function getL2Output(uint256 _l2OutputIndex)
external
view
returns (Types.OutputProposal memory)
{
function getL2Output(uint256 _l2OutputIndex) external view returns (Types.OutputProposal memory) {
return l2Outputs[_l2OutputIndex];
}
......@@ -261,10 +244,7 @@ contract L2OutputOracle is Initializable, Semver {
);
// Make sure there's at least one output proposed.
require(
l2Outputs.length > 0,
"L2OutputOracle: cannot get output as no outputs have been proposed yet"
);
require(l2Outputs.length > 0, "L2OutputOracle: cannot get output as no outputs have been proposed yet");
// Find the output via binary search, guaranteed to exist.
uint256 lo = 0;
......@@ -286,11 +266,7 @@ contract L2OutputOracle is Initializable, Semver {
/// block.
/// @param _l2BlockNumber L2 block number to find a checkpoint for.
/// @return First checkpoint that commits to the given L2 block number.
function getL2OutputAfter(uint256 _l2BlockNumber)
external
view
returns (Types.OutputProposal memory)
{
function getL2OutputAfter(uint256 _l2BlockNumber) external view returns (Types.OutputProposal memory) {
return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];
}
......@@ -312,10 +288,7 @@ contract L2OutputOracle is Initializable, Semver {
/// block number.
/// @return Latest submitted L2 block number.
function latestBlockNumber() public view returns (uint256) {
return
l2Outputs.length == 0
? startingBlockNumber
: l2Outputs[l2Outputs.length - 1].l2BlockNumber;
return l2Outputs.length == 0 ? startingBlockNumber : l2Outputs[l2Outputs.length - 1].l2BlockNumber;
}
/// @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 {
/// @param to Address that the deposit transaction is directed to.
/// @param version Version of this deposit transaction event.
/// @param opaqueData ABI encoded deposit data to be parsed off-chain.
event TransactionDeposited(
address indexed from,
address indexed to,
uint256 indexed version,
bytes opaqueData
);
event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
/// @notice Emitted when a withdrawal transaction is proven.
/// @param withdrawalHash Hash of the withdrawal transaction.
/// @param from Address that triggered the withdrawal transaction.
/// @param to Address that the withdrawal transaction is directed to.
event WithdrawalProven(
bytes32 indexed withdrawalHash,
address indexed from,
address indexed to
);
event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to);
/// @notice Emitted when a withdrawal transaction is finalized.
/// @param withdrawalHash Hash of the withdrawal transaction.
......@@ -127,7 +118,10 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
address _guardian,
SystemConfig _systemConfig,
bool _paused
) public reinitializer(2) {
)
public
reinitializer(2)
{
l2Sender = Constants.DEFAULT_L2_SENDER;
l2Oracle = _l2Oracle;
systemConfig = _systemConfig;
......@@ -199,12 +193,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
/// Used internally by the ResourceMetering contract.
/// The SystemConfig is the source of truth for the resource config.
/// @return ResourceMetering ResourceConfig
function _resourceConfig()
internal
view
override
returns (ResourceMetering.ResourceConfig memory)
{
function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory) {
return systemConfig.resourceConfig();
}
......@@ -218,14 +207,14 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
) external whenNotPaused {
)
external
whenNotPaused
{
// 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
// `finalizeWithdrawalTransaction`.
require(
_tx.target != address(this),
"OptimismPortal: you cannot send messages to the portal contract"
);
require(_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
// revert if there is no output root for the given block number.
......@@ -233,8 +222,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// Verify that the output root can be generated with the elements in the proof.
require(
outputRoot == Hashing.hashOutputRootProof(_outputRootProof),
"OptimismPortal: invalid output root proof"
outputRoot == Hashing.hashOutputRootProof(_outputRootProof), "OptimismPortal: invalid output root proof"
);
// Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.
......@@ -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
// output index has been updated.
require(
provenWithdrawal.timestamp == 0 ||
l2Oracle.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=
provenWithdrawal.outputRoot,
provenWithdrawal.timestamp == 0
|| l2Oracle.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot != provenWithdrawal.outputRoot,
"OptimismPortal: withdrawal hash has already been proven"
);
......@@ -270,10 +257,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// be relayed on L1.
require(
SecureMerkleTrie.verifyInclusionProof(
abi.encode(storageKey),
hex"01",
_withdrawalProof,
_outputRootProof.messagePasserStorageRoot
abi.encode(storageKey), hex"01", _withdrawalProof, _outputRootProof.messagePasserStorageRoot
),
"OptimismPortal: invalid withdrawal inclusion proof"
);
......@@ -293,16 +277,12 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
/// @notice Finalizes a withdrawal transaction.
/// @param _tx Withdrawal transaction to finalize.
function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)
external
whenNotPaused
{
function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external whenNotPaused {
// 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
// a defacto reentrancy guard.
require(
l2Sender == Constants.DEFAULT_L2_SENDER,
"OptimismPortal: can only trigger one withdrawal per transaction"
l2Sender == Constants.DEFAULT_L2_SENDER, "OptimismPortal: can only trigger one withdrawal per transaction"
);
// Grab the proven withdrawal from the `provenWithdrawals` map.
......@@ -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
// been proven at least once when its timestamp is non-zero. Unproven withdrawals will have
// a timestamp of zero.
require(
provenWithdrawal.timestamp != 0,
"OptimismPortal: withdrawal has not been proven yet"
);
require(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
// starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of
......@@ -353,10 +330,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
);
// Check that this withdrawal has not already been finalized, this is replay protection.
require(
finalizedWithdrawals[withdrawalHash] == false,
"OptimismPortal: withdrawal has already been finalized"
);
require(finalizedWithdrawals[withdrawalHash] == false, "OptimismPortal: withdrawal has already been finalized");
// Mark the withdrawal as finalized so it can't be replayed.
finalizedWithdrawals[withdrawalHash] = true;
......@@ -403,22 +377,20 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
uint64 _gasLimit,
bool _isCreation,
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
// contract creations.
if (_isCreation) {
require(
_to == address(0),
"OptimismPortal: must send to address(0) when creating a contract"
);
require(_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
// more for more resource usage.
require(
_gasLimit >= minimumGasLimit(uint64(_data.length)),
"OptimismPortal: gas limit too small"
);
require(_gasLimit >= minimumGasLimit(uint64(_data.length)), "OptimismPortal: gas limit too small");
// 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
......@@ -435,13 +407,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// 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
// without breaking the current interface.
bytes memory opaqueData = abi.encodePacked(
msg.value,
_value,
_gasLimit,
_isCreation,
_data
);
bytes memory opaqueData = abi.encodePacked(msg.value, _value, _gasLimit, _isCreation, _data);
// Emit a TransactionDeposited event so that the rollup node can derive a deposit
// transaction for this deposit.
......
......@@ -76,16 +76,16 @@ abstract contract ResourceMetering is Initializable {
uint256 blockDiff = block.number - params.prevBlockNum;
ResourceConfig memory config = _resourceConfig();
int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /
int256(uint256(config.elasticityMultiplier));
int256 targetResourceLimit =
int256(uint256(config.maxResourceLimit)) / int256(uint256(config.elasticityMultiplier));
if (blockDiff > 0) {
// 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
// spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.
int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;
int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /
(targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));
int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta)
/ (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));
// Update base fee by adding the base fee delta and clamp the resulting value between
// min and max.
......@@ -155,10 +155,6 @@ abstract contract ResourceMetering is Initializable {
/// child contract.
// solhint-disable-next-line func-name-mixedcase
function __ResourceMetering_init() internal onlyInitializing {
params = ResourceParams({
prevBaseFee: 1 gwei,
prevBoughtGas: 0,
prevBlockNum: uint64(block.number)
});
params = ResourceParams({ prevBaseFee: 1 gwei, prevBoughtGas: 0, prevBlockNum: uint64(block.number) });
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Semver } from "../universal/Semver.sol";
import { ResourceMetering } from "./ResourceMetering.sol";
......@@ -54,28 +52,23 @@ contract SystemConfig is OwnableUpgradeable, Semver {
bytes32(uint256(keccak256("systemconfig.l1crossdomainmessenger")) - 1);
/// @notice Storage slot that the L1ERC721Bridge address is stored at.
bytes32 public constant L1_ERC_721_BRIDGE_SLOT =
bytes32(uint256(keccak256("systemconfig.l1erc721bridge")) - 1);
bytes32 public constant L1_ERC_721_BRIDGE_SLOT = bytes32(uint256(keccak256("systemconfig.l1erc721bridge")) - 1);
/// @notice Storage slot that the L1StandardBridge address is stored at.
bytes32 public constant L1_STANDARD_BRIDGE_SLOT =
bytes32(uint256(keccak256("systemconfig.l1standardbridge")) - 1);
bytes32 public constant L1_STANDARD_BRIDGE_SLOT = bytes32(uint256(keccak256("systemconfig.l1standardbridge")) - 1);
/// @notice Storage slot that the L2OutputOracle address is stored at.
bytes32 public constant L2_OUTPUT_ORACLE_SLOT =
bytes32(uint256(keccak256("systemconfig.l2outputoracle")) - 1);
bytes32 public constant L2_OUTPUT_ORACLE_SLOT = bytes32(uint256(keccak256("systemconfig.l2outputoracle")) - 1);
/// @notice Storage slot that the OptimismPortal address is stored at.
bytes32 public constant OPTIMISM_PORTAL_SLOT =
bytes32(uint256(keccak256("systemconfig.optimismportal")) - 1);
bytes32 public constant OPTIMISM_PORTAL_SLOT = bytes32(uint256(keccak256("systemconfig.optimismportal")) - 1);
/// @notice Storage slot that the OptimismMintableERC20Factory address is stored at.
bytes32 public constant OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT =
bytes32(uint256(keccak256("systemconfig.optimismmintableerc20factory")) - 1);
/// @notice Storage slot that the batch inbox address is stored at.
bytes32 public constant BATCH_INBOX_SLOT =
bytes32(uint256(keccak256("systemconfig.batchinbox")) - 1);
bytes32 public constant BATCH_INBOX_SLOT = bytes32(uint256(keccak256("systemconfig.batchinbox")) - 1);
/// @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.
uint256 public overhead;
......@@ -165,7 +158,10 @@ contract SystemConfig is OwnableUpgradeable, Semver {
uint256 _startBlock,
address _batchInbox,
SystemConfig.Addresses memory _addresses
) public reinitializer(2) {
)
public
reinitializer(2)
{
__Ownable_init();
transferOwnership(_owner);
......@@ -346,29 +342,19 @@ contract SystemConfig is OwnableUpgradeable, Semver {
function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {
// Min base fee must be less than or equal to max base fee.
require(
_config.minimumBaseFee <= _config.maximumBaseFee,
"SystemConfig: min base fee must be less than max base"
_config.minimumBaseFee <= _config.maximumBaseFee, "SystemConfig: min base fee must be less than max base"
);
// Base fee change denominator must be greater than 1.
require(
_config.baseFeeMaxChangeDenominator > 1,
"SystemConfig: denominator must be larger than 1"
);
require(_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.
// The gas limit must be increased before these values can be increased.
require(
_config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,
"SystemConfig: gas limit too low"
);
require(_config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit, "SystemConfig: gas limit too low");
// Elasticity multiplier must be greater than 0.
require(
_config.elasticityMultiplier > 0,
"SystemConfig: elasticity multiplier cannot be 0"
);
require(_config.elasticityMultiplier > 0, "SystemConfig: elasticity multiplier cannot be 0");
// No precision loss when computing target resource limit.
require(
((_config.maxResourceLimit / _config.elasticityMultiplier) *
_config.elasticityMultiplier) == _config.maxResourceLimit,
((_config.maxResourceLimit / _config.elasticityMultiplier) * _config.elasticityMultiplier)
== _config.maxResourceLimit,
"SystemConfig: precision loss with target resource limit"
);
......
......@@ -18,5 +18,8 @@ contract BaseFeeVault is FeeVault, Semver {
address _recipient,
uint256 _minWithdrawalAmount,
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 {
/// `msg.sender` is the owner of the contract.
function _checkOwner() internal view override {
require(
owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),
"CrossDomainOwnable: caller is not the owner"
owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender), "CrossDomainOwnable: caller is not the owner"
);
}
}
......@@ -15,18 +15,10 @@ abstract contract CrossDomainOwnable2 is Ownable {
/// `xDomainMessageSender` is the owner of the contract. This value is set to the caller
/// of the L1CrossDomainMessenger.
function _checkOwner() internal view override {
L2CrossDomainMessenger messenger = L2CrossDomainMessenger(
Predeploys.L2_CROSS_DOMAIN_MESSENGER
);
L2CrossDomainMessenger messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
require(
msg.sender == address(messenger),
"CrossDomainOwnable2: caller is not the messenger"
);
require(msg.sender == address(messenger), "CrossDomainOwnable2: caller is not the messenger");
require(
owner() == messenger.xDomainMessageSender(),
"CrossDomainOwnable2: caller is not the owner"
);
require(owner() == messenger.xDomainMessageSender(), "CrossDomainOwnable2: caller is not the owner");
}
}
......@@ -20,11 +20,7 @@ abstract contract CrossDomainOwnable3 is Ownable {
/// @param previousOwner The previous owner of the contract.
/// @param newOwner The new owner of the contract.
/// @param isLocal Configures the `isLocal` contract variable.
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner, bool isLocal);
/// @notice Allows for ownership to be transferred with specifying the locality.
/// @param _owner The new owner of the contract.
......@@ -46,19 +42,11 @@ abstract contract CrossDomainOwnable3 is Ownable {
if (isLocal) {
require(owner() == msg.sender, "CrossDomainOwnable3: caller is not the owner");
} else {
L2CrossDomainMessenger messenger = L2CrossDomainMessenger(
Predeploys.L2_CROSS_DOMAIN_MESSENGER
);
L2CrossDomainMessenger messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
require(
msg.sender == address(messenger),
"CrossDomainOwnable3: caller is not the messenger"
);
require(msg.sender == address(messenger), "CrossDomainOwnable3: caller is not the messenger");
require(
owner() == messenger.xDomainMessageSender(),
"CrossDomainOwnable3: caller is not the owner"
);
require(owner() == messenger.xDomainMessageSender(), "CrossDomainOwnable3: caller is not the owner");
}
}
}
......@@ -25,7 +25,7 @@ contract GasPriceOracle is Semver {
/// @custom:semver 1.0.1
/// @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
/// transaction, the current L1 base fee, and the various dynamic parameters.
......@@ -34,7 +34,7 @@ contract GasPriceOracle is Semver {
function getL1Fee(bytes memory _data) external view returns (uint256) {
uint256 l1GasUsed = getL1GasUsed(_data);
uint256 l1Fee = l1GasUsed * l1BaseFee();
uint256 divisor = 10**DECIMALS;
uint256 divisor = 10 ** DECIMALS;
uint256 unscaled = l1Fee * scalar();
uint256 scaled = unscaled / divisor;
return scaled;
......
......@@ -40,7 +40,7 @@ contract L1Block is Semver {
/// @custom:semver 1.0.1
/// @notice Constructs the L1Block contract.
constructor() Semver(1, 0, 1) {}
constructor() Semver(1, 0, 1) { }
/// @notice Updates the L1 block values.
/// @param _number L1 blocknumber.
......@@ -60,11 +60,10 @@ contract L1Block is Semver {
bytes32 _batcherHash,
uint256 _l1FeeOverhead,
uint256 _l1FeeScalar
) external {
require(
msg.sender == DEPOSITOR_ACCOUNT,
"L1Block: only the depositor account can set L1 block values"
);
)
external
{
require(msg.sender == DEPOSITOR_ACCOUNT, "L1Block: only the depositor account can set L1 block values");
number = _number;
timestamp = _timestamp;
......
......@@ -18,5 +18,8 @@ contract L1FeeVault is FeeVault, Semver {
address _recipient,
uint256 _minWithdrawalAmount,
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 {
/// @custom:semver 1.5.0
/// @notice Constructs the L2CrossDomainMessenger contract.
/// @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.
constructor(address _l1CrossDomainMessenger)
Semver(1, 5, 0)
CrossDomainMessenger(_l1CrossDomainMessenger)
{
constructor(address _l1CrossDomainMessenger) Semver(1, 5, 0) CrossDomainMessenger(_l1CrossDomainMessenger) {
initialize();
}
......@@ -38,15 +35,10 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, Semver {
}
/// @inheritdoc CrossDomainMessenger
function _sendMessage(
address _to,
uint64 _gasLimit,
uint256 _value,
bytes memory _data
) internal override {
L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{
value: _value
}(_to, _gasLimit, _data);
function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override {
L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: _value }(
_to, _gasLimit, _data
);
}
/// @inheritdoc CrossDomainMessenger
......
......@@ -48,7 +48,10 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
address _to,
uint256 _tokenId,
bytes calldata _extraData
) external onlyOtherBridge {
)
external
onlyOtherBridge
{
require(_localToken != address(this), "L2ERC721Bridge: local token cannot be self");
// Note that supportsInterface makes a callback to the _localToken address which is user
......@@ -80,7 +83,10 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
uint256 _tokenId,
uint32 _minGasLimit,
bytes calldata _extraData
) internal override {
)
internal
override
{
require(_remoteToken != address(0), "L2ERC721Bridge: remote token cannot be address(0)");
// Check that the withdrawal is being initiated by the NFT owner
......@@ -92,10 +98,7 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
// Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)
// slither-disable-next-line reentrancy-events
address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();
require(
remoteToken == _remoteToken,
"L2ERC721Bridge: remote token does not match given value"
);
require(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
// usage
......@@ -103,13 +106,7 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
IOptimismMintableERC721(_localToken).burn(_from, _tokenId);
bytes memory message = abi.encodeWithSelector(
L1ERC721Bridge.finalizeBridgeERC721.selector,
remoteToken,
_localToken,
_from,
_to,
_tokenId,
_extraData
L1ERC721Bridge.finalizeBridgeERC721.selector, remoteToken, _localToken, _from, _to, _tokenId, _extraData
);
// Send message to L1 bridge
......
......@@ -60,20 +60,13 @@ contract L2StandardBridge is StandardBridge, Semver {
/// @notice Initializer
function initialize() public reinitializer(2) {
__StandardBridge_init({
_messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)
});
__StandardBridge_init({ _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) });
}
/// @notice Allows EOAs to bridge ETH by sending directly to the bridge.
receive() external payable override onlyEOA {
_initiateWithdrawal(
Predeploys.LEGACY_ERC20_ETH,
msg.sender,
msg.sender,
msg.value,
RECEIVE_DEFAULT_GAS_LIMIT,
bytes("")
Predeploys.LEGACY_ERC20_ETH, msg.sender, msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, bytes("")
);
}
......@@ -90,7 +83,12 @@ contract L2StandardBridge is StandardBridge, Semver {
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external payable virtual onlyEOA {
)
external
payable
virtual
onlyEOA
{
_initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
}
......@@ -113,7 +111,11 @@ contract L2StandardBridge is StandardBridge, Semver {
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external payable virtual {
)
external
payable
virtual
{
_initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);
}
......@@ -133,7 +135,11 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes calldata _extraData
) external payable virtual {
)
external
payable
virtual
{
if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {
finalizeBridgeETH(_from, _to, _amount, _extraData);
} else {
......@@ -163,7 +169,9 @@ contract L2StandardBridge is StandardBridge, Semver {
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
)
internal
{
if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {
_initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);
} else {
......@@ -180,15 +188,11 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
emit WithdrawalInitiated(
address(0),
Predeploys.LEGACY_ERC20_ETH,
_from,
_to,
_amount,
_extraData
);
)
internal
override
{
emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, _from, _to, _amount, _extraData);
super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);
}
......@@ -200,15 +204,11 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
emit DepositFinalized(
address(0),
Predeploys.LEGACY_ERC20_ETH,
_from,
_to,
_amount,
_extraData
);
)
internal
override
{
emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, _from, _to, _amount, _extraData);
super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);
}
......@@ -222,7 +222,10 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
)
internal
override
{
emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
......@@ -237,7 +240,10 @@ contract L2StandardBridge is StandardBridge, Semver {
address _to,
uint256 _amount,
bytes memory _extraData
) internal override {
)
internal
override
{
emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);
super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
......
......@@ -50,7 +50,7 @@ contract L2ToL1MessagePasser is Semver {
/// @custom:semver 1.0.1
/// @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.
receive() external payable {
......@@ -71,11 +71,7 @@ contract L2ToL1MessagePasser is Semver {
/// @param _target Address to call on L1 execution.
/// @param _gasLimit Minimum gas limit for executing the message on L1.
/// @param _data Data to forward to L1 target.
function initiateWithdrawal(
address _target,
uint256 _gasLimit,
bytes memory _data
) public payable {
function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) public payable {
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({
nonce: messageNonce(),
......@@ -89,15 +85,7 @@ contract L2ToL1MessagePasser is Semver {
sentMessages[withdrawalHash] = true;
emit MessagePassed(
messageNonce(),
msg.sender,
_target,
msg.value,
_gasLimit,
_data,
withdrawalHash
);
emit MessagePassed(messageNonce(), msg.sender, _target, msg.value, _gasLimit, _data, withdrawalHash);
unchecked {
++msgNonce;
......
......@@ -19,7 +19,10 @@ contract SequencerFeeVault is FeeVault, Semver {
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 3, 0) {}
)
FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
Semver(1, 3, 0)
{ }
/// @custom:legacy
/// @notice Legacy getter for the recipient address.
......
......@@ -20,7 +20,6 @@ import { PreimageKeyLib } from "./PreimageKeyLib.sol";
/// @dev https://github.com/golang/go/blob/master/src/syscall/zerrors_linux_mips.go
/// MIPS linux kernel errors used by Go runtime
contract MIPS {
/// @notice Stores the VM state.
/// 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.
......@@ -40,7 +39,7 @@ contract MIPS {
}
/// @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_STDOUT = 1;
......@@ -104,9 +103,7 @@ contract MIPS {
from := add(from, 32) // offset to registers
// Copy registers
for { let i := 0 } lt(i, 32) { i := add(i, 1) } {
from, to := copyMem(from, to, 4)
}
for { let i := 0 } lt(i, 32) { i := add(i, 1) } { from, to := copyMem(from, to, 4) }
// Clean up end of memory
mstore(to, 0)
......@@ -141,8 +138,9 @@ contract MIPS {
// mmap: Allocates a page from the heap.
if (syscall_no == 4090) {
uint32 sz = a1;
if (sz&4095 != 0) { // adjust size to align with page size
sz += 4096 - (sz&4095);
if (sz & 4095 != 0) {
// adjust size to align with page size
sz += 4096 - (sz & 4095);
}
if (a0 == 0) {
v0 = state.heap;
......@@ -191,9 +189,11 @@ contract MIPS {
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
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 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
mem := or(and(mem, not(mask)), dat) // clear masked part of original memory, and insert data
}
......@@ -208,8 +208,7 @@ contract MIPS {
// Don't read into memory, just say we read it all
// The result is ignored anyway
v0 = a2;
}
else {
} else {
v0 = 0xFFffFFff;
v1 = EBADF;
}
......@@ -242,17 +241,18 @@ contract MIPS {
state.preimageKey = key;
state.preimageOffset = 0; // reset offset, to read new pre-image data from the start
v0 = a2;
}
else {
} else {
v0 = 0xFFffFFff;
v1 = EBADF;
}
}
// fcntl: Like linux fcntl syscall, but only supports minimal file-descriptor control commands,
// 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
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) {
v0 = 0; // O_RDONLY
} else if (a0 == FD_STDOUT || a0 == FD_STDERR || a0 == FD_PREIMAGE_WRITE || a0 == FD_HINT_WRITE) {
......@@ -295,7 +295,7 @@ contract MIPS {
bool shouldBranch = false;
if (state.nextPC != state.pc+4) {
if (state.nextPC != state.pc + 4) {
revert("branch in delay slot");
}
......@@ -428,7 +428,7 @@ contract MIPS {
state := 0x80
}
if (state.nextPC != state.pc+4) {
if (state.nextPC != state.pc + 4) {
revert("jump in delay slot");
}
......@@ -486,7 +486,9 @@ contract MIPS {
// And the leaf value itself needs to be encoded as well. And proof.offset == 388
offset_ = 388 + (uint256(_proofIndex) * (28 * 32));
uint256 s = 0;
assembly { s := calldatasize() }
assembly {
s := calldatasize()
}
require(s >= (offset_ + 28 * 32), "check that there is enough calldata");
return offset_;
}
......@@ -503,9 +505,7 @@ contract MIPS {
assembly {
// Validate the address alignement.
if and(_addr, 3) {
revert(0, 0)
}
if and(_addr, 3) { revert(0, 0) }
// Load the leaf value.
let leaf := calldataload(offset)
......@@ -526,11 +526,8 @@ contract MIPS {
let sibling := calldataload(offset)
offset := add(offset, 32)
switch and(shr(i, path), 1)
case 0 {
node := hashPair(node, sibling)
} case 1 {
node := hashPair(sibling, node)
}
case 0 { node := hashPair(node, sibling) }
case 1 { node := hashPair(sibling, node) }
}
// Load the memory root from the first field of state.
......@@ -562,9 +559,7 @@ contract MIPS {
assembly {
// Validate the address alignement.
if and(_addr, 3) {
revert(0, 0)
}
if and(_addr, 3) { revert(0, 0) }
// Load the leaf value.
let leaf := calldataload(offset)
......@@ -589,11 +584,8 @@ contract MIPS {
let sibling := calldataload(offset)
offset := add(offset, 32)
switch and(shr(i, path), 1)
case 0 {
node := hashPair(node, sibling)
} case 1 {
node := hashPair(sibling, node)
}
case 0 { node := hashPair(node, sibling) }
case 1 { node := hashPair(sibling, node) }
}
// Store the new memory root in the first field of state.
......@@ -610,17 +602,21 @@ contract MIPS {
// Packed calldata is ~6 times smaller than state size
assembly {
if iszero(eq(state, 0x80)) { // expected state mem offset check
revert(0,0)
if iszero(eq(state, 0x80)) {
// expected state mem offset check
revert(0, 0)
}
if iszero(eq(mload(0x40), mul(32, 48))) { // expected memory check
revert(0,0)
if iszero(eq(mload(0x40), mul(32, 48))) {
// expected memory check
revert(0, 0)
}
if iszero(eq(stateData.offset, 100)) { // 32*3+4=100 expected state data offset
revert(0,0)
if iszero(eq(stateData.offset, 100)) {
// 32*3+4=100 expected state data offset
revert(0, 0)
}
if iszero(eq(proof.offset, 388)) { // 100+32+256=388 expected proof offset
revert(0,0)
if iszero(eq(proof.offset, 388)) {
// 100+32+256=388 expected proof offset
revert(0, 0)
}
function putField(callOffset, memOffset, size) -> callOffsetOut, memOffsetOut {
......@@ -649,9 +645,7 @@ contract MIPS {
// Unpack register calldata into memory
mstore(m, add(m, 32)) // offset to registers
m := add(m, 32)
for { let i := 0 } lt(i, 32) { i := add(i, 1) } {
c, m := putField(c, m, 4)
}
for { let i := 0 } lt(i, 32) { i := add(i, 1) } { c, m := putField(c, m, 4) }
}
// Don't change state once exited
......@@ -713,7 +707,7 @@ contract MIPS {
uint32 mem;
if (opcode >= 0x20) {
// M[R[rs]+SignExtImm]
rs += SE(insn&0xFFFF, 16);
rs += SE(insn & 0xFFFF, 16);
uint32 addr = rs & 0xFFFFFFFC;
mem = readMem(addr, 1);
if (opcode >= 0x28 && opcode != 0x30) {
......@@ -729,14 +723,17 @@ contract MIPS {
uint32 func = insn & 0x3f; // 6-bits
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);
}
if (func == 0xa) { // movz
if (func == 0xa) {
// movz
return handleRd(rdReg, rs, rt == 0);
}
if (func == 0xb) { // movn
if (func == 0xb) {
// movn
return handleRd(rdReg, rs, rt != 0);
}
......@@ -778,13 +775,19 @@ contract MIPS {
// transform ArithLogI
// TODO(CLI-4136): replace with table
if (opcode >= 8 && opcode < 0xF) {
if (opcode == 8) { func = 0x20; } // addi
else if (opcode == 9) { func = 0x21; } // addiu
else if (opcode == 0xa) { func = 0x2a; } // slti
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
if (opcode == 8) func = 0x20; // addi
else if (opcode == 9) func = 0x21; // addiu
else if (opcode == 0xa) func = 0x2a; // slti
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;
}
......@@ -854,7 +857,7 @@ contract MIPS {
}
// sltu: Set to 1 if less than unsigned
else if (func == 0x2B) {
return rs<rt ? 1 : 0;
return rs < rt ? 1 : 0;
}
}
// lui: Load Upper Immediate
......@@ -873,15 +876,14 @@ contract MIPS {
rs = ~rs;
}
uint32 i = 0;
while (rs&0x80000000 != 0) {
while (rs & 0x80000000 != 0) {
i++;
rs <<= 1;
}
return i;
}
}
}
else if (opcode < 0x28) {
} else if (opcode < 0x28) {
// lb
if (opcode == 0x20) {
return SE((mem >> (24 - (rs & 3) * 8)) & 0xFF, 8);
......
......@@ -16,11 +16,7 @@ contract PreimageOracle is IPreimageOracle {
mapping(bytes32 => mapping(uint256 => bool)) public preimagePartOk;
/// @inheritdoc IPreimageOracle
function readPreimage(bytes32 _key, uint256 _offset)
external
view
returns (bytes32 dat_, uint256 datLen_)
{
function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_) {
require(preimagePartOk[_key][_offset], "pre-image must exist");
// Calculate the length of the pre-image data
......@@ -40,12 +36,7 @@ contract PreimageOracle is IPreimageOracle {
/// 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.
/// This method is DANGEROUS. And NOT FOR PRODUCTION.
function cheat(
uint256 partOffset,
bytes32 key,
bytes32 part,
uint256 size
) external {
function cheat(uint256 partOffset, bytes32 key, bytes32 part, uint256 size) external {
preimagePartOk[key][partOffset] = true;
preimageParts[key][partOffset] = part;
preimageLengths[key] = size;
......@@ -57,7 +48,10 @@ contract PreimageOracle is IPreimageOracle {
bytes32 _word,
uint256 _size,
uint256 _partOffset
) external returns (bytes32 key_) {
)
external
returns (bytes32 key_)
{
// Compute the localized key from the given local identifier.
key_ = PreimageKeyLib.localizeIdent(_ident);
......
......@@ -9,10 +9,7 @@ interface IPreimageOracle {
/// @param _offset The offset of the preimage to read.
/// @return dat_ The preimage data.
/// @return datLen_ The length of the preimage data.
function readPreimage(bytes32 _key, uint256 _offset)
external
view
returns (bytes32 dat_, uint256 datLen_);
function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_);
/// @notice Loads of local data part into the preimage oracle.
/// @param _ident The identifier of the local data.
......@@ -38,7 +35,9 @@ interface IPreimageOracle {
bytes32 _word,
uint256 _size,
uint256 _partOffset
) external returns (bytes32 key_);
)
external
returns (bytes32 key_);
/// @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).
......
......@@ -14,11 +14,7 @@ contract BlockOracle {
}
/// @notice Emitted when a block is checkpointed.
event Checkpoint(
uint256 indexed blockNumber,
Hash indexed blockHash,
Timestamp indexed childTimestamp
);
event Checkpoint(uint256 indexed blockNumber, Hash indexed blockHash, Timestamp indexed childTimestamp);
/// @notice Maps block numbers to block hashes and timestamps
mapping(uint256 => BlockInfo) internal blocks;
......
......@@ -2,9 +2,7 @@
pragma solidity ^0.8.15;
import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol";
import {
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Semver } from "src/universal/Semver.sol";
import { IDisputeGame } from "./interfaces/IDisputeGame.sol";
......@@ -58,7 +56,11 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
GameType _gameType,
Claim _rootClaim,
bytes calldata _extraData
) external view returns (IDisputeGame proxy_, uint256 timestamp_) {
)
external
view
returns (IDisputeGame proxy_, uint256 timestamp_)
{
Hash uuid = getGameUUID(_gameType, _rootClaim, _extraData);
GameId slot = _disputeGames[uuid];
(address addr, uint256 timestamp) = _unpackSlot(slot);
......@@ -67,11 +69,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
}
/// @inheritdoc IDisputeGameFactory
function gameAtIndex(uint256 _index)
external
view
returns (IDisputeGame proxy_, uint256 timestamp_)
{
function gameAtIndex(uint256 _index) external view returns (IDisputeGame proxy_, uint256 timestamp_) {
GameId slot = _disputeGameList[_index];
(address addr, uint256 timestamp) = _unpackSlot(slot);
proxy_ = IDisputeGame(addr);
......@@ -83,7 +81,10 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
GameType gameType,
Claim rootClaim,
bytes calldata extraData
) external returns (IDisputeGame proxy) {
)
external
returns (IDisputeGame proxy)
{
// Grab the implementation contract for the given `GameType`.
IDisputeGame impl = gameImpls[gameType];
......@@ -109,11 +110,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
}
/// @inheritdoc IDisputeGameFactory
function getGameUUID(
GameType gameType,
Claim rootClaim,
bytes memory extraData
) public pure returns (Hash _uuid) {
function getGameUUID(GameType gameType, Claim rootClaim, bytes memory extraData) public pure returns (Hash _uuid) {
assembly {
// Grab the offsets of the other memory locations we will need to temporarily overwrite.
let gameTypeOffset := sub(extraData, 0x60)
......
......@@ -94,7 +94,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
IBigStepper _vm,
L2OutputOracle _l2oo,
BlockOracle _blockOracle
) Semver(0, 0, 7) {
)
Semver(0, 0, 7)
{
GAME_TYPE = _gameType;
ABSOLUTE_PRESTATE = _absolutePrestate;
MAX_GAME_DEPTH = _maxGameDepth;
......@@ -109,12 +111,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
////////////////////////////////////////////////////////////////
/// @inheritdoc IFaultDisputeGame
function step(
uint256 _claimIndex,
bool _isAttack,
bytes calldata _stateData,
bytes calldata _proof
) external {
function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external {
// INVARIANT: Steps cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
......@@ -139,10 +136,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// the game state.
preStateClaim = stepPos.indexAtDepth() == 0
? ABSOLUTE_PRESTATE
: findTraceAncestor(
Position.wrap(Position.unwrap(parentPos) - 1),
parent.parentIndex
).claim;
: findTraceAncestor(Position.wrap(Position.unwrap(parentPos) - 1), parent.parentIndex).claim;
// For all attacks, the poststate is the parent claim.
postState = parent;
......@@ -150,10 +144,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// If the step is a defense, the poststate exists elsewhere in the game state,
// and the parent claim is the expected pre-state.
preStateClaim = parent.claim;
postState = findTraceAncestor(
Position.wrap(Position.unwrap(parentPos) + 1),
parent.parentIndex
);
postState = findTraceAncestor(Position.wrap(Position.unwrap(parentPos) + 1), parent.parentIndex);
}
// INVARIANT: The prestate is always invalid if the passed `_stateData` is not the
......@@ -185,11 +176,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @param _challengeIndex The index of the claim being moved against.
/// @param _claim The claim at the next logical position in the game.
/// @param _isAttack Whether or not the move is an attack or defense.
function move(
uint256 _challengeIndex,
Claim _claim,
bool _isAttack
) public payable {
function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable {
// INVARIANT: Moves cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
......@@ -225,11 +212,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
Duration nextDuration = Duration.wrap(
uint64(
// 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
// parent's clock timestamp.
block.timestamp -
Timestamp.unwrap(parent.clock.timestamp())
+ block.timestamp - Timestamp.unwrap(parent.clock.timestamp())
)
);
......@@ -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
uint256 leftMostIndex = claimData.length - 1;
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.
ClaimData storage claim = claimData[i];
......@@ -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
// creation.
uint256 parentIndex = leftMostUncontested.parentIndex;
Clock opposingClock = parentIndex == type(uint32).max
? leftMostUncontested.clock
: claimData[parentIndex].clock;
Clock opposingClock = parentIndex == type(uint32).max ? leftMostUncontested.clock : claimData[parentIndex].clock;
if (
Duration.unwrap(opposingClock.duration()) +
(block.timestamp - Timestamp.unwrap(opposingClock.timestamp())) <=
Duration.unwrap(GAME_DURATION) >> 1
Duration.unwrap(opposingClock.duration()) + (block.timestamp - Timestamp.unwrap(opposingClock.timestamp()))
<= Duration.unwrap(GAME_DURATION) >> 1
) {
revert ClockNotExpired();
}
......@@ -410,8 +393,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// 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.
if (
leftMostUncontested
.position
// slither-disable-next-line weak-prng
leftMostUncontested.position.depth() % 2 == 0 && leftMostTraceIndex != type(uint128).max
.depth() % 2 == 0 && leftMostTraceIndex != type(uint128).max
) {
status_ = GameStatus.DEFENDER_WINS;
} else {
......@@ -435,15 +420,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
}
/// @inheritdoc IDisputeGame
function gameData()
external
view
returns (
GameType gameType_,
Claim rootClaim_,
bytes memory extraData_
)
{
function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_) {
gameType_ = gameType();
rootClaim_ = rootClaim();
extraData_ = extraData();
......@@ -543,11 +520,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @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
// looping?
function findTraceAncestor(Position _pos, uint256 _start)
internal
view
returns (ClaimData storage ancestor_)
{
function findTraceAncestor(Position _pos, uint256 _start) internal view returns (ClaimData storage ancestor_) {
// Grab the trace ancestor's expected position.
Position preStateTraceAncestor = _pos.traceAncestor();
......
......@@ -30,9 +30,7 @@ interface IBigStepper {
/// @param _stateData The preimage of the prestate hash.
/// @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.
function step(bytes calldata _stateData, bytes calldata _proof)
external
returns (bytes32 postState_);
function step(bytes calldata _stateData, bytes calldata _proof) external returns (bytes32 postState_);
/// @notice Returns the preimage oracle used by the stepper.
function oracle() external view returns (IPreimageOracle oracle_);
......
......@@ -30,11 +30,7 @@ interface IBondManager {
/// @param _bondOwner is the address that owns the bond.
/// @param _minClaimHold is the minimum amount of time the owner
/// must wait before reclaiming their bond.
function post(
bytes32 _bondId,
address _bondOwner,
uint128 _minClaimHold
) external payable;
function post(bytes32 _bondId, address _bondOwner, uint128 _minClaimHold) external payable;
/// @notice Seizes the bond with 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 {
/// @return gameType_ The type of proof system being used.
/// @return rootClaim_ The root claim of the DisputeGame.
/// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
function gameData()
external
view
returns (
GameType gameType_,
Claim rootClaim_,
bytes memory extraData_
);
function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_);
}
......@@ -12,11 +12,7 @@ interface IDisputeGameFactory {
/// @param disputeProxy The address of the dispute game proxy
/// @param gameType The type of the dispute game proxy's implementation
/// @param rootClaim The root claim of the dispute game
event DisputeGameCreated(
address indexed disputeProxy,
GameType indexed gameType,
Claim indexed rootClaim
);
event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);
/// @notice Emitted when a new game implementation added to the factory
/// @param impl The implementation contract for the given `GameType`.
......@@ -40,7 +36,10 @@ interface IDisputeGameFactory {
GameType gameType,
Claim rootClaim,
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
/// at the given index. Each created dispute game increments the underlying index.
......@@ -48,10 +47,7 @@ interface IDisputeGameFactory {
/// @return _proxy The clone of the `DisputeGame` created with the given parameters.
/// Returns `address(0)` if nonexistent.
/// @return _timestamp The timestamp of the creation of the dispute game.
function gameAtIndex(uint256 _index)
external
view
returns (IDisputeGame _proxy, uint256 _timestamp);
function gameAtIndex(uint256 _index) external view returns (IDisputeGame _proxy, uint256 _timestamp);
/// @notice `gameImpls` is a mapping that maps `GameType`s to their respective
/// `IDisputeGame` implementations.
......@@ -69,7 +65,9 @@ interface IDisputeGameFactory {
GameType gameType,
Claim rootClaim,
bytes calldata extraData
) external returns (IDisputeGame proxy);
)
external
returns (IDisputeGame proxy);
/// @notice Sets the implementation contract for a specific `GameType`.
/// @dev May only be called by the `owner`.
......@@ -88,5 +86,8 @@ interface IDisputeGameFactory {
GameType gameType,
Claim rootClaim,
bytes memory extraData
) external pure returns (Hash _uuid);
)
external
pure
returns (Hash _uuid);
}
......@@ -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 absolute prestate of the fault proof VM.
/// @param _proof Proof to access memory nodes in the VM's merkle state tree.
function step(
uint256 _claimIndex,
bool _isAttack,
bytes calldata _stateData,
bytes calldata _proof
) external;
function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external;
/// @notice Posts the requested local data to the VM's `PreimageOralce`.
/// @param _ident The local identifier of the data to post.
......
......@@ -6,7 +6,6 @@ import "src/libraries/DisputeTypes.sol";
/// @title Hashing
/// @notice This library contains all of the hashing utilities used in the Cannon contracts.
library LibHashing {
/// @notice Hashes a claim and a position together.
/// @param _claim A Claim type.
/// @param _position The position of `claim`.
......
......@@ -6,7 +6,6 @@ import "src/libraries/DisputeTypes.sol";
/// @title LibPosition
/// @notice This library contains helper functions for working with the `Position` type.
library LibPosition {
/// @notice Computes a generalized index (2^{depth} + indexAtDepth).
/// @param _depth The depth of the position.
/// @param _indexAtDepth The index at the depth of the position.
......@@ -36,7 +35,8 @@ library LibPosition {
_position := or(_position, shr(8, _position))
_position := or(_position, shr(16, _position))
depth_ := or(
depth_ :=
or(
depth_,
byte(
shr(251, mul(_position, shl(224, 0x07c4acdd))),
......@@ -93,10 +93,7 @@ library LibPosition {
/// @param _position The position to get the relative deepest, right most gindex of.
/// @param _maxDepth The maximum depth of the game.
/// @return rightIndex_ The deepest, right most gindex relative to the `position`.
function rightIndex(
Position _position,
uint256 _maxDepth
) internal pure returns (Position rightIndex_) {
function rightIndex(Position _position, uint256 _maxDepth) internal pure returns (Position rightIndex_) {
uint256 msb = depth(_position);
assembly {
let remaining := sub(_maxDepth, msb)
......@@ -110,17 +107,11 @@ library LibPosition {
/// @param _position The position to get the relative trace index of.
/// @param _maxDepth The maximum depth of the game.
/// @return traceIndex_ The trace index relative to the `position`.
function traceIndex(
Position _position,
uint256 _maxDepth
) internal pure returns (uint256 traceIndex_) {
function traceIndex(Position _position, uint256 _maxDepth) internal pure returns (uint256 traceIndex_) {
uint256 msb = depth(_position);
assembly {
let remaining := sub(_maxDepth, msb)
traceIndex_ := sub(
or(shl(remaining, _position), sub(shl(remaining, 1), 1)),
shl(_maxDepth, 1)
)
traceIndex_ := sub(or(shl(remaining, _position), sub(shl(remaining, 1), 1)), shl(_maxDepth, 1))
}
}
......
......@@ -14,7 +14,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";
/// inflation schedule.
contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
/// @notice Constructs the GovernanceToken contract.
constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") {}
constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") { }
/// @notice Allows the owner to mint tokens.
/// @param _account The account receiving minted tokens.
......@@ -27,11 +27,7 @@ contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
/// @param from The account sending tokens.
/// @param to The account receiving tokens.
/// @param amount The amount of tokens being transfered.
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal override(ERC20, ERC20Votes) {
function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) {
super._afterTokenTransfer(from, to, amount);
}
......
......@@ -41,10 +41,7 @@ contract MintManager is Ownable {
/// @param _amount The amount of tokens to mint.
function mint(address _account, uint256 _amount) public onlyOwner {
if (mintPermittedAfter > 0) {
require(
mintPermittedAfter <= block.timestamp,
"MintManager: minting not permitted yet"
);
require(mintPermittedAfter <= block.timestamp, "MintManager: minting not permitted yet");
require(
_amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,
......@@ -59,10 +56,7 @@ contract MintManager is Ownable {
/// @notice Upgrade the owner of the governance token to a new MintManager.
/// @param _newMintManager The MintManager to upgrade to.
function upgrade(address _newMintManager) public onlyOwner {
require(
_newMintManager != address(0),
"MintManager: mint manager cannot be the zero address"
);
require(_newMintManager != address(0), "MintManager: mint manager cannot be the zero address");
governanceToken.transferOwnership(_newMintManager);
}
......
......@@ -36,15 +36,12 @@ contract DeployerWhitelist is Semver {
/// @notice Blocks functions to anyone except the contract owner.
modifier onlyOwner() {
require(
msg.sender == owner,
"DeployerWhitelist: function can only be called by the owner of this contract"
);
require(msg.sender == owner, "DeployerWhitelist: function can only be called by the owner of this contract");
_;
}
/// @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.
/// @param _deployer Address to update permissions for.
......@@ -60,10 +57,7 @@ contract DeployerWhitelist is Semver {
// Prevent users from setting the whitelist owner to address(0) except via
// enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to
// any other address that doesn't have a corresponding knowable private key.
require(
_owner != address(0),
"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment"
);
require(_owner != address(0), "DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment");
emit OwnerChanged(owner, _owner);
owner = _owner;
......
......@@ -15,7 +15,7 @@ import { Semver } from "../universal/Semver.sol";
/// contract instead.
contract L1BlockNumber is Semver {
/// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {}
constructor() Semver(1, 0, 1) { }
/// @notice Returns the L1 block number.
receive() external payable {
......
......@@ -22,12 +22,10 @@ contract L1ChugSplashProxy {
bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;
/// @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
bytes32 internal constant IMPLEMENTATION_KEY =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
bytes32 internal constant IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/// @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
bytes32 internal constant OWNER_KEY =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
bytes32 internal constant OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/// @notice Blocks a function from being called when the parent signals that the system should
/// be paused via an isUpgrading function.
......@@ -37,9 +35,8 @@ contract L1ChugSplashProxy {
// 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
// it turns out that it isn't the right type of contract.
(bool success, bytes memory returndata) = owner.staticcall(
abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)
);
(bool success, bytes memory returndata) =
owner.staticcall(abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector));
// 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
......@@ -195,9 +192,7 @@ contract L1ChugSplashProxy {
returndatacopy(0x0, 0x0, returndatasize())
// Success == 0 means a revert. We'll revert too and pass the data up.
if iszero(success) {
revert(0x0, returndatasize())
}
if iszero(success) { revert(0x0, returndatasize()) }
// Otherwise we'll just return and pass the data up.
return(0x0, returndatasize())
......
......@@ -14,9 +14,7 @@ import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/// disabled as part of the EVM equivalence upgrade.
contract LegacyERC20ETH is OptimismMintableERC20 {
/// @notice Initializes the contract as an Optimism Mintable ERC20.
constructor()
OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH")
{}
constructor() OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH") { }
/// @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
......@@ -53,11 +51,7 @@ contract LegacyERC20ETH is OptimismMintableERC20 {
/// @custom:blocked
/// @notice Transfers funds from some sender account.
function transferFrom(
address,
address,
uint256
) public virtual override returns (bool) {
function transferFrom(address, address, uint256) public virtual override returns (bool) {
revert("LegacyERC20ETH: transferFrom is disabled");
}
......
......@@ -14,7 +14,7 @@ contract LegacyMessagePasser is Semver {
mapping(bytes32 => bool) public sentMessages;
/// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {}
constructor() Semver(1, 0, 1) { }
/// @notice Passes a message to L1.
/// @param _message Message to pass to L1.
......
......@@ -29,7 +29,9 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
address _l1Token,
string memory _name,
string memory _symbol
) ERC20(_name, _symbol) {
)
ERC20(_name, _symbol)
{
l1Token = _l1Token;
l2Bridge = _l2Bridge;
}
......@@ -43,9 +45,8 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
/// @notice EIP165 implementation.
function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^
ILegacyMintableERC20.mint.selector ^
ILegacyMintableERC20.burn.selector;
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^ ILegacyMintableERC20.mint.selector
^ ILegacyMintableERC20.burn.selector;
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
}
......
......@@ -32,9 +32,7 @@ contract ResolvedDelegateProxy {
/// @notice Fallback, performs a delegatecall to the resolved implementation address.
// solhint-disable-next-line no-complex-fallback
fallback() external payable {
address target = addressManager[address(this)].getAddress(
(implementationName[address(this)])
);
address target = addressManager[address(this)].getAddress((implementationName[address(this)]));
require(target != address(0), "ResolvedDelegateProxy: target address must be initialized");
......
......@@ -12,11 +12,7 @@ library Arithmetic {
/// @param _min The minimum value.
/// @param _max The maximum value.
/// @return The clamped value.
function clamp(
int256 _value,
int256 _min,
int256 _max
) internal pure returns (int256) {
function clamp(int256 _value, int256 _min, int256 _max) internal pure returns (int256) {
return SignedMath.min(SignedMath.max(_value, _min), _max);
}
......@@ -26,13 +22,7 @@ library Arithmetic {
/// @param _denominator Fractional denominator.
/// @param _exponent Power function exponent.
/// @return Result of c * (1 - 1/d)^exp.
function cdexp(
int256 _coefficient,
int256 _denominator,
int256 _exponent
) internal pure returns (int256) {
return
(_coefficient *
(FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;
function cdexp(int256 _coefficient, int256 _denominator, int256 _exponent) internal pure returns (int256) {
return (_coefficient * (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;
}
}
......@@ -12,11 +12,7 @@ library Bytes {
/// @param _start Starting index of the slice.
/// @param _length Length of the slice.
/// @return Slice of the input byte array.
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
) internal pure returns (bytes memory) {
function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {
unchecked {
require(_length + 31 >= _length, "slice_overflow");
require(_start + _length >= _start, "slice_overflow");
......@@ -56,9 +52,7 @@ library Bytes {
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
} { mstore(mc, mload(cc)) }
mstore(tempBytes, _length)
......@@ -125,11 +119,7 @@ library Bytes {
let nibblesStart := add(_nibbles, 0x20)
// Loop through each byte in the input array
for {
let i := 0x00
} lt(i, bytesLength) {
i := add(i, 0x01)
} {
for { let i := 0x00 } lt(i, bytesLength) { i := add(i, 0x01) } {
// Get the starting offset of the next 2 bytes in the nibbles array
let offset := add(nibblesStart, shl(0x01, i))
// Load the byte at the current index within the `_bytes` array
......
......@@ -46,11 +46,7 @@ contract Clone {
/// @param argOffset The offset of the arg in the packed data
/// @param arrLen Number of elements in the array
/// @return arr The array
function _getArgUint256Array(uint256 argOffset, uint64 arrLen)
internal
pure
returns (uint256[] memory arr)
{
function _getArgUint256Array(uint256 argOffset, uint64 arrLen) internal pure returns (uint256[] memory arr) {
uint256 offset = _getImmutableArgsOffset() + argOffset;
arr = new uint256[](arrLen);
......@@ -63,11 +59,7 @@ contract Clone {
/// @param argOffset The offset of the arg in the packed data
/// @param arrLen Number of elements in the array
/// @return arr The array
function _getArgDynBytes(uint256 argOffset, uint64 arrLen)
internal
pure
returns (bytes memory arr)
{
function _getArgDynBytes(uint256 argOffset, uint64 arrLen) internal pure returns (bytes memory arr) {
uint256 offset = _getImmutableArgsOffset() + argOffset;
arr = new bytes(arrLen);
......
......@@ -23,11 +23,7 @@ library Constants {
/// @notice Returns the default values for the ResourceConfig. These are the recommended values
/// for a production network.
function DEFAULT_RESOURCE_CONFIG()
internal
pure
returns (ResourceMetering.ResourceConfig memory)
{
function DEFAULT_RESOURCE_CONFIG() internal pure returns (ResourceMetering.ResourceConfig memory) {
ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({
maxResourceLimit: 20_000_000,
elasticityMultiplier: 10,
......
......@@ -60,8 +60,9 @@ type Position is uint128;
type GameType is uint8;
/// @notice The current status of the dispute game.
enum GameStatus {
// The game is currently in progress, and has not been resolved.
enum GameStatus
// The game is currently in progress, and has not been resolved.
{
IN_PROGRESS,
// The game has concluded, and the `rootClaim` was challenged successfully.
CHALLENGER_WINS,
......
......@@ -13,11 +13,7 @@ library Encoding {
/// transaction is prefixed with 0x7e to identify its EIP-2718 type.
/// @param _tx User deposit transaction to encode.
/// @return RLP encoded L2 deposit transaction.
function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)
internal
pure
returns (bytes memory)
{
function encodeDepositTransaction(Types.UserDepositTransaction memory _tx) internal pure returns (bytes memory) {
bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);
bytes[] memory raw = new bytes[](8);
raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
......@@ -47,7 +43,11 @@ library Encoding {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) internal pure returns (bytes memory) {
)
internal
pure
returns (bytes memory)
{
(, uint16 version) = decodeVersionedNonce(_nonce);
if (version == 0) {
return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);
......@@ -69,15 +69,12 @@ library Encoding {
address _sender,
bytes memory _data,
uint256 _nonce
) internal pure returns (bytes memory) {
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_data,
_nonce
);
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSignature("relayMessage(address,address,bytes,uint256)", _target, _sender, _data, _nonce);
}
/// @notice Encodes a cross domain message based on the V1 (current) encoding.
......@@ -95,9 +92,12 @@ library Encoding {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) internal pure returns (bytes memory) {
return
abi.encodeWithSignature(
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSignature(
"relayMessage(uint256,address,address,uint256,uint256,bytes)",
_nonce,
_sender,
......
......@@ -12,11 +12,7 @@ library Hashing {
/// system.
/// @param _tx User deposit transaction to hash.
/// @return Hash of the RLP encoded L2 deposit transaction.
function hashDepositTransaction(Types.UserDepositTransaction memory _tx)
internal
pure
returns (bytes32)
{
function hashDepositTransaction(Types.UserDepositTransaction memory _tx) internal pure returns (bytes32) {
return keccak256(Encoding.encodeDepositTransaction(_tx));
}
......@@ -26,11 +22,7 @@ library Hashing {
/// @param _l1BlockHash Hash of the L1 block where the deposit was included.
/// @param _logIndex The index of the log that created the deposit transaction.
/// @return Hash of the deposit transaction's "source hash".
function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)
internal
pure
returns (bytes32)
{
function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex) internal pure returns (bytes32) {
bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));
return keccak256(abi.encode(bytes32(0), depositId));
}
......@@ -51,7 +43,11 @@ library Hashing {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) internal pure returns (bytes32) {
)
internal
pure
returns (bytes32)
{
(, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
if (version == 0) {
return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);
......@@ -73,7 +69,11 @@ library Hashing {
address _sender,
bytes memory _data,
uint256 _nonce
) internal pure returns (bytes32) {
)
internal
pure
returns (bytes32)
{
return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));
}
......@@ -92,45 +92,27 @@ library Hashing {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) internal pure returns (bytes32) {
return
keccak256(
Encoding.encodeCrossDomainMessageV1(
_nonce,
_sender,
_target,
_value,
_gasLimit,
_data
)
);
internal
pure
returns (bytes32)
{
return keccak256(Encoding.encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data));
}
/// @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract
/// @param _tx Withdrawal transaction to hash.
/// @return Hashed withdrawal transaction.
function hashWithdrawal(Types.WithdrawalTransaction memory _tx)
internal
pure
returns (bytes32)
{
return
keccak256(
abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)
);
function hashWithdrawal(Types.WithdrawalTransaction memory _tx) internal 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
/// can be used to check if the proof is valid.
/// @param _outputRootProof Output root proof which should hash to an output root.
/// @return Hashed output root proof.
function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)
internal
pure
returns (bytes32)
{
return
keccak256(
function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof) internal pure returns (bytes32) {
return keccak256(
abi.encode(
_outputRootProof.version,
_outputRootProof.stateRoot,
......
......@@ -19,14 +19,13 @@ library LegacyCrossDomainUtils {
address _sender,
bytes memory _message,
uint256 _messageNonce
) internal pure returns (bytes memory) {
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_message,
_messageNonce
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)", _target, _sender, _message, _messageNonce
);
}
}
......@@ -8,8 +8,7 @@ library Predeploys {
address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;
/// @notice Address of the L2CrossDomainMessenger predeploy.
address internal constant L2_CROSS_DOMAIN_MESSENGER =
0x4200000000000000000000000000000000000007;
address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007;
/// @notice Address of the L2StandardBridge predeploy.
address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;
......@@ -21,12 +20,10 @@ library Predeploys {
address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;
/// @notice Address of the OptimismMintableERC20Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =
0x4200000000000000000000000000000000000012;
address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY = 0x4200000000000000000000000000000000000012;
/// @notice Address of the OptimismMintableERC721Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =
0x4200000000000000000000000000000000000017;
address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY = 0x4200000000000000000000000000000000000017;
/// @notice Address of the L1Block predeploy.
address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;
......
......@@ -9,14 +9,11 @@ library SafeCall {
/// @param _target Address to call
/// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call
function send(
address _target,
uint256 _gas,
uint256 _value
) internal returns (bool) {
function send(address _target, uint256 _gas, uint256 _value) internal returns (bool) {
bool _success;
assembly {
_success := call(
_success :=
call(
_gas, // gas
_target, // recipient
_value, // ether value
......@@ -34,15 +31,11 @@ library SafeCall {
/// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call
function call(
address _target,
uint256 _gas,
uint256 _value,
bytes memory _calldata
) internal returns (bool) {
function call(address _target, uint256 _gas, uint256 _value, bytes memory _calldata) internal returns (bool) {
bool _success;
assembly {
_success := call(
_success :=
call(
_gas, // gas
_target, // recipient
_value, // ether value
......@@ -82,9 +75,7 @@ library SafeCall {
bool _hasMinGas;
assembly {
// Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas)
_hasMinGas := iszero(
lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63)))
)
_hasMinGas := iszero(lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63))))
}
return _hasMinGas;
}
......@@ -101,7 +92,10 @@ library SafeCall {
uint256 _minGas,
uint256 _value,
bytes memory _calldata
) internal returns (bool) {
)
internal
returns (bool)
{
bool _success;
bool _hasMinGas = hasMinGas(_minGas, 0);
assembly {
......@@ -132,7 +126,8 @@ library SafeCall {
// `_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
// the minimum amount of gas specified.
_success := call(
_success :=
call(
gas(), // gas
_target, // recipient
_value, // ether value
......
......@@ -34,10 +34,7 @@ library RLPReader {
/// @return out_ Output memory reference.
function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory out_) {
// Empty arrays are not RLP items.
require(
_in.length > 0,
"RLPReader: length of an RLP item must be greater than zero to be decodable"
);
require(_in.length > 0, "RLPReader: length of an RLP item must be greater than zero to be decodable");
MemoryPointer ptr;
assembly {
......@@ -53,15 +50,9 @@ library RLPReader {
function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory out_) {
(uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);
require(
itemType == RLPItemType.LIST_ITEM,
"RLPReader: decoded item type for list is not a list item"
);
require(itemType == RLPItemType.LIST_ITEM, "RLPReader: decoded item type for list is not a list item");
require(
listOffset + listLength == _in.length,
"RLPReader: list item has an invalid data remainder"
);
require(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
// writing to the length. Since we can't know the number of RLP items without looping over
......@@ -72,11 +63,8 @@ library RLPReader {
uint256 itemCount = 0;
uint256 offset = listOffset;
while (offset < _in.length) {
(uint256 itemOffset, uint256 itemLength, ) = _decodeLength(
RLPItem({
length: _in.length - offset,
ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)
})
(uint256 itemOffset, uint256 itemLength,) = _decodeLength(
RLPItem({ 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
......@@ -109,15 +97,9 @@ library RLPReader {
function readBytes(RLPItem memory _in) internal pure returns (bytes memory out_) {
(uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);
require(
itemType == RLPItemType.DATA_ITEM,
"RLPReader: decoded item type for bytes is not a data item"
);
require(itemType == RLPItemType.DATA_ITEM, "RLPReader: decoded item type for bytes is not a data item");
require(
_in.length == itemOffset + itemLength,
"RLPReader: bytes value contains an invalid remainder"
);
require(_in.length == itemOffset + itemLength, "RLPReader: bytes value contains an invalid remainder");
out_ = _copy(_in.ptr, itemOffset, itemLength);
}
......@@ -144,19 +126,12 @@ library RLPReader {
function _decodeLength(RLPItem memory _in)
private
pure
returns (
uint256 offset_,
uint256 length_,
RLPItemType type_
)
returns (uint256 offset_, uint256 length_, RLPItemType type_)
{
// 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
// that function and create an RLP item directly. So we need to check this anyway.
require(
_in.length > 0,
"RLPReader: length of an RLP item must be greater than zero to be decodable"
);
require(_in.length > 0, "RLPReader: length of an RLP item must be greater than zero to be decodable");
MemoryPointer ptr = _in.ptr;
uint256 prefix;
......@@ -174,8 +149,7 @@ library RLPReader {
uint256 strLen = prefix - 0x80;
require(
_in.length > strLen,
"RLPReader: length of content must be greater than string length (short string)"
_in.length > strLen, "RLPReader: length of content must be greater than string length (short string)"
);
bytes1 firstByteOfContent;
......@@ -204,8 +178,7 @@ library RLPReader {
}
require(
firstByteOfContent != 0x00,
"RLPReader: length of content must not have any leading zeros (long string)"
firstByteOfContent != 0x00, "RLPReader: length of content must not have any leading zeros (long string)"
);
uint256 strLen;
......@@ -213,10 +186,7 @@ library RLPReader {
strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))
}
require(
strLen > 55,
"RLPReader: length of content must be greater than 55 bytes (long string)"
);
require(strLen > 55, "RLPReader: length of content must be greater than 55 bytes (long string)");
require(
_in.length > lenOfStrLen + strLen,
......@@ -229,10 +199,7 @@ library RLPReader {
// slither-disable-next-line variable-scope
uint256 listLen = prefix - 0xc0;
require(
_in.length > listLen,
"RLPReader: length of content must be greater than list length (short list)"
);
require(_in.length > listLen, "RLPReader: length of content must be greater than list length (short list)");
return (1, listLen, RLPItemType.LIST_ITEM);
} else {
......@@ -250,8 +217,7 @@ library RLPReader {
}
require(
firstByteOfContent != 0x00,
"RLPReader: length of content must not have any leading zeros (long list)"
firstByteOfContent != 0x00, "RLPReader: length of content must not have any leading zeros (long list)"
);
uint256 listLen;
......@@ -259,10 +225,7 @@ library RLPReader {
listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))
}
require(
listLen > 55,
"RLPReader: length of content must be greater than 55 bytes (long list)"
);
require(listLen > 55, "RLPReader: length of content must be greater than 55 bytes (long list)");
require(
_in.length > lenOfListLen + listLen,
......@@ -278,11 +241,7 @@ library RLPReader {
/// @param _offset Offset to start reading from.
/// @param _length Number of bytes to read.
/// @return out_ Copied bytes.
function _copy(
MemoryPointer _src,
uint256 _offset,
uint256 _length
) private pure returns (bytes memory out_) {
function _copy(MemoryPointer _src, uint256 _offset, uint256 _length) private pure returns (bytes memory out_) {
out_ = new bytes(_length);
if (_length == 0) {
return out_;
......@@ -295,17 +254,9 @@ library RLPReader {
assembly {
let dest := add(out_, 32)
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) {
mstore(add(dest, _length), 0)
}
if gt(i, _length) { mstore(add(dest, _length), 0) }
}
}
}
......@@ -74,7 +74,7 @@ library RLPWriter {
out_ = new bytes(lenLen + 1);
out_[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);
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 {
/// @param _dest Destination location.
/// @param _src Source location.
/// @param _len Length of memory to copy.
function _memcpy(
uint256 _dest,
uint256 _src,
uint256 _len
) private pure {
function _memcpy(uint256 _dest, uint256 _src, uint256 _len) private pure {
uint256 dest = _dest;
uint256 src = _src;
uint256 len = _len;
......@@ -122,7 +118,7 @@ library RLPWriter {
uint256 mask;
unchecked {
mask = 256**(32 - len) - 1;
mask = 256 ** (32 - len) - 1;
}
assembly {
let srcpart := and(mload(src), not(mask))
......
......@@ -52,7 +52,11 @@ library MerkleTrie {
bytes memory _value,
bytes[] memory _proof,
bytes32 _root
) internal pure returns (bool valid_) {
)
internal
pure
returns (bool valid_)
{
valid_ = Bytes.equal(_value, get(_key, _proof, _root));
}
......@@ -61,11 +65,7 @@ library MerkleTrie {
/// @param _proof Merkle trie inclusion proof for the key.
/// @param _root Known root of the Merkle trie.
/// @return value_ Value of the key if it exists.
function get(
bytes memory _key,
bytes[] memory _proof,
bytes32 _root
) internal pure returns (bytes memory value_) {
function get(bytes memory _key, bytes[] memory _proof, bytes32 _root) internal pure returns (bytes memory value_) {
require(_key.length > 0, "MerkleTrie: empty key");
TrieNode[] memory proof = _parseProof(_proof);
......@@ -78,10 +78,7 @@ library MerkleTrie {
TrieNode memory currentNode = proof[i];
// Key index should never exceed total key length or we'll be out of bounds.
require(
currentKeyIndex <= key.length,
"MerkleTrie: key index exceeds total key length"
);
require(currentKeyIndex <= key.length, "MerkleTrie: key index exceeds total key length");
if (currentKeyIndex == 0) {
// First proof element is always the root node.
......@@ -97,10 +94,7 @@ library MerkleTrie {
);
} else {
// Nodes smaller than 32 bytes aren't hashed.
require(
Bytes.equal(currentNode.encoded, currentNodeID),
"MerkleTrie: invalid internal node hash"
);
require(Bytes.equal(currentNode.encoded, currentNodeID), "MerkleTrie: invalid internal node hash");
}
if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {
......@@ -111,16 +105,10 @@ library MerkleTrie {
// 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.
value_ = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);
require(
value_.length > 0,
"MerkleTrie: value length must be greater than zero (branch)"
);
require(value_.length > 0, "MerkleTrie: value length must be greater than zero (branch)");
// Extra proof elements are not allowed.
require(
i == proof.length - 1,
"MerkleTrie: value node must be last node in proof (branch)"
);
require(i == proof.length - 1, "MerkleTrie: value node must be last node in proof (branch)");
return value_;
} else {
......@@ -164,16 +152,10 @@ library MerkleTrie {
// say that if the value is empty, the key should not exist and the proof is
// invalid.
value_ = RLPReader.readBytes(currentNode.decoded[1]);
require(
value_.length > 0,
"MerkleTrie: value length must be greater than zero (leaf)"
);
require(value_.length > 0, "MerkleTrie: value length must be greater than zero (leaf)");
// Extra proof elements are not allowed.
require(
i == proof.length - 1,
"MerkleTrie: value node must be last node in proof (leaf)"
);
require(i == proof.length - 1, "MerkleTrie: value node must be last node in proof (leaf)");
return value_;
} else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {
......@@ -200,7 +182,7 @@ library MerkleTrie {
function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory proof_) {
uint256 length = _proof.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]) });
unchecked {
++i;
......@@ -227,13 +209,9 @@ library MerkleTrie {
/// @param _a First nibble array.
/// @param _b Second nibble array.
/// @return shared_ Number of shared nibbles.
function _getSharedNibbleLength(bytes memory _a, bytes memory _b)
private
pure
returns (uint256 shared_)
{
function _getSharedNibbleLength(bytes memory _a, bytes memory _b) private pure returns (uint256 shared_) {
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 {
++shared_;
}
......
......@@ -21,7 +21,11 @@ library SecureMerkleTrie {
bytes memory _value,
bytes[] memory _proof,
bytes32 _root
) internal pure returns (bool valid_) {
)
internal
pure
returns (bool valid_)
{
bytes memory key = _getSecureKey(_key);
valid_ = MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);
}
......@@ -31,11 +35,7 @@ library SecureMerkleTrie {
/// @param _proof Merkle trie inclusion proof for the key.
/// @param _root Known root of the Merkle trie.
/// @return value_ Value of the key if it exists.
function get(
bytes memory _key,
bytes[] memory _proof,
bytes32 _root
) internal pure returns (bytes memory value_) {
function get(bytes memory _key, bytes[] memory _proof, bytes32 _root) internal pure returns (bytes memory value_) {
bytes memory key = _getSecureKey(_key);
value_ = MerkleTrie.get(key, _proof, _root);
}
......
......@@ -25,27 +25,17 @@ contract AssetReceiver is Transactor {
/// @param recipient Address that received the withdrawal.
/// @param asset Address of the token being withdrawn.
/// @param amount ERC20 amount withdrawn.
event WithdrewERC20(
address indexed withdrawer,
address indexed recipient,
address indexed asset,
uint256 amount
);
event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount);
/// @notice Emitted when ERC20 tokens are withdrawn from this address.
/// @param withdrawer Address that triggered the withdrawal.
/// @param recipient Address that received the withdrawal.
/// @param asset Address of the token being withdrawn.
/// @param id Token ID being withdrawn.
event WithdrewERC721(
address indexed withdrawer,
address indexed recipient,
address indexed asset,
uint256 id
);
event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id);
/// @param _owner Initial contract owner.
constructor(address _owner) Transactor(_owner) {}
constructor(address _owner) Transactor(_owner) { }
/// @notice Make sure we can receive ETH.
receive() external payable {
......@@ -63,7 +53,7 @@ contract AssetReceiver is Transactor {
/// @param _amount Amount of ETH to withdraw.
function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {
// 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.
emit WithdrewETH(msg.sender, _to, _amount);
}
......@@ -79,11 +69,7 @@ contract AssetReceiver is Transactor {
/// @param _asset ERC20 token to withdraw.
/// @param _to Address to receive the ERC20 balance.
/// @param _amount Amount of ERC20 to withdraw.
function withdrawERC20(
ERC20 _asset,
address _to,
uint256 _amount
) public onlyOwner {
function withdrawERC20(ERC20 _asset, address _to, uint256 _amount) public onlyOwner {
// slither-disable-next-line unchecked-transfer
_asset.transfer(_to, _amount);
// slither-disable-next-line reentrancy-events
......@@ -94,11 +80,7 @@ contract AssetReceiver is Transactor {
/// @param _asset ERC721 token to withdraw.
/// @param _to Address to receive the ERC721 token.
/// @param _id Token ID of the ERC721 token to withdraw.
function withdrawERC721(
ERC721 _asset,
address _to,
uint256 _id
) external onlyOwner {
function withdrawERC721(ERC721 _asset, address _to, uint256 _id) external onlyOwner {
_asset.transferFrom(address(this), _to, _id);
// slither-disable-next-line reentrancy-events
emit WithdrewERC721(msg.sender, _to, address(_asset), _id);
......
......@@ -7,7 +7,7 @@ import { Owned } from "@rari-capital/solmate/src/auth/Owned.sol";
/// @notice Transactor is a minimal contract that can send transactions.
contract Transactor is Owned {
/// @param _owner Initial contract owner.
constructor(address _owner) Owned(_owner) {}
constructor(address _owner) Owned(_owner) { }
/// @notice Sends a CALL to a target address.
/// @param _target Address to call.
......@@ -19,7 +19,12 @@ contract Transactor is Owned {
address _target,
bytes memory _data,
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);
}
......@@ -28,7 +33,10 @@ contract Transactor is Owned {
/// @param _data Data to send with the call.
/// @return success_ Boolean success value.
/// @return data_ Bytes data returned by the call.
function DELEGATECALL(address _target, bytes memory _data)
function DELEGATECALL(
address _target,
bytes memory _data
)
external
payable
onlyOwner
......
......@@ -33,11 +33,7 @@ contract TransferOnion is ReentrancyGuard {
/// @param _token Address of the token to distribute.
/// @param _sender Address of the sender to distribute from.
/// @param _shell Initial shell of the onion.
constructor(
ERC20 _token,
address _sender,
bytes32 _shell
) {
constructor(ERC20 _token, address _sender, bytes32 _shell) {
TOKEN = _token;
SENDER = _sender;
shell = _shell;
......@@ -48,7 +44,7 @@ contract TransferOnion is ReentrancyGuard {
function peel(Layer[] memory _layers) public nonReentrant {
bytes32 tempShell = shell;
uint256 length = _layers.length;
for (uint256 i = 0; i < length; ) {
for (uint256 i = 0; i < length;) {
Layer memory layer = _layers[i];
// Confirm that the onion layer is correct.
......
......@@ -55,42 +55,29 @@ contract Drippie is AssetReceiver {
/// @param nameref Indexed name parameter (hashed).
/// @param name Unindexed name parameter (unhashed).
/// @param config Config for the created drip.
event DripCreated(
// Emit name twice because indexed version is hashed.
string indexed nameref,
string name,
DripConfig config
);
event DripCreated(string indexed nameref, string name, DripConfig config);
/// @notice Emitted when a drip status is updated.
/// @param nameref Indexed name parameter (hashed).
/// @param name Unindexed name parameter (unhashed).
/// @param status New drip status.
event DripStatusUpdated(
// Emit name twice because indexed version is hashed.
string indexed nameref,
string name,
DripStatus status
);
event DripStatusUpdated(string indexed nameref, string name, DripStatus status);
/// @notice Emitted when a drip is executed.
/// @param nameref Indexed name parameter (hashed).
/// @param name Unindexed name parameter (unhashed).
/// @param executor Address that executed the drip.
/// @param timestamp Time when the drip was executed.
event DripExecuted(
// Emit name twice because indexed version is hashed.
string indexed nameref,
string name,
address executor,
uint256 timestamp
);
event DripExecuted(string indexed nameref, string name, address executor, uint256 timestamp);
/// @notice Maps from drip names to drip states.
mapping(string => DripState) public drips;
//// @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
/// 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 {
// 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
// archival is a separate status.
require(
drips[_name].status == DripStatus.NONE,
"Drippie: drip with that name already exists"
);
require(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
// been marked as reentrant. Prevents client-side bugs making a drip infinitely executable
// within the same block (of course, restricted by gas limits).
if (_config.reentrant) {
require(
_config.interval == 0,
"Drippie: if allowing reentrant drip, must set interval to zero"
);
require(_config.interval == 0, "Drippie: if allowing reentrant drip, must set interval to zero");
} else {
require(
_config.interval > 0,
"Drippie: interval must be greater than zero if drip is not reentrant"
);
require(_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.
......@@ -147,10 +125,7 @@ contract Drippie is AssetReceiver {
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
// prevent accidental overwrites if this code is ever updated down the line.
require(
_status != DripStatus.NONE,
"Drippie: drip status can never be set back to NONE after creation"
);
require(_status != DripStatus.NONE, "Drippie: drip status can never be set back to NONE after creation");
// Load the drip status once to avoid unnecessary SLOADs.
DripStatus curr = drips[_name].status;
......@@ -158,34 +133,22 @@ contract Drippie is AssetReceiver {
// 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
// the case of a front-end bug.
require(
curr != DripStatus.NONE,
"Drippie: drip with that name does not exist and cannot be updated"
);
require(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
// point of archiving a drip.
require(
curr != DripStatus.ARCHIVED,
"Drippie: drip with that name has been archived and cannot be updated"
);
require(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.
// 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.
require(
curr != _status,
"Drippie: cannot set drip status to the same status as its current status"
);
require(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
// not allow users to archive active drips so that the effects of this action are more
// abundantly clear.
if (_status == DripStatus.ARCHIVED) {
require(
curr == DripStatus.PAUSED,
"Drippie: drip must first be paused before being archived"
);
require(curr == DripStatus.PAUSED, "Drippie: drip must first be paused before being archived");
}
// If we made it here then we can safely update the status.
......@@ -200,10 +163,7 @@ contract Drippie is AssetReceiver {
DripState storage state = drips[_name];
// Only allow active drips to be executed, an obvious security measure.
require(
state.status == DripStatus.ACTIVE,
"Drippie: selected drip does not exist or is not currently active"
);
require(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
// is a safety measure that prevents a malicious recipient from, e.g., spending all of
......@@ -269,7 +229,7 @@ contract Drippie is AssetReceiver {
// will ever happen in practice). Could save a marginal amount of gas to ignore the
// returndata.
// 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
// the wrong data to the target contract), the recipient is not payable, or
......@@ -279,10 +239,7 @@ contract Drippie is AssetReceiver {
// 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
// not execute).
require(
success,
"Drippie: drip was unsuccessful, please check your configuration for mistakes"
);
require(success, "Drippie: drip was unsuccessful, please check your configuration for mistakes");
}
emit DripExecuted(_name, _name, msg.sender, block.timestamp);
......
......@@ -25,12 +25,10 @@ contract CheckGelatoLow is IDripCheck {
Params memory params = abi.decode(_params, (Params));
// Check GelatoTreasury ETH balance is below threshold.
execute_ =
IGelatoTreasury(params.treasury).userTokenBalance(
execute_ = IGelatoTreasury(params.treasury).userTokenBalance(
params.recipient,
// Gelato represents ETH as 0xeeeee....eeeee
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
) <
params.threshold;
) < params.threshold;
}
}
......@@ -20,12 +20,7 @@ contract Faucet {
/// @param userId The id of the user that requested the drip.
/// @param amount The amount of funds sent.
/// @param recipient The recipient of the drip.
event Drip(
string indexed authModule,
bytes32 indexed userId,
uint256 amount,
address indexed recipient
);
event Drip(string indexed authModule, bytes32 indexed userId, uint256 amount, address indexed recipient);
/// @notice Parameters for a drip.
struct DripParameters {
......
......@@ -14,8 +14,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 {
address public immutable ADMIN;
/// @notice EIP712 typehash for the Proof type.
bytes32 public constant PROOF_TYPEHASH =
keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
/// @notice Struct that represents a proof that verifies the admin.
/// @custom:field recipient Address that will be receiving the faucet funds.
......@@ -30,11 +29,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 {
/// @param _admin Admin address that can sign off on drips.
/// @param _name Contract name.
/// @param _version The current major version of the signing domain.
constructor(
address _admin,
string memory _name,
string memory _version
) EIP712(_name, _version) {
constructor(address _admin, string memory _name, string memory _version) EIP712(_name, _version) {
ADMIN = _admin;
}
......@@ -43,13 +38,15 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 {
Faucet.DripParameters memory _params,
bytes32 _id,
bytes memory _proof
) external view returns (bool valid_) {
)
external
view
returns (bool valid_)
{
// Generate a EIP712 typed data hash to compare against the proof.
valid_ = SignatureChecker.isValidSignatureNow(
ADMIN,
_hashTypedDataV4(
keccak256(abi.encode(PROOF_TYPEHASH, _params.recipient, _params.nonce, _id))
),
_hashTypedDataV4(keccak256(abi.encode(PROOF_TYPEHASH, _params.recipient, _params.nonce, _id))),
_proof
);
}
......
......@@ -15,5 +15,8 @@ interface IFaucetAuthModule {
Faucet.DripParameters memory _params,
bytes32 _id,
bytes memory _proof
) external view returns (bool);
)
external
view
returns (bool);
}
......@@ -26,25 +26,16 @@ contract AttestationStation is Semver {
/// @param about Address attestation is about.
/// @param key Key of the attestation.
/// @param val Value of the attestation.
event AttestationCreated(
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
/// @custom:semver 1.1.1
constructor() Semver(1, 1, 1) {}
constructor() Semver(1, 1, 1) { }
/// @notice Allows anyone to create an attestation.
/// @param _about Address that the attestation is about.
/// @param _key A key used to namespace the attestation.
/// @param _val An arbitrary value stored as part of the attestation.
function attest(
address _about,
bytes32 _key,
bytes memory _val
) public {
function attest(address _about, bytes32 _key, bytes memory _val) public {
attestations[msg.sender][_about][_key] = _val;
emit AttestationCreated(msg.sender, _about, _key, _val);
......@@ -54,7 +45,7 @@ contract AttestationStation is Semver {
/// @param _attestations An array of AttestationData structs.
function attest(AttestationData[] calldata _attestations) external {
uint256 length = _attestations.length;
for (uint256 i = 0; i < length; ) {
for (uint256 i = 0; i < length;) {
AttestationData memory attestation = _attestations[i];
attest(attestation.about, attestation.key, attestation.val);
......
......@@ -2,9 +2,8 @@
pragma solidity 0.8.15;
import { Semver } from "../../universal/Semver.sol";
import {
ERC721BurnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
import { ERC721BurnableUpgradeable } from
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
import { AttestationStation } from "./AttestationStation.sol";
import { OptimistAllowlist } from "./OptimistAllowlist.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
......@@ -38,7 +37,9 @@ contract Optimist is ERC721BurnableUpgradeable, Semver {
address _baseURIAttestor,
AttestationStation _attestationStation,
OptimistAllowlist _optimistAllowlist
) Semver(2, 0, 1) {
)
Semver(2, 0, 1)
{
BASE_URI_ATTESTOR = _baseURIAttestor;
ATTESTATION_STATION = _attestationStation;
OPTIMIST_ALLOWLIST = _optimistAllowlist;
......@@ -67,11 +68,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver {
function baseURI() public view returns (string memory uri_) {
uri_ = string(
abi.encodePacked(
ATTESTATION_STATION.attestations(
BASE_URI_ATTESTOR,
address(this),
bytes32("optimist.base-uri")
)
ATTESTATION_STATION.attestations(BASE_URI_ATTESTOR, address(this), bytes32("optimist.base-uri"))
)
);
}
......@@ -120,11 +117,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver {
/// @notice Prevents transfers of the Optimist NFT (Soul Bound Token).
/// @param _from Address of the token sender.
/// @param _to Address of the token recipient.
function _beforeTokenTransfer(
address _from,
address _to,
uint256
) internal virtual override {
function _beforeTokenTransfer(address _from, address _to, uint256) internal virtual override {
require(_from == address(0) || _to == address(0), "Optimist: soul bound token");
}
}
......@@ -15,8 +15,7 @@ contract OptimistAllowlist is Semver {
bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32("optimist.can-mint");
/// @notice Attestation key used by Coinbase to issue attestations for Quest participants.
bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY =
bytes32("coinbase.quest-eligible");
bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY = bytes32("coinbase.quest-eligible");
/// @notice Address of the AttestationStation contract.
AttestationStation public immutable ATTESTATION_STATION;
......@@ -41,7 +40,9 @@ contract OptimistAllowlist is Semver {
address _allowlistAttestor,
address _coinbaseQuestAttestor,
address _optimistInviter
) Semver(1, 0, 1) {
)
Semver(1, 0, 1)
{
ATTESTATION_STATION = _attestationStation;
ALLOWLIST_ATTESTOR = _allowlistAttestor;
COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor;
......@@ -59,58 +60,34 @@ contract OptimistAllowlist is Semver {
/// @param _claimer Address to check.
/// @return allowed_ Whether or not the address is allowed to mint yet.
function isAllowedToMint(address _claimer) public view returns (bool allowed_) {
allowed_ =
_hasAttestationFromAllowlistAttestor(_claimer) ||
_hasAttestationFromCoinbaseQuestAttestor(_claimer) ||
_hasAttestationFromOptimistInviter(_claimer);
allowed_ = _hasAttestationFromAllowlistAttestor(_claimer) || _hasAttestationFromCoinbaseQuestAttestor(_claimer)
|| _hasAttestationFromOptimistInviter(_claimer);
}
/// @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the
/// allowlist attestor.
/// @param _claimer Address to check.
/// @return valid_ Whether or not the address has a valid attestation.
function _hasAttestationFromAllowlistAttestor(address _claimer)
internal
view
returns (bool valid_)
{
function _hasAttestationFromAllowlistAttestor(address _claimer) internal view returns (bool valid_) {
// Expected attestation value is bytes32("true")
valid_ = _hasValidAttestation(
ALLOWLIST_ATTESTOR,
_claimer,
OPTIMIST_CAN_MINT_ATTESTATION_KEY
);
valid_ = _hasValidAttestation(ALLOWLIST_ATTESTOR, _claimer, OPTIMIST_CAN_MINT_ATTESTATION_KEY);
}
/// @notice Checks whether an address has a valid attestation from the Coinbase attestor.
/// @param _claimer Address to check.
/// @return valid_ Whether or not the address has a valid attestation.
function _hasAttestationFromCoinbaseQuestAttestor(address _claimer)
internal
view
returns (bool valid_)
{
function _hasAttestationFromCoinbaseQuestAttestor(address _claimer) internal view returns (bool valid_) {
// Expected attestation value is bytes32("true")
valid_ = _hasValidAttestation(
COINBASE_QUEST_ATTESTOR,
_claimer,
COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY
);
valid_ = _hasValidAttestation(COINBASE_QUEST_ATTESTOR, _claimer, COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY);
}
/// @notice Checks whether an address has a valid attestation from the OptimistInviter contract.
/// @param _claimer Address to check.
/// @return valid_ Whether or not the address has a valid attestation.
function _hasAttestationFromOptimistInviter(address _claimer)
internal
view
returns (bool valid_)
{
function _hasAttestationFromOptimistInviter(address _claimer) internal view returns (bool valid_) {
// Expected attestation value is the inviter's address
valid_ = _hasValidAttestation(
OPTIMIST_INVITER,
_claimer,
OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
OPTIMIST_INVITER, _claimer, OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
);
}
......@@ -120,11 +97,7 @@ contract OptimistAllowlist is Semver {
/// @param _about Address attestation is about.
/// @param _key Key of the attestation.
/// @return valid_ Whether or not the address has a valid truthy attestation.
function _hasValidAttestation(
address _creator,
address _about,
bytes32 _key
) internal view returns (bool valid_) {
function _hasValidAttestation(address _creator, address _about, bytes32 _key) internal view returns (bool valid_) {
valid_ = ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0;
}
}
......@@ -5,9 +5,7 @@ import { OptimistConstants } from "./libraries/OptimistConstants.sol";
import { Semver } from "../../universal/Semver.sol";
import { AttestationStation } from "./AttestationStation.sol";
import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import {
EIP712Upgradeable
} from "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol";
import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol";
/// @custom:upgradeable
/// @title OptimistInviter
......@@ -47,8 +45,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
string public constant EIP712_VERSION = "1.0.0";
/// @notice EIP712 typehash for the ClaimableInvite type.
bytes32 public constant CLAIMABLE_INVITE_TYPEHASH =
keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
/// @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");
......@@ -113,17 +110,13 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
/// @param _inviteCount Number of invites to set to.
function setInviteCounts(address[] calldata _accounts, uint256 _inviteCount) public {
// Only invite granter can grant invites
require(
msg.sender == INVITE_GRANTER,
"OptimistInviter: only invite granter can grant invites"
);
require(msg.sender == INVITE_GRANTER, "OptimistInviter: only invite granter can grant invites");
uint256 length = _accounts.length;
AttestationStation.AttestationData[]
memory attestations = new AttestationStation.AttestationData[](length);
AttestationStation.AttestationData[] memory attestations = new AttestationStation.AttestationData[](length);
for (uint256 i; i < length; ) {
for (uint256 i; i < length;) {
// Set invite count for account to _inviteCount
inviteCounts[_accounts[i]] = _inviteCount;
......@@ -179,20 +172,11 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
/// @param _claimer Address that will be granted the invite.
/// @param _claimableInvite ClaimableInvite struct containing the issuer and nonce.
/// @param _signature Signature signed over the claimable invite.
function claimInvite(
address _claimer,
ClaimableInvite calldata _claimableInvite,
bytes memory _signature
) public {
uint256 commitmentTimestamp = commitmentTimestamps[
keccak256(abi.encode(_claimer, _signature))
];
function claimInvite(address _claimer, ClaimableInvite calldata _claimableInvite, bytes memory _signature) public {
uint256 commitmentTimestamp = commitmentTimestamps[keccak256(abi.encode(_claimer, _signature))];
// Make sure the claimer and signature have been committed.
require(
commitmentTimestamp > 0,
"OptimistInviter: claimer and signature have not been committed yet"
);
require(commitmentTimestamp > 0, "OptimistInviter: claimer and signature have not been committed yet");
// Check that MIN_COMMITMENT_PERIOD has passed since the commitment was made.
require(
......@@ -202,13 +186,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
// Generate a EIP712 typed data hash to compare against the signature.
bytes32 digest = _hashTypedDataV4(
keccak256(
abi.encode(
CLAIMABLE_INVITE_TYPEHASH,
_claimableInvite.issuer,
_claimableInvite.nonce
)
)
keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce))
);
// Uses SignatureChecker, which supports both regular ECDSA signatures from EOAs as well as
......@@ -233,10 +211,7 @@ contract OptimistInviter is Semver, EIP712Upgradeable {
usedNonces[_claimableInvite.issuer][_claimableInvite.nonce] = true;
// Failing this check means that the issuer has used up all of their existing invites.
require(
inviteCounts[_claimableInvite.issuer] > 0,
"OptimistInviter: issuer has no invites"
);
require(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
// count is > 0.
......
......@@ -5,6 +5,5 @@ pragma solidity 0.8.15;
/// @notice Library for storing Optimist related constants that are shared in multiple contracts.
library OptimistConstants {
/// @notice Attestation key issued by OptimistInviter allowing the attested account to mint.
bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =
bytes32("optimist.can-mint-from-invite");
bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY = bytes32("optimist.can-mint-from-invite");
}
......@@ -149,13 +149,7 @@ abstract contract CrossDomainMessenger is
/// @param message Message to trigger the recipient address with.
/// @param messageNonce Unique nonce attached to the message.
/// @param gasLimit Minimum gas limit that the message can be executed with.
event SentMessage(
address indexed target,
address sender,
bytes message,
uint256 messageNonce,
uint256 gasLimit
);
event SentMessage(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
/// SentMessage event without breaking the ABI of this contract, this is good enough.
......@@ -183,11 +177,7 @@ abstract contract CrossDomainMessenger is
/// @param _target Target contract or wallet address.
/// @param _message Message to trigger the target address with.
/// @param _minGasLimit Minimum gas limit that the message can be executed with.
function sendMessage(
address _target,
bytes calldata _message,
uint32 _minGasLimit
) external payable {
function sendMessage(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
// 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
......@@ -197,13 +187,7 @@ abstract contract CrossDomainMessenger is
baseGas(_message, _minGasLimit),
msg.value,
abi.encodeWithSelector(
this.relayMessage.selector,
messageNonce(),
msg.sender,
_target,
msg.value,
_minGasLimit,
_message
this.relayMessage.selector, messageNonce(), msg.sender, _target, msg.value, _minGasLimit, _message
)
);
......@@ -231,33 +215,24 @@ abstract contract CrossDomainMessenger is
uint256 _value,
uint256 _minGasLimit,
bytes calldata _message
) external payable {
)
external
payable
{
(, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
require(
version < 2,
"CrossDomainMessenger: only version 0 or 1 messages are supported at this time"
);
require(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
// to check that the legacy version of the message has not already been relayed.
if (version == 0) {
bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);
require(
successfulMessages[oldHash] == false,
"CrossDomainMessenger: legacy withdrawal already relayed"
);
require(successfulMessages[oldHash] == false, "CrossDomainMessenger: legacy withdrawal already relayed");
}
// 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.
bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(
_nonce,
_sender,
_target,
_value,
_minGasLimit,
_message
);
bytes32 versionedHash =
Hashing.hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _minGasLimit, _message);
if (_isOtherMessenger()) {
// These properties should always hold when the message is first submitted (as
......@@ -265,26 +240,16 @@ abstract contract CrossDomainMessenger is
assert(msg.value == _value);
assert(!failedMessages[versionedHash]);
} else {
require(
msg.value == 0,
"CrossDomainMessenger: value must be zero unless message is from a system address"
);
require(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(
_isUnsafeTarget(_target) == false,
"CrossDomainMessenger: cannot send message to blocked system address"
_isUnsafeTarget(_target) == false, "CrossDomainMessenger: cannot send message to blocked system address"
);
require(
successfulMessages[versionedHash] == false,
"CrossDomainMessenger: message has already been relayed"
);
require(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,
// return early and assign the message to the failedMessages mapping.
......@@ -296,8 +261,8 @@ abstract contract CrossDomainMessenger is
// 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.
if (
!SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) ||
xDomainMsgSender != Constants.DEFAULT_L2_SENDER
!SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER)
|| xDomainMsgSender != Constants.DEFAULT_L2_SENDER
) {
failedMessages[versionedHash] = true;
emit FailedRelayedMessage(versionedHash);
......@@ -342,8 +307,7 @@ abstract contract CrossDomainMessenger is
/// @return Address of the sender of the currently executing message on the other chain.
function xDomainMessageSender() external view returns (address) {
require(
xDomainMsgSender != Constants.DEFAULT_L2_SENDER,
"CrossDomainMessenger: xDomainMessageSender is not set"
xDomainMsgSender != Constants.DEFAULT_L2_SENDER, "CrossDomainMessenger: xDomainMessageSender is not set"
);
return xDomainMsgSender;
......@@ -367,21 +331,20 @@ abstract contract CrossDomainMessenger is
function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {
return
// Constant overhead
RELAY_CONSTANT_OVERHEAD +
RELAY_CONSTANT_OVERHEAD
// Calldata overhead
(uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +
+ (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD)
// Dynamic overhead (EIP-150)
((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /
MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +
+ ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) / MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR)
// Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas
// factors. (Conservative)
RELAY_CALL_OVERHEAD +
+ RELAY_CALL_OVERHEAD
// Relay reserved gas (to ensure execution of `relayMessage` completes after the
// subcontext finishes executing) (Conservative)
RELAY_RESERVED_GAS +
+ RELAY_RESERVED_GAS
// Gas reserved for the execution between the `hasMinGas` check and the `CALL`
// opcode. (Conservative)
RELAY_GAS_CHECK_BUFFER;
+ RELAY_GAS_CHECK_BUFFER;
}
/// @notice Initializer.
......@@ -397,12 +360,7 @@ abstract contract CrossDomainMessenger is
/// @param _gasLimit Minimum gas limit the message can be executed with.
/// @param _value Amount of ETH to send with the message.
/// @param _data Message data.
function _sendMessage(
address _to,
uint64 _gasLimit,
uint256 _value,
bytes memory _data
) internal virtual;
function _sendMessage(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
/// contracts because the logic for this depends on the network where the messenger is
......
......@@ -106,7 +106,9 @@ abstract contract ERC721Bridge is Initializable {
uint256 _tokenId,
uint32 _minGasLimit,
bytes calldata _extraData
) external {
)
external
{
// 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
// (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 {
// care of the user error we want to avoid.
require(!Address.isContract(msg.sender), "ERC721Bridge: account is not externally owned");
_initiateBridgeERC721(
_localToken,
_remoteToken,
msg.sender,
msg.sender,
_tokenId,
_minGasLimit,
_extraData
);
_initiateBridgeERC721(_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
......@@ -148,18 +142,12 @@ abstract contract ERC721Bridge is Initializable {
uint256 _tokenId,
uint32 _minGasLimit,
bytes calldata _extraData
) external {
)
external
{
require(_to != address(0), "ERC721Bridge: nft recipient cannot be address(0)");
_initiateBridgeERC721(
_localToken,
_remoteToken,
msg.sender,
_to,
_tokenId,
_minGasLimit,
_extraData
);
_initiateBridgeERC721(_localToken, _remoteToken, msg.sender, _to, _tokenId, _minGasLimit, _extraData);
}
/// @notice Internal function for initiating a token bridge to the other domain.
......@@ -180,5 +168,7 @@ abstract contract ERC721Bridge is Initializable {
uint256 _tokenId,
uint32 _minGasLimit,
bytes calldata _extraData
) internal virtual;
)
internal
virtual;
}
......@@ -48,18 +48,14 @@ abstract contract FeeVault {
/// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
) {
constructor(address _recipient, uint256 _minWithdrawalAmount, WithdrawalNetwork _withdrawalNetwork) {
RECIPIENT = _recipient;
MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;
WITHDRAWAL_NETWORK = _withdrawalNetwork;
}
/// @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.
function withdraw() external {
......@@ -75,13 +71,11 @@ abstract contract FeeVault {
emit Withdrawal(value, RECIPIENT, msg.sender, WITHDRAWAL_NETWORK);
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");
} else {
L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(
RECIPIENT,
WITHDRAWAL_MIN_GAS,
bytes("")
RECIPIENT, WITHDRAWAL_MIN_GAS, bytes("")
);
}
}
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {
IERC721Enumerable
} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
/// @title IOptimismMintableERC721
/// @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.
......
......@@ -45,7 +45,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20,
address _remoteToken,
string memory _name,
string memory _symbol
) ERC20(_name, _symbol) Semver(1, 0, 2) {
)
ERC20(_name, _symbol)
Semver(1, 0, 2)
{
REMOTE_TOKEN = _remoteToken;
BRIDGE = _bridge;
}
......@@ -53,7 +56,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20,
/// @notice Allows the StandardBridge on this network to mint tokens.
/// @param _to Address to mint tokens to.
/// @param _amount Amount of tokens to mint.
function mint(address _to, uint256 _amount)
function mint(
address _to,
uint256 _amount
)
external
virtual
override(IOptimismMintableERC20, ILegacyMintableERC20)
......@@ -66,7 +72,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20,
/// @notice Allows the StandardBridge on this network to burn tokens.
/// @param _from Address to burn tokens from.
/// @param _amount Amount of tokens to burn.
function burn(address _from, uint256 _amount)
function burn(
address _from,
uint256 _amount
)
external
virtual
override(IOptimismMintableERC20, ILegacyMintableERC20)
......
......@@ -26,11 +26,7 @@ contract OptimismMintableERC20Factory is Semver {
/// @param localToken Address of the created token on the local chain.
/// @param remoteToken Address of the corresponding token on the remote chain.
/// @param deployer Address of the account that deployed the token.
event OptimismMintableERC20Created(
address indexed localToken,
address indexed remoteToken,
address deployer
);
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
/// @custom:semver 1.1.1
/// @notice The semver MUST be bumped any time that there is a change in
......@@ -52,7 +48,10 @@ contract OptimismMintableERC20Factory is Semver {
address _remoteToken,
string memory _name,
string memory _symbol
) external returns (address) {
)
external
returns (address)
{
return createOptimismMintableERC20(_remoteToken, _name, _symbol);
}
......@@ -65,15 +64,13 @@ contract OptimismMintableERC20Factory is Semver {
address _remoteToken,
string memory _name,
string memory _symbol
) public returns (address) {
require(
_remoteToken != address(0),
"OptimismMintableERC20Factory: must provide remote token address"
);
)
public
returns (address)
{
require(_remoteToken != address(0), "OptimismMintableERC20Factory: must provide remote token address");
address localToken = address(
new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)
);
address localToken = address(new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol));
// Emit the old event too for legacy support.
emit StandardL2TokenCreated(_remoteToken, localToken);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {
ERC721Enumerable
} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
......@@ -45,13 +43,13 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Se
address _remoteToken,
string memory _name,
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(_remoteChainId != 0, "OptimismMintableERC721: remote chain id cannot be zero");
require(
_remoteToken != address(0),
"OptimismMintableERC721: remote token cannot be address(0)"
);
require(_remoteToken != address(0), "OptimismMintableERC721: remote token cannot be address(0)");
REMOTE_CHAIN_ID = _remoteChainId;
REMOTE_TOKEN = _remoteToken;
......@@ -102,12 +100,7 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Se
/// @notice Checks if a given interface ID is supported by this contract.
/// @param _interfaceId The interface ID to check.
/// @return True if the interface ID is supported, false otherwise.
function supportsInterface(bytes4 _interfaceId)
public
view
override(ERC721Enumerable, IERC165)
returns (bool)
{
function supportsInterface(bytes4 _interfaceId) public view override(ERC721Enumerable, IERC165) returns (bool) {
bytes4 iface = type(IOptimismMintableERC721).interfaceId;
return _interfaceId == iface || super.supportsInterface(_interfaceId);
}
......
......@@ -20,11 +20,7 @@ contract OptimismMintableERC721Factory is Semver {
/// @param localToken Address of the token on the this domain.
/// @param remoteToken Address of the token on the remote domain.
/// @param deployer Address of the initiator of the deployment
event OptimismMintableERC721Created(
address indexed localToken,
address indexed remoteToken,
address deployer
);
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
/// @custom:semver 1.2.1
/// @notice The semver MUST be bumped any time that there is a change in
......@@ -45,15 +41,13 @@ contract OptimismMintableERC721Factory is Semver {
address _remoteToken,
string memory _name,
string memory _symbol
) external returns (address) {
require(
_remoteToken != address(0),
"OptimismMintableERC721Factory: L1 token address cannot be address(0)"
);
address localToken = address(
new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)
);
)
external
returns (address)
{
require(_remoteToken != address(0), "OptimismMintableERC721Factory: L1 token address cannot be address(0)");
address localToken = address(new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol));
isOptimismMintableERC721[localToken] = true;
emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);
......
......@@ -8,13 +8,11 @@ pragma solidity 0.8.15;
contract Proxy {
/// @notice The storage slot that holds the address of the implementation.
/// 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.
/// bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
bytes32 internal constant OWNER_KEY =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
bytes32 internal constant OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/// @notice An event that is emitted each time the implementation is changed. This event is part
/// of the EIP-1967 specification.
......@@ -72,7 +70,10 @@ contract Proxy {
/// atomic execution of initialization-based upgrades.
/// @param _implementation Address of the implementation contract.
/// @param _data Calldata to delegatecall the new implementation with.
function upgradeToAndCall(address _implementation, bytes calldata _data)
function upgradeToAndCall(
address _implementation,
bytes calldata _data
)
public
payable
virtual
......@@ -140,9 +141,7 @@ contract Proxy {
returndatacopy(0x0, 0x0, returndatasize())
// Success == 0 means a revert. We'll revert too and pass the data up.
if iszero(success) {
revert(0x0, returndatasize())
}
if iszero(success) { revert(0x0, returndatasize()) }
// Otherwise we'll just return and pass the data up.
return(0x0, returndatasize())
......
......@@ -186,14 +186,18 @@ contract ProxyAdmin is Ownable {
address payable _proxy,
address _implementation,
bytes memory _data
) external payable onlyOwner {
)
external
payable
onlyOwner
{
ProxyType ptype = proxyType[_proxy];
if (ptype == ProxyType.ERC1967) {
Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);
} else {
// reverts if proxy type is unknown
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");
}
}
......
......@@ -18,11 +18,7 @@ contract Semver {
/// @param _major Version number (major).
/// @param _minor Version number (minor).
/// @param _patch Version number (patch).
constructor(
uint256 _major,
uint256 _minor,
uint256 _patch
) {
constructor(uint256 _major, uint256 _minor, uint256 _patch) {
MAJOR_VERSION = _major;
MINOR_VERSION = _minor;
PATCH_VERSION = _patch;
......@@ -31,8 +27,7 @@ contract Semver {
/// @notice Returns the full semver contract version.
/// @return Semver contract version as a string.
function version() public view returns (string memory) {
return
string(
return string(
abi.encodePacked(
Strings.toString(MAJOR_VERSION),
".",
......
......@@ -56,24 +56,14 @@ abstract contract StandardBridge is Initializable {
/// @param to Address of the receiver.
/// @param amount Amount of ETH sent.
/// @param extraData Extra data sent with the transaction.
event ETHBridgeInitiated(
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
/// @notice Emitted when an ETH bridge is finalized on this chain.
/// @param from Address of the sender.
/// @param to Address of the receiver.
/// @param amount Amount of ETH sent.
/// @param extraData Extra data sent with the transaction.
event ETHBridgeFinalized(
address indexed from,
address indexed to,
uint256 amount,
bytes extraData
);
event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
/// @notice Emitted when an ERC20 bridge is initiated to the other chain.
/// @param localToken Address of the ERC20 on this chain.
......@@ -111,18 +101,14 @@ abstract contract StandardBridge is Initializable {
/// 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.
modifier onlyEOA() {
require(
!Address.isContract(msg.sender),
"StandardBridge: function can only be called from an EOA"
);
require(!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.
modifier onlyOtherBridge() {
require(
msg.sender == address(messenger) &&
messenger.xDomainMessageSender() == address(OTHER_BRIDGE),
msg.sender == address(messenger) && messenger.xDomainMessageSender() == address(OTHER_BRIDGE),
"StandardBridge: function can only be called from the other bridge"
);
_;
......@@ -177,11 +163,7 @@ abstract contract StandardBridge is Initializable {
/// @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
/// to identify the transaction.
function bridgeETHTo(
address _to,
uint32 _minGasLimit,
bytes calldata _extraData
) public payable {
function bridgeETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) public payable {
_initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);
}
......@@ -202,16 +184,12 @@ abstract contract StandardBridge is Initializable {
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) public virtual onlyEOA {
_initiateBridgeERC20(
_localToken,
_remoteToken,
msg.sender,
msg.sender,
_amount,
_minGasLimit,
_extraData
);
)
public
virtual
onlyEOA
{
_initiateBridgeERC20(_localToken, _remoteToken, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
}
/// @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 {
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) public virtual {
_initiateBridgeERC20(
_localToken,
_remoteToken,
msg.sender,
_to,
_amount,
_minGasLimit,
_extraData
);
)
public
virtual
{
_initiateBridgeERC20(_localToken, _remoteToken, msg.sender, _to, _amount, _minGasLimit, _extraData);
}
/// @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other
......@@ -258,7 +231,11 @@ abstract contract StandardBridge is Initializable {
address _to,
uint256 _amount,
bytes calldata _extraData
) public payable onlyOtherBridge {
)
public
payable
onlyOtherBridge
{
require(msg.value == _amount, "StandardBridge: amount sent does not match amount required");
require(_to != address(this), "StandardBridge: cannot send to self");
require(_to != address(messenger), "StandardBridge: cannot send to messenger");
......@@ -288,7 +265,10 @@ abstract contract StandardBridge is Initializable {
address _to,
uint256 _amount,
bytes calldata _extraData
) public onlyOtherBridge {
)
public
onlyOtherBridge
{
if (_isOptimismMintableERC20(_localToken)) {
require(
_isCorrectTokenPair(_localToken, _remoteToken),
......@@ -320,11 +300,10 @@ abstract contract StandardBridge is Initializable {
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
require(
msg.value == _amount,
"StandardBridge: bridging ETH must include sufficient ETH value"
);
)
internal
{
require(msg.value == _amount, "StandardBridge: bridging ETH must include sufficient ETH value");
// 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.
......@@ -332,13 +311,7 @@ abstract contract StandardBridge is Initializable {
messenger.sendMessage{ value: _amount }(
address(OTHER_BRIDGE),
abi.encodeWithSelector(
this.finalizeBridgeETH.selector,
_from,
_to,
_amount,
_extraData
),
abi.encodeWithSelector(this.finalizeBridgeETH.selector, _from, _to, _amount, _extraData),
_minGasLimit
);
}
......@@ -360,7 +333,9 @@ abstract contract StandardBridge is Initializable {
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
)
internal
{
if (_isOptimismMintableERC20(_localToken)) {
require(
_isCorrectTokenPair(_localToken, _remoteToken),
......@@ -400,9 +375,8 @@ abstract contract StandardBridge is Initializable {
/// @param _token Address of the token to check.
/// @return True if the token is an OptimismMintableERC20.
function _isOptimismMintableERC20(address _token) internal view returns (bool) {
return
ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||
ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);
return ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId)
|| ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);
}
/// @notice Checks if the "other token" is the correct pair token for the OptimismMintableERC20.
......@@ -411,14 +385,8 @@ abstract contract StandardBridge is Initializable {
/// @param _mintableToken OptimismMintableERC20 to check against.
/// @param _otherToken Pair token to check.
/// @return True if the other token is the correct pair token for the OptimismMintableERC20.
function _isCorrectTokenPair(address _mintableToken, address _otherToken)
internal
view
returns (bool)
{
if (
ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)
) {
function _isCorrectTokenPair(address _mintableToken, address _otherToken) internal view returns (bool) {
if (ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)) {
return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();
} else {
return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();
......@@ -436,7 +404,10 @@ abstract contract StandardBridge is Initializable {
address _to,
uint256 _amount,
bytes memory _extraData
) internal virtual {
)
internal
virtual
{
emit ETHBridgeInitiated(_from, _to, _amount, _extraData);
}
......@@ -451,7 +422,10 @@ abstract contract StandardBridge is Initializable {
address _to,
uint256 _amount,
bytes memory _extraData
) internal virtual {
)
internal
virtual
{
emit ETHBridgeFinalized(_from, _to, _amount, _extraData);
}
......@@ -470,7 +444,10 @@ abstract contract StandardBridge is Initializable {
address _to,
uint256 _amount,
bytes memory _extraData
) internal virtual {
)
internal
virtual
{
emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
......@@ -489,7 +466,10 @@ abstract contract StandardBridge is Initializable {
address _to,
uint256 _amount,
bytes memory _extraData
) internal virtual {
)
internal
virtual
{
emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
}
......@@ -20,49 +20,48 @@ contract WETH9 {
string public symbol = "WETH";
uint8 public decimals = 18;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
event Deposit(address indexed dst, uint wad);
event Withdrawal(address indexed src, uint wad);
event Approval(address indexed src, address indexed guy, uint256 wad);
event Transfer(address indexed src, address indexed dst, uint256 wad);
event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint256 wad);
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
function() external payable {
deposit();
}
function deposit() public payable {
balanceOf[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);
balanceOf[msg.sender] -= wad;
msg.sender.transfer(wad);
emit Withdrawal(msg.sender, wad);
}
function totalSupply() public view returns (uint) {
function totalSupply() public view returns (uint256) {
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;
emit Approval(msg.sender, guy, wad);
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);
}
function transferFrom(address src, address dst, uint wad)
public
returns (bool)
{
function transferFrom(address src, address dst, uint256 wad) public returns (bool) {
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);
allowance[src][msg.sender] -= wad;
}
......@@ -76,7 +75,6 @@ contract WETH9 {
}
}
/*
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
......
......@@ -45,11 +45,7 @@ contract AdminFaucetAuthModuleTest is Test {
}
/// @notice Get signature as a bytes blob.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest)
internal
pure
returns (bytes memory)
{
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v);
......@@ -68,21 +64,16 @@ contract AdminFaucetAuthModuleTest is Test {
address recipient,
bytes32 id,
bytes32 nonce
) internal view returns (bytes memory) {
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(
recipient,
nonce,
id
);
return
_getSignature(
)
internal
view
returns (bytes memory)
{
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(recipient, nonce, id);
return _getSignature(
_issuerPrivateKey,
faucetHelper.getDigestWithEIP712Domain(
proof,
_eip712Name,
_contractVersion,
_eip712Chainid,
_eip712VerifyingContract
proof, _eip712Name, _contractVersion, _eip712Chainid, _eip712VerifyingContract
)
);
}
......@@ -105,9 +96,7 @@ contract AdminFaucetAuthModuleTest is Test {
vm.prank(nonAdmin);
assertEq(
adminFam.verify(
Faucet.DripParameters(payable(fundsReceiver), nonce),
keccak256(abi.encodePacked(fundsReceiver)),
proof
Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(fundsReceiver)), proof
),
true
);
......@@ -131,9 +120,7 @@ contract AdminFaucetAuthModuleTest is Test {
vm.prank(admin);
assertEq(
adminFam.verify(
Faucet.DripParameters(payable(fundsReceiver), nonce),
keccak256(abi.encodePacked(fundsReceiver)),
proof
Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(fundsReceiver)), proof
),
false
);
......@@ -159,9 +146,7 @@ contract AdminFaucetAuthModuleTest is Test {
vm.prank(admin);
assertEq(
adminFam.verify(
Faucet.DripParameters(payable(fundsReceiver), nonce),
keccak256(abi.encodePacked(randomAddress)),
proof
Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(randomAddress)), proof
),
false
);
......
......@@ -19,18 +19,8 @@ contract AssetReceiver_Initializer is Test {
event ReceivedETH(address indexed from, uint256 amount);
event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);
event WithdrewERC20(
address indexed withdrawer,
address indexed recipient,
address indexed asset,
uint256 amount
);
event WithdrewERC721(
address indexed withdrawer,
address indexed recipient,
address indexed asset,
uint256 id
);
event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount);
event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id);
function setUp() public {
// Deploy ERC20 and ERC721 tokens
......@@ -67,7 +57,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
emit ReceivedETH(alice, 100);
// Send funds
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
assertTrue(success);
......
......@@ -21,12 +21,7 @@ contract AttestationStation_Initializer is Test {
}
contract AttestationStationTest is AttestationStation_Initializer {
event AttestationCreated(
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
function test_attest_individual_succeeds() external {
AttestationStation attestationStation = new AttestationStation();
......@@ -41,26 +36,17 @@ contract AttestationStationTest is AttestationStation_Initializer {
function test_attest_single_succeeds() external {
AttestationStation attestationStation = new AttestationStation();
AttestationStation.AttestationData[]
memory attestationDataArr = new AttestationStation.AttestationData[](1);
AttestationStation.AttestationData[] memory attestationDataArr = new AttestationStation.AttestationData[](1);
// alice is going to attest about bob
AttestationStation.AttestationData memory attestationData = AttestationStation
.AttestationData({
AttestationStation.AttestationData memory attestationData = AttestationStation.AttestationData({
about: bob,
key: bytes32("test-key:string"),
val: bytes("test-value")
});
// assert the attestation starts empty
assertEq(
attestationStation.attestations(
alice_attestor,
attestationData.about,
attestationData.key
),
""
);
assertEq(attestationStation.attestations(alice_attestor, attestationData.about, attestationData.key), "");
// make attestation
vm.prank(alice_attestor);
......@@ -69,21 +55,14 @@ contract AttestationStationTest is AttestationStation_Initializer {
// assert the attestation is there
assertEq(
attestationStation.attestations(
alice_attestor,
attestationData.about,
attestationData.key
),
attestationStation.attestations(alice_attestor, attestationData.about, attestationData.key),
attestationData.val
);
bytes memory new_val = bytes("new updated value");
// make a new attestations to same about and key
attestationData = AttestationStation.AttestationData({
about: attestationData.about,
key: attestationData.key,
val: new_val
});
attestationData =
AttestationStation.AttestationData({ about: attestationData.about, key: attestationData.key, val: new_val });
vm.prank(alice_attestor);
attestationDataArr[0] = attestationData;
......@@ -91,11 +70,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
// assert the attestation is updated
assertEq(
attestationStation.attestations(
alice_attestor,
attestationData.about,
attestationData.key
),
attestationStation.attestations(alice_attestor, attestationData.about, attestationData.key),
attestationData.val
);
}
......@@ -105,19 +80,15 @@ contract AttestationStationTest is AttestationStation_Initializer {
vm.prank(alice_attestor);
AttestationStation.AttestationData[]
memory attestationData = new AttestationStation.AttestationData[](3);
AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](3);
attestationData[0] = AttestationStation.AttestationData({
about: bob,
key: bytes32("test-key:string"),
val: bytes("test-value")
});
attestationData[1] = AttestationStation.AttestationData({
about: bob,
key: bytes32("test-key2"),
val: bytes("test-value2")
});
attestationData[1] =
AttestationStation.AttestationData({ about: bob, key: bytes32("test-key2"), val: bytes("test-value2") });
attestationData[2] = AttestationStation.AttestationData({
about: sally,
......@@ -129,27 +100,15 @@ contract AttestationStationTest is AttestationStation_Initializer {
// assert the attestations are there
assertEq(
attestationStation.attestations(
alice_attestor,
attestationData[0].about,
attestationData[0].key
),
attestationStation.attestations(alice_attestor, attestationData[0].about, attestationData[0].key),
attestationData[0].val
);
assertEq(
attestationStation.attestations(
alice_attestor,
attestationData[1].about,
attestationData[1].key
),
attestationStation.attestations(alice_attestor, attestationData[1].about, attestationData[1].key),
attestationData[1].val
);
assertEq(
attestationStation.attestations(
alice_attestor,
attestationData[2].about,
attestationData[2].key
),
attestationStation.attestations(alice_attestor, attestationData[2].about, attestationData[2].key),
attestationData[2].val
);
}
......
......@@ -9,18 +9,14 @@ import { CrossDomainMessenger } from "../src/universal/CrossDomainMessenger.sol"
import { ResourceMetering } from "../src/L1/ResourceMetering.sol";
// Free function for setting the prevBaseFee param in the OptimismPortal.
function setPrevBaseFee(
Vm _vm,
address _op,
uint128 _prevBaseFee
) {
function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) {
_vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));
}
contract SetPrevBaseFee_Test is Portal_Initializer {
function test_setPrevBaseFee_succeeds() external {
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(prevBlockNum), block.number);
}
......@@ -56,8 +52,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
// Get withdrawal proof data we can use for testing.
bytes32 _storageRoot;
bytes32 _stateRoot;
(_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi
.getProveWithdrawalTransactionInputs(_defaultTx);
(_stateRoot, _storageRoot, _outputRoot,, _withdrawalProof) = ffi.getProveWithdrawalTransactionInputs(_defaultTx);
// Setup a dummy output root proof for reuse.
_outputRootProof = Types.OutputRootProof({
......@@ -78,11 +73,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed.
vm.warp(
oracle.getL2Output(_proposedOutputIndex).timestamp +
oracle.FINALIZATION_PERIOD_SECONDS() +
1
);
vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF);
......@@ -90,32 +81,19 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
function test_depositTransaction_benchmark() external {
op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
);
}
function test_depositTransaction_benchmark_1() external {
setPrevBaseFee(vm, address(op), 1 gwei);
op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
);
}
function test_proveWithdrawalTransaction_benchmark() external {
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
}
}
......@@ -124,8 +102,8 @@ contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {
vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 1 gwei);
// The amount of data typically sent during a bridge deposit.
bytes
memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
bytes memory data =
hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
vm.resumeGasMetering();
L1Messenger.sendMessage(bob, data, uint32(100));
}
......@@ -134,8 +112,8 @@ contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {
vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 10 gwei);
// The amount of data typically sent during a bridge deposit.
bytes
memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
bytes memory data =
hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
vm.resumeGasMetering();
L1Messenger.sendMessage(bob, data, uint32(100));
}
......
......@@ -10,11 +10,7 @@ contract BlockOracle_Test is Test {
BlockOracle oracle;
/// @notice Emitted when a block is checkpointed.
event Checkpoint(
uint256 indexed blockNumber,
Hash indexed blockHash,
Timestamp indexed childTimestamp
);
event Checkpoint(uint256 indexed blockNumber, Hash indexed blockHash, Timestamp indexed childTimestamp);
function setUp() public {
oracle = new BlockOracle();
......@@ -27,9 +23,7 @@ contract BlockOracle_Test is Test {
function test_checkpointAndLoad_succeeds() public {
vm.expectEmit(true, true, true, false);
emit Checkpoint(
block.number - 1,
Hash.wrap(blockhash(block.number - 1)),
Timestamp.wrap(uint64(block.timestamp))
block.number - 1, Hash.wrap(blockhash(block.number - 1)), Timestamp.wrap(uint64(block.timestamp))
);
oracle.checkpoint();
uint256 blockNumber = block.number - 1;
......
......@@ -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
/// first word and the 1st byte of the second word is correct.
function test_slice_acrossWords_works() public {
bytes
memory input = hex"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000";
bytes memory input =
hex"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000";
assertEq(Bytes.slice(input, 31, 2), hex"1122");
}
......@@ -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
/// returns the correct result.
function test_slice_acrossMultipleWords_works() public {
bytes
memory input = hex"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000";
bytes
memory expected = hex"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11";
bytes memory input =
hex"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000";
bytes memory expected = hex"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11";
assertEq(Bytes.slice(input, 31, 34), expected);
}
/// @notice Tests that the `slice` function correctly updates the free memory pointer depending
/// on the length of the slice.
function testFuzz_slice_memorySafety_succeeds(
bytes memory _input,
uint256 _start,
uint256 _length
) public {
function testFuzz_slice_memorySafety_succeeds(bytes memory _input, uint256 _start, uint256 _length) public {
// The start should never be more than the length of the input bytes array - 1
vm.assume(_start < _input.length);
// 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 {
contract Bytes_slice_TestFail is Test {
/// @notice Tests that, when given an input bytes array of length `n`, the `slice` function will
/// always revert if `_start + _length > n`.
function testFuzz_slice_outOfBounds_reverts(
bytes memory _input,
uint256 _start,
uint256 _length
) public {
function testFuzz_slice_outOfBounds_reverts(bytes memory _input, uint256 _start, uint256 _length) public {
// We want a valid start index and a length that will not overflow.
vm.assume(_start < _input.length && _length < type(uint256).max - 31);
// But, we want an invalid slice length.
......@@ -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`,
/// the `slice` function reverts.
function testFuzz_slice_lengthOverflows_reverts(
bytes memory _input,
uint256 _start,
uint256 _length
) public {
function testFuzz_slice_lengthOverflows_reverts(bytes memory _input, uint256 _start, uint256 _length) public {
// Ensure that the `_length` will overflow if a number >= 31 is added to it.
vm.assume(_length > type(uint256).max - 31);
......@@ -155,11 +142,7 @@ contract Bytes_slice_TestFail is Test {
/// @notice Tests that, when given a start index `n` that is greater than
/// `type(uint256).max - n`, the `slice` function reverts.
function testFuzz_slice_rangeOverflows_reverts(
bytes memory _input,
uint256 _start,
uint256 _length
) public {
function testFuzz_slice_rangeOverflows_reverts(bytes memory _input, uint256 _start, uint256 _length) public {
// Ensure that `_length` is a realistic length of a slice. This is to make sure
// we revert on the correct require statement.
vm.assume(_length < _input.length);
......@@ -188,10 +171,10 @@ contract Bytes_toNibbles_Test is Test {
/// of 256 nibbles corresponding to the input data. This test exists to ensure that,
/// given a large input, the `toNibbles` function works as expected.
function test_toNibbles_expectedResult128Bytes_works() public {
bytes
memory input = hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f";
bytes
memory expected = hex"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f";
bytes memory input =
hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f";
bytes memory expected =
hex"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f";
bytes memory actual = Bytes.toNibbles(input);
assertEq(input.length * 2, actual.length);
......@@ -265,7 +248,8 @@ contract Bytes_equal_Test is Test {
function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {
bool _eq;
assembly {
_eq := and(
_eq :=
and(
// Check if the contents of the two bytes arrays are equal in memory.
eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),
// Check if the length of the two bytes arrays are equal in memory.
......
......@@ -19,10 +19,7 @@ contract CheckBalanceHighTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns true
/// when the target's balance is larger than the threshold.
function testFuzz_check_succeeds(address _target, uint256 _threshold) external {
CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({
target: _target,
threshold: _threshold
});
CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold });
// prevent overflows
vm.assume(_threshold != type(uint256).max);
......@@ -34,10 +31,7 @@ contract CheckBalanceHighTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns false
/// when the target's balance is smaller than the threshold.
function testFuzz_check_lowBalance_fails(address _target, uint256 _threshold) external {
CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({
target: _target,
threshold: _threshold
});
CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold });
vm.assume(_target.balance < _threshold);
......
......@@ -19,10 +19,7 @@ contract CheckBalanceLowTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns true
/// when the target's balance is smaller than the threshold.
function testFuzz_check_succeeds(address _target, uint256 _threshold) external {
CheckBalanceLow.Params memory p = CheckBalanceLow.Params({
target: _target,
threshold: _threshold
});
CheckBalanceLow.Params memory p = CheckBalanceLow.Params({ target: _target, threshold: _threshold });
vm.assume(_target.balance < _threshold);
......@@ -32,10 +29,7 @@ contract CheckBalanceLowTest is Test {
/// @notice Fuzz the `check` function and assert that it always returns false
/// when the target's balance is larger than the threshold.
function testFuzz_check_highBalance_fails(address _target, uint256 _threshold) external {
CheckBalanceLow.Params memory p = CheckBalanceLow.Params({
target: _target,
threshold: _threshold
});
CheckBalanceLow.Params memory p = CheckBalanceLow.Params({ target: _target, threshold: _threshold });
// prevent overflows
vm.assume(_threshold != type(uint256).max);
......
......@@ -2,10 +2,7 @@
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import {
CheckGelatoLow,
IGelatoTreasury
} from "../src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
import { CheckGelatoLow, IGelatoTreasury } from "../src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
/// @title MockGelatoTreasury
/// @notice Mocks the Gelato treasury for testing purposes. Allows arbitrary
......@@ -13,11 +10,7 @@ import {
contract MockGelatoTreasury is IGelatoTreasury {
mapping(address => mapping(address => uint256)) private tokenBalances;
function setTokenBalance(
address _user,
address _token,
uint256 _balance
) external {
function setTokenBalance(address _user, address _token, uint256 _balance) external {
tokenBalances[_token][_user] = _balance;
}
......@@ -48,11 +41,8 @@ contract CheckGelatoLowTest is Test {
/// @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.
function testFuzz_check_succeeds(uint256 _threshold, address _recipient) external {
CheckGelatoLow.Params memory p = CheckGelatoLow.Params({
treasury: address(gelato),
threshold: _threshold,
recipient: _recipient
});
CheckGelatoLow.Params memory p =
CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
vm.assume(gelato.userTokenBalance(_recipient, eth) < _threshold);
......@@ -63,11 +53,8 @@ contract CheckGelatoLowTest is Test {
/// when the user's balance in the treasury is greater than or equal
/// to the threshold.
function testFuzz_check_highBalance_fails(uint256 _threshold, address _recipient) external {
CheckGelatoLow.Params memory p = CheckGelatoLow.Params({
treasury: address(gelato),
threshold: _threshold,
recipient: _recipient
});
CheckGelatoLow.Params memory p =
CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
gelato.setTokenBalance(_recipient, eth, _threshold);
......
......@@ -117,9 +117,7 @@ contract Clones_Test is Test {
assertEq(fetched, param);
}
function testFuzz_clone_uintArrayArg_succeeds(uint256 argOffset, uint256[] memory param)
public
{
function testFuzz_clone_uintArrayArg_succeeds(uint256 argOffset, uint256[] memory param) public {
ExampleClone implementation = new ExampleClone(argOffset);
ExampleCloneFactory factory = new ExampleCloneFactory(implementation);
ExampleClone clone = factory.createUintArrayClone(param);
......
......@@ -49,12 +49,7 @@ contract CommonTest is Test {
bytes32 nonZeroHash = keccak256(abi.encode("NON_ZERO"));
bytes NON_ZERO_DATA = hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000";
event TransactionDeposited(
address indexed from,
address indexed to,
uint256 indexed version,
bytes opaqueData
);
event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
FFIInterface ffi;
......@@ -82,13 +77,10 @@ contract CommonTest is Test {
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
) internal {
emit TransactionDeposited(
_from,
_to,
0,
abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)
);
)
internal
{
emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data));
}
}
......@@ -97,8 +89,7 @@ contract L2OutputOracle_Initializer is CommonTest {
L2OutputOracle oracle;
L2OutputOracle oracleImpl;
L2ToL1MessagePasser messagePasser =
L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
L2ToL1MessagePasser messagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
// Constructor arguments
address internal proposer = 0x000000000000000000000000000000000000AbBa;
......@@ -114,10 +105,7 @@ contract L2OutputOracle_Initializer is CommonTest {
uint256 initL1Time;
event OutputProposed(
bytes32 indexed outputRoot,
uint256 indexed l2OutputIndex,
uint256 indexed l2BlockNumber,
uint256 l1Timestamp
bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp
);
event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);
......@@ -166,15 +154,7 @@ contract L2OutputOracle_Initializer is CommonTest {
vm.prank(multisig);
proxy.upgradeToAndCall(
address(oracleImpl),
abi.encodeCall(
L2OutputOracle.initialize,
(
startingBlockNumber,
startingTimestamp,
proposer,
owner
)
)
abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp, proposer, owner))
);
oracle = L2OutputOracle(address(proxy));
vm.label(address(oracle), "L2OutputOracle");
......@@ -193,11 +173,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
SystemConfig systemConfig;
event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);
event WithdrawalProven(
bytes32 indexed withdrawalHash,
address indexed from,
address indexed to
);
event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to);
function setUp() public virtual override {
super.setUp();
......@@ -240,11 +216,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
Proxy proxy = new Proxy(multisig);
vm.prank(multisig);
proxy.upgradeToAndCall(
address(opImpl),
abi.encodeCall(
OptimismPortal.initialize,
(oracle, guardian, systemConfig, false)
)
address(opImpl), abi.encodeCall(OptimismPortal.initialize, (oracle, guardian, systemConfig, false))
);
op = OptimismPortal(payable(address(proxy)));
vm.label(address(op), "OptimismPortal");
......@@ -254,16 +226,9 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
contract Messenger_Initializer is Portal_Initializer {
AddressManager internal addressManager;
L1CrossDomainMessenger internal L1Messenger;
L2CrossDomainMessenger internal L2Messenger =
L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
L2CrossDomainMessenger internal L2Messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
event SentMessage(
address indexed target,
address sender,
bytes message,
uint256 messageNonce,
uint256 gasLimit
);
event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);
event SentMessageExtension1(address indexed sender, uint256 value);
......@@ -312,10 +277,7 @@ contract Messenger_Initializer is Portal_Initializer {
L1Messenger = L1CrossDomainMessenger(address(proxy));
L1Messenger.initialize(op);
vm.etch(
Predeploys.L2_CROSS_DOMAIN_MESSENGER,
address(new L2CrossDomainMessenger(address(L1Messenger))).code
);
vm.etch(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(new L2CrossDomainMessenger(address(L1Messenger))).code);
L2Messenger.initialize();
......@@ -326,10 +288,7 @@ contract Messenger_Initializer is Portal_Initializer {
vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH");
vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger");
vm.label(
AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),
"L1CrossDomainMessenger_aliased"
);
vm.label(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), "L1CrossDomainMessenger_aliased");
}
}
......@@ -348,56 +307,26 @@ contract Bridge_Initializer is Messenger_Initializer {
event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);
event ETHWithdrawalFinalized(
address indexed from,
address indexed to,
uint256 amount,
bytes data
);
event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data);
event ERC20DepositInitiated(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event ERC20WithdrawalFinalized(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event WithdrawalInitiated(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event DepositFinalized(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event DepositFailed(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes data
address indexed l1Token, address indexed l2Token, address indexed from, address 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 {
// Deploy the L1 bridge and initialize it with the address of the
// L1CrossDomainMessenger
L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);
vm.mockCall(
multisig,
abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),
abi.encode(true)
);
vm.mockCall(multisig, abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector), abi.encode(true));
vm.startPrank(multisig);
proxy.setCode(address(new L1StandardBridge()).code);
vm.clearMockedCalls();
......@@ -443,9 +368,7 @@ contract Bridge_Initializer is Messenger_Initializer {
vm.stopPrank();
L1Bridge = L1StandardBridge(payable(address(proxy)));
L1Bridge.initialize({
_messenger: L1Messenger
});
L1Bridge.initialize({ _messenger: L1Messenger });
vm.label(address(proxy), "L1StandardBridge_Proxy");
vm.label(address(L1Bridge_Impl), "L1StandardBridge_Impl");
......@@ -526,11 +449,7 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
vm.prank(multisig);
l1BridgeProxy.upgradeToAndCall(
address(l1BridgeImpl),
abi.encodeCall(
L1ERC721Bridge.initialize,
(CrossDomainMessenger(L1Messenger))
)
address(l1BridgeImpl), abi.encodeCall(L1ERC721Bridge.initialize, (CrossDomainMessenger(L1Messenger)))
);
L1Bridge = L1ERC721Bridge(address(l1BridgeProxy));
......@@ -546,8 +465,7 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
vm.prank(multisig);
Proxy(payable(Predeploys.L2_ERC721_BRIDGE)).upgradeToAndCall(
address(l2BridgeImpl),
abi.encodeCall(L2ERC721Bridge.initialize, (L2Messenger))
address(l2BridgeImpl), abi.encodeCall(L2ERC721Bridge.initialize, (L2Messenger))
);
// Set up a reference to the L2ERC721Bridge.
......@@ -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,
FeeVault.WithdrawalNetwork withdrawalNetwork
);
event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork);
}
contract FFIInterface is Test {
function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)
external
returns (
bytes32,
bytes32,
bytes32,
bytes32,
bytes[] memory
)
returns (bytes32, bytes32, bytes32, bytes32, bytes[] memory)
{
string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing";
......@@ -613,7 +520,10 @@ contract FFIInterface is Test {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external returns (bytes32) {
)
external
returns (bytes32)
{
string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashCrossDomainMessage";
......@@ -635,7 +545,10 @@ contract FFIInterface is Test {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external returns (bytes32) {
)
external
returns (bytes32)
{
string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashWithdrawal";
......@@ -655,7 +568,10 @@ contract FFIInterface is Test {
bytes32 _stateRoot,
bytes32 _messagePasserStorageRoot,
bytes32 _latestBlockhash
) external returns (bytes32) {
)
external
returns (bytes32)
{
string[] memory cmds = new string[](6);
cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashOutputRootProof";
......@@ -676,7 +592,10 @@ contract FFIInterface is Test {
uint64 _gas,
bytes memory _data,
uint64 _logIndex
) external returns (bytes32) {
)
external
returns (bytes32)
{
string[] memory cmds = new string[](10);
cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "hashDepositTransaction";
......@@ -693,10 +612,7 @@ contract FFIInterface is Test {
return abi.decode(result, (bytes32));
}
function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)
external
returns (bytes memory)
{
function encodeDepositTransaction(Types.UserDepositTransaction calldata txn) external returns (bytes memory) {
string[] memory cmds = new string[](11);
cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "encodeDepositTransaction";
......@@ -721,7 +637,10 @@ contract FFIInterface is Test {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external returns (bytes memory) {
)
external
returns (bytes memory)
{
string[] memory cmds = new string[](8);
cmds[0] = "scripts/differential-testing/differential-testing";
cmds[1] = "encodeCrossDomainMessage";
......@@ -748,12 +667,7 @@ contract FFIInterface is Test {
function getMerkleTrieFuzzCase(string memory variant)
external
returns (
bytes32,
bytes memory,
bytes memory,
bytes[] memory
)
returns (bytes32, bytes memory, bytes memory, bytes[] memory)
{
string[] memory cmds = new string[](5);
cmds[0] = "./test-case-generator/fuzz";
......@@ -797,12 +711,8 @@ contract CallerCaller {
emit WhatHappened(success, returndata);
assembly {
switch success
case 0 {
revert(add(returndata, 0x20), mload(returndata))
}
default {
return(add(returndata, 0x20), mload(returndata))
}
case 0 { revert(add(returndata, 0x20), mload(returndata)) }
default { return(add(returndata, 0x20), mload(returndata)) }
}
}
}
......@@ -824,12 +734,8 @@ contract ConfigurableCaller {
emit WhatHappened(success, returndata);
assembly {
switch success
case 0 {
revert(add(returndata, 0x20), mload(returndata))
}
default {
return(add(returndata, 0x20), mload(returndata))
}
case 0 { revert(add(returndata, 0x20), mload(returndata)) }
default { return(add(returndata, 0x20), mload(returndata)) }
}
}
}
......
......@@ -28,9 +28,7 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
/// or equal to the minimum gas limit value on the OptimismPortal.
/// This guarantees that the messengers will always pass sufficient
/// gas to the OptimismPortal.
function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit)
external
{
function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) external {
vm.assume(_data.length <= type(uint64).max);
uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit);
uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length));
......
......@@ -61,12 +61,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);
bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
);
// It should be a failed message. The revert is caught,
......@@ -75,14 +70,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
);
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message);
assertEq(setter.value(), 0);
}
......
......@@ -30,11 +30,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/// @dev CrossDomainOwnable3.sol transferOwnership event
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner, bool isLocal);
/// @dev Sets up the test suite.
function setUp() public override {
......@@ -111,12 +107,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);
bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
);
// It should be a failed message. The revert is caught,
......@@ -125,14 +116,7 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
);
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message);
assertEq(setter.value(), 0);
}
......
......@@ -14,11 +14,7 @@ contract DisputeGameFactory_Init is L2OutputOracle_Initializer {
DisputeGameFactory factory;
FakeClone fakeClone;
event DisputeGameCreated(
address indexed disputeProxy,
GameType indexed gameType,
Claim indexed rootClaim
);
event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);
event ImplementationSet(address indexed impl, GameType indexed gameType);
......@@ -42,11 +38,7 @@ contract DisputeGameFactory_Init is L2OutputOracle_Initializer {
contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
/// @dev Tests that the `create` function succeeds when creating a new dispute game
/// with a `GameType` that has an implementation set.
function testFuzz_create_succeeds(
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
function testFuzz_create_succeeds(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
......@@ -73,11 +65,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
/// @dev Tests that the `create` function reverts when there is no implementation
/// set for the given `GameType`.
function testFuzz_create_noImpl_reverts(
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
function testFuzz_create_noImpl_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
......@@ -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.
function testFuzz_create_sameUUID_reverts(
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
function testFuzz_create_sameUUID_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
......@@ -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.
vm.expectRevert(
abi.encodeWithSelector(
GameAlreadyExists.selector,
factory.getGameUUID(gt, rootClaim, extraData)
)
abi.encodeWithSelector(GameAlreadyExists.selector, factory.getGameUUID(gt, rootClaim, extraData))
);
factory.create(gt, rootClaim, extraData);
}
......@@ -148,17 +129,12 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
/// @dev Tests that the `getGameUUID` function returns the correct hash when comparing
/// against the keccak256 hash of the abi-encoded parameters.
function testDiff_getGameUUID_succeeds(
uint8 gameType,
Claim rootClaim,
bytes calldata extraData
) public {
function testDiff_getGameUUID_succeeds(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
assertEq(
Hash.unwrap(factory.getGameUUID(gt, rootClaim, extraData)),
keccak256(abi.encode(gt, rootClaim, extraData))
Hash.unwrap(factory.getGameUUID(gt, rootClaim, extraData)), keccak256(abi.encode(gt, rootClaim, extraData))
);
}
}
......
......@@ -14,7 +14,7 @@ import { SimpleStorage } from "./Helpers.sol";
/// to go up by ~4x. Each of the methods is a simple getter around
/// parts of the `DripState`.
contract TestDrippie is Drippie {
constructor(address owner) Drippie(owner) {}
constructor(address owner) Drippie(owner) { }
function dripStatus(string memory name) external view returns (Drippie.DripStatus) {
return drips[name].status;
......@@ -28,11 +28,7 @@ contract TestDrippie is Drippie {
return drips[name].config;
}
function dripConfigActions(string memory name)
external
view
returns (Drippie.DripAction[] memory)
{
function dripConfigActions(string memory name) external view returns (Drippie.DripAction[] memory) {
return drips[name].config.actions;
}
......@@ -93,8 +89,7 @@ contract Drippie_Test is Test {
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
actions[0] = Drippie.DripAction({ target: payable(address(0x44)), data: hex"", value: 1 });
return
Drippie.DripConfig({
return Drippie.DripConfig({
interval: 100,
dripcheck: check,
reentrant: false,
......@@ -189,11 +184,7 @@ contract Drippie_Test is Test {
vm.prank(owner);
vm.expectEmit(true, true, true, true);
emit DripStatusUpdated({
nameref: dripName,
name: dripName,
status: Drippie.DripStatus.ACTIVE
});
emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.ACTIVE });
drippie.status(dripName, Drippie.DripStatus.ACTIVE);
......@@ -205,11 +196,7 @@ contract Drippie_Test is Test {
vm.prank(owner);
vm.expectEmit(true, true, true, true);
emit DripStatusUpdated({
nameref: dripName,
name: dripName,
status: Drippie.DripStatus.PAUSED
});
emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.PAUSED });
drippie.status(dripName, Drippie.DripStatus.PAUSED);
......@@ -252,11 +239,7 @@ contract Drippie_Test is Test {
vm.prank(owner);
vm.expectEmit(true, true, true, true);
emit DripStatusUpdated({
nameref: dripName,
name: dripName,
status: Drippie.DripStatus.ARCHIVED
});
emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.ARCHIVED });
drippie.status(dripName, Drippie.DripStatus.ARCHIVED);
......@@ -339,20 +322,12 @@ contract Drippie_Test is Test {
_warpToExecutable(dripName);
vm.expectEmit(true, true, true, true);
emit DripExecuted({
nameref: dripName,
name: dripName,
executor: address(this),
timestamp: block.timestamp
});
emit DripExecuted({ nameref: dripName, name: dripName, executor: address(this), timestamp: block.timestamp });
Drippie.DripAction[] memory actions = drippie.dripConfigActions(dripName);
assertEq(actions.length, 1);
vm.expectCall(
drippie.dripConfigCheckAddress(dripName),
drippie.dripConfigCheckParams(dripName)
);
vm.expectCall(drippie.dripConfigCheckAddress(dripName), drippie.dripConfigCheckParams(dripName));
vm.expectCall(actions[0].target, actions[0].value, actions[0].data);
......@@ -381,11 +356,7 @@ contract Drippie_Test is Test {
vm.prank(drippie.owner());
drippie.status(dripName, Drippie.DripStatus.ACTIVE);
vm.expectCall(
address(simpleStorage),
0,
abi.encodeWithSelector(SimpleStorage.set.selector, key, value)
);
vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, key, value));
vm.expectEmit(true, true, true, true, address(drippie));
emit DripExecuted(dripName, dripName, address(this), block.timestamp);
......@@ -425,22 +396,11 @@ contract Drippie_Test is Test {
vm.prank(drippie.owner());
drippie.status(dripName, Drippie.DripStatus.ACTIVE);
vm.expectCall(
drippie.dripConfigCheckAddress(dripName),
drippie.dripConfigCheckParams(dripName)
);
vm.expectCall(drippie.dripConfigCheckAddress(dripName), drippie.dripConfigCheckParams(dripName));
vm.expectCall(
address(simpleStorage),
0,
abi.encodeWithSelector(SimpleStorage.set.selector, keyOne, valueOne)
);
vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, keyOne, valueOne));
vm.expectCall(
address(simpleStorage),
0,
abi.encodeWithSelector(SimpleStorage.set.selector, keyTwo, valueTwo)
);
vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, keyTwo, valueTwo));
vm.expectEmit(true, true, true, true, address(drippie));
emit DripExecuted(dripName, dripName, address(this), block.timestamp);
......@@ -475,12 +435,7 @@ contract Drippie_Test is Test {
_warpToExecutable(dripName);
vm.expectEmit(true, true, true, true, address(drippie));
emit DripExecuted({
nameref: dripName,
name: dripName,
executor: address(this),
timestamp: block.timestamp
});
emit DripExecuted({ nameref: dripName, name: dripName, executor: address(this), timestamp: block.timestamp });
drippie.drip(dripName);
}
......
......@@ -14,9 +14,7 @@ import { Encoding } from "../src/libraries/Encoding.sol";
contract Encoding_Test is CommonTest {
/// @dev Tests encoding and decoding a nonce and version.
function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {
(uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(
Encoding.encodeVersionedNonce(_nonce, _version)
);
(uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(Encoding.encodeVersionedNonce(_nonce, _version));
assertEq(version, _version);
assertEq(nonce, _nonce);
}
......@@ -40,27 +38,15 @@ contract Encoding_Test is CommonTest {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
uint8 version = _version % 2;
uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);
bytes memory encoding = Encoding.encodeCrossDomainMessage(
nonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes memory encoding = Encoding.encodeCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data);
bytes memory _encoding = ffi.encodeCrossDomainMessage(
nonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes memory _encoding = ffi.encodeCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data);
assertEq(encoding, _encoding);
}
......@@ -71,23 +57,15 @@ contract Encoding_Test is CommonTest {
address _sender,
address _target,
bytes memory _data
) external {
)
external
{
uint8 version = 0;
uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);
bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(
_target,
_sender,
_data,
nonce
);
bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(_target, _sender, _data, nonce);
bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(
_target,
_sender,
_data,
nonce
);
bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, nonce);
assertEq(legacyEncoding, bedrockEncoding);
}
......@@ -102,17 +80,11 @@ contract Encoding_Test is CommonTest {
bool isCreate,
bytes memory _data,
uint64 _logIndex
) external {
)
external
{
Types.UserDepositTransaction memory t = Types.UserDepositTransaction(
_from,
_to,
isCreate,
_value,
_mint,
_gas,
_data,
bytes32(uint256(0)),
_logIndex
_from, _to, isCreate, _value, _mint, _gas, _data, bytes32(uint256(0)), _logIndex
);
bytes memory txn = Encoding.encodeDepositTransaction(t);
......
......@@ -7,12 +7,8 @@ import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/Admin
import { FaucetHelper } from "./Helpers.sol";
contract Faucet_Initializer is Test {
event Drip(
string indexed authModule,
bytes32 indexed userId,
uint256 amount,
address indexed recipient
);
event Drip(string indexed authModule, bytes32 indexed userId, uint256 amount, address indexed recipient);
address internal faucetContractAdmin;
address internal faucetAuthAdmin;
address internal nonAdmin;
......@@ -66,20 +62,13 @@ contract Faucet_Initializer is Test {
function _enableFaucetAuthModules() internal {
vm.startPrank(faucetContractAdmin);
faucet.configure(
optimistNftFam,
Faucet.ModuleConfig("OptimistNftModule", true, 1 days, 1 ether)
);
faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", true, 1 days, .05 ether));
faucet.configure(optimistNftFam, Faucet.ModuleConfig("OptimistNftModule", true, 1 days, 1 ether));
faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", true, 1 days, 0.05 ether));
vm.stopPrank();
}
/// @notice Get signature as a bytes blob.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest)
internal
pure
returns (bytes memory)
{
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v);
......@@ -98,21 +87,16 @@ contract Faucet_Initializer is Test {
address recipient,
bytes32 id,
bytes32 nonce
) internal view returns (bytes memory) {
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(
recipient,
nonce,
id
);
return
_getSignature(
)
internal
view
returns (bytes memory)
{
AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(recipient, nonce, id);
return _getSignature(
_issuerPrivateKey,
faucetHelper.getDigestWithEIP712Domain(
proof,
_eip712Name,
_contractVersion,
_eip712Chainid,
_eip712VerifyingContract
proof, _eip712Name, _contractVersion, _eip712Chainid, _eip712VerifyingContract
)
);
}
......@@ -140,11 +124,7 @@ contract FaucetTest is Faucet_Initializer {
vm.prank(nonAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(
optimistNftFam,
keccak256(abi.encodePacked(fundsReceiver)),
signature
)
Faucet.AuthParameters(optimistNftFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
);
}
......@@ -166,11 +146,7 @@ contract FaucetTest is Faucet_Initializer {
vm.expectRevert("Faucet: drip parameters could not be verified by security module");
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(
optimistNftFam,
keccak256(abi.encodePacked(fundsReceiver)),
signature
)
Faucet.AuthParameters(optimistNftFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
);
}
......@@ -192,18 +168,10 @@ contract FaucetTest is Faucet_Initializer {
vm.prank(nonAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(
optimistNftFam,
keccak256(abi.encodePacked(fundsReceiver)),
signature
)
Faucet.AuthParameters(optimistNftFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
);
uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq(
recipientBalanceAfter - recipientBalanceBefore,
1 ether,
"expect increase of 1 ether"
);
assertEq(recipientBalanceAfter - recipientBalanceBefore, 1 ether, "expect increase of 1 ether");
}
function test_drip_githubSendsCorrectAmount_succeeds() external {
......@@ -227,11 +195,7 @@ contract FaucetTest is Faucet_Initializer {
Faucet.AuthParameters(githubFam, keccak256(abi.encodePacked(fundsReceiver)), signature)
);
uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq(
recipientBalanceAfter - recipientBalanceBefore,
.05 ether,
"expect increase of .05 ether"
);
assertEq(recipientBalanceAfter - recipientBalanceBefore, 0.05 ether, "expect increase of .05 ether");
}
function test_drip_emitsEvent_succeeds() external {
......@@ -249,12 +213,7 @@ contract FaucetTest is Faucet_Initializer {
);
vm.expectEmit(true, true, true, true, address(faucet));
emit Drip(
"GithubModule",
keccak256(abi.encodePacked(fundsReceiver)),
.05 ether,
fundsReceiver
);
emit Drip("GithubModule", keccak256(abi.encodePacked(fundsReceiver)), 0.05 ether, fundsReceiver);
vm.prank(nonAdmin);
faucet.drip(
......@@ -283,7 +242,7 @@ contract FaucetTest is Faucet_Initializer {
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");
faucet.drip(
......@@ -408,11 +367,7 @@ contract FaucetTest is Faucet_Initializer {
faucet.withdraw(payable(fundsReceiver), 2 ether);
uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq(
recipientBalanceAfter - recipientBalanceBefore,
2 ether,
"expect increase of 2 ether"
);
assertEq(recipientBalanceAfter - recipientBalanceBefore, 2 ether, "expect increase of 2 ether");
vm.stopPrank();
}
......@@ -426,7 +381,7 @@ contract FaucetTest is Faucet_Initializer {
uint256 faucetBalanceBefore = address(faucet).balance;
vm.prank(nonAdmin);
(bool success, ) = address(faucet).call{ value: 1 ether }("");
(bool success,) = address(faucet).call{ value: 1 ether }("");
assertTrue(success);
uint256 faucetBalanceAfter = address(faucet).balance;
......
......@@ -126,11 +126,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// contain the disputed L2 output root.
function test_initialize_l1HeadTooOld_reverts() public {
// Store a mock block hash for the genesis block. The timestamp will default to 0.
vm.store(
address(gameImpl.BLOCK_ORACLE()),
keccak256(abi.encode(0, 0)),
bytes32(uint256(1))
);
vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1)));
bytes memory _extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, 0);
vm.expectRevert(L1HeadTooOld.selector);
......@@ -150,10 +146,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that the game is initialized with the correct data.
function test_initialize_correctData_succeeds() public {
// Starting
(
FaultDisputeGame.OutputProposal memory startingProp,
FaultDisputeGame.OutputProposal memory disputedProp
) = gameProxy.proposals();
(FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) =
gameProxy.proposals();
Types.OutputProposal memory starting = oracle.getL2Output(startingProp.index);
assertEq(startingProp.index, 0);
assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber);
......@@ -168,21 +162,14 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
(, uint256 l1HeadNumber) = abi.decode(gameProxy.extraData(), (uint256, uint256));
assertEq(blockhash(l1HeadNumber), Hash.unwrap(gameProxy.l1Head()));
(
uint32 parentIndex,
bool countered,
Claim claim,
Position position,
Clock clock
) = gameProxy.claimData(0);
(uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(0);
assertEq(parentIndex, type(uint32).max);
assertEq(countered, false);
assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM));
assertEq(Position.unwrap(position), 1);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
);
}
......@@ -256,44 +243,39 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @notice Static unit test for the correctness of the chess clock incrementation.
function test_move_clockCorrectness_succeeds() public {
(, , , , Clock clock) = gameProxy.claimData(0);
(,,,, Clock clock) = gameProxy.claimData(0);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
);
Claim claim = Claim.wrap(bytes32(uint256(5)));
vm.warp(block.timestamp + 15);
gameProxy.attack(0, claim);
(, , , , clock) = gameProxy.claimData(1);
(,,,, clock) = gameProxy.claimData(1);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(1, claim);
(, , , , clock) = gameProxy.claimData(2);
(,,,, clock) = gameProxy.claimData(2);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(2, claim);
(, , , , clock) = gameProxy.claimData(3);
(,,,, clock) = gameProxy.claimData(3);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(3, claim);
(, , , , clock) = gameProxy.claimData(4);
(,,,, clock) = gameProxy.claimData(4);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp))))
);
}
......@@ -323,13 +305,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, counter);
// 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.
assertEq(parentIndex, 0);
......@@ -337,8 +313,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(Claim.unwrap(claim), Claim.unwrap(counter));
assertEq(Position.unwrap(position), Position.unwrap(Position.wrap(1).move(true)));
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(5), Timestamp.wrap(uint64(block.timestamp))))
Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(5), Timestamp.wrap(uint64(block.timestamp))))
);
// Grab the claim data of the parent.
......@@ -351,9 +326,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(Position.unwrap(position), 1);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(
LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp - 5)))
)
Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp - 5))))
);
}
......@@ -438,10 +411,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that local data is loaded into the preimage oracle correctly.
function test_addLocalData_static_succeeds() public {
IPreimageOracle oracle = IPreimageOracle(address(gameProxy.VM().oracle()));
(
FaultDisputeGame.OutputProposal memory starting,
FaultDisputeGame.OutputProposal memory disputed
) = gameProxy.proposals();
(FaultDisputeGame.OutputProposal memory starting, FaultDisputeGame.OutputProposal memory disputed) =
gameProxy.proposals();
bytes32[5] memory data = [
Hash.unwrap(gameProxy.l1Head()),
......@@ -493,11 +464,7 @@ contract GamePlayer {
uint256 internal maxDepth;
/// @notice Initializes the player
function init(
FaultDisputeGame _gameProxy,
GamePlayer _counterParty,
Vm _vm
) public {
function init(FaultDisputeGame _gameProxy, GamePlayer _counterParty, Vm _vm) public {
gameProxy = _gameProxy;
counterParty = _counterParty;
vm = _vm;
......@@ -507,9 +474,7 @@ contract GamePlayer {
/// @notice Perform the next move in the game.
function play(uint256 _parentIndex) public virtual {
// Grab the claim data at the parent index.
(uint32 grandparentIndex, , Claim parentClaim, Position parentPos, ) = gameProxy.claimData(
_parentIndex
);
(uint32 grandparentIndex,, Claim parentClaim, Position parentPos,) = gameProxy.claimData(_parentIndex);
// The position to move to.
Position movePos;
......@@ -531,9 +496,7 @@ contract GamePlayer {
Claim ourParentClaim = claimAt(parentPos);
// Fetch our claim at the grandparent's position.
(, , Claim grandparentClaim, Position grandparentPos, ) = gameProxy.claimData(
grandparentIndex
);
(,, Claim grandparentClaim, Position grandparentPos,) = gameProxy.claimData(grandparentIndex);
Claim ourGrandparentClaim = claimAt(grandparentPos);
if (Claim.unwrap(ourParentClaim) != Claim.unwrap(parentClaim)) {
......@@ -547,8 +510,8 @@ contract GamePlayer {
// Flag the move as an attack.
isAttack = true;
} else if (
Claim.unwrap(ourParentClaim) == Claim.unwrap(parentClaim) &&
Claim.unwrap(ourGrandparentClaim) == Claim.unwrap(grandparentClaim)
Claim.unwrap(ourParentClaim) == Claim.unwrap(parentClaim)
&& Claim.unwrap(ourGrandparentClaim) == Claim.unwrap(grandparentClaim)
) {
movePos = parentPos.move(false);
}
......@@ -598,7 +561,7 @@ contract GamePlayer {
// If we have a second move position, attack the grandparent.
if (Position.unwrap(movePos2) != 0) {
(, , , Position grandparentPos, ) = gameProxy.claimData(grandparentIndex);
(,,, Position grandparentPos,) = gameProxy.claimData(grandparentIndex);
Claim ourGrandparentClaim = claimAt(grandparentPos.move(true));
gameProxy.attack(grandparentIndex, ourGrandparentClaim);
......@@ -606,10 +569,7 @@ contract GamePlayer {
}
} else {
// Don't defend a claim we would've made ourselves.
if (
parentPos.depth() % 2 == 0 &&
Claim.unwrap(claimAt(15)) == Claim.unwrap(gameProxy.rootClaim())
) {
if (parentPos.depth() % 2 == 0 && Claim.unwrap(claimAt(15)) == Claim.unwrap(gameProxy.rootClaim())) {
return;
}
......@@ -628,22 +588,13 @@ contract GamePlayer {
/// @notice Returns the state at the trace index within the player's trace.
function traceAt(uint256 _traceIndex) public view returns (uint256 state_) {
return
uint256(
uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex])
);
return uint256(uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex]));
}
/// @notice Returns the player's claim that commits to a given trace index.
function claimAt(uint256 _traceIndex) public view returns (Claim claim_) {
return
Claim.wrap(
keccak256(
abi.encode(
_traceIndex >= trace.length ? trace.length - 1 : _traceIndex,
traceAt(_traceIndex)
)
)
return Claim.wrap(
keccak256(abi.encode(_traceIndex >= trace.length ? trace.length - 1 : _traceIndex, traceAt(_traceIndex)))
);
}
......@@ -663,14 +614,8 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
/// @dev The challenger.
GamePlayer internal challenger;
function init(
GamePlayer _defender,
GamePlayer _challenger,
uint256 _finalTraceIndex
) public {
Claim rootClaim = Claim.wrap(
keccak256(abi.encode(_finalTraceIndex, _defender.traceAt(_finalTraceIndex)))
);
function init(GamePlayer _defender, GamePlayer _challenger, uint256 _finalTraceIndex) public {
Claim rootClaim = Claim.wrap(keccak256(abi.encode(_finalTraceIndex, _defender.traceAt(_finalTraceIndex))));
super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM);
defender = _defender;
challenger = _challenger;
......@@ -995,11 +940,7 @@ contract HonestPlayer_QuarterTrace is GamePlayer {
}
contract VariableDivergentPlayer is GamePlayer {
constructor(
bytes memory _absolutePrestate,
uint256 _traceLength,
uint256 _divergeAt
) {
constructor(bytes memory _absolutePrestate, uint256 _traceLength, uint256 _divergeAt) {
uint8 absolutePrestate = uint8(_absolutePrestate[31]);
bytes memory _trace = new bytes(_traceLength);
for (uint8 i = 0; i < _trace.length; i++) {
......@@ -1024,11 +965,7 @@ contract AlphabetVM is IBigStepper {
}
/// @inheritdoc IBigStepper
function step(bytes calldata _stateData, bytes calldata)
external
view
returns (bytes32 postState_)
{
function step(bytes calldata _stateData, bytes calldata) external view returns (bytes32 postState_) {
uint256 traceIndex;
uint256 claim;
if (keccak256(_stateData) == Claim.unwrap(ABSOLUTE_PRESTATE)) {
......
......@@ -31,9 +31,7 @@ contract FeeVault_Test is Bridge_Initializer {
);
vm.etch(
Predeploys.L1_FEE_VAULT,
address(
new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)
).code
address(new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)).code
);
vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault");
......
......@@ -94,9 +94,8 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `setGasPrice` reverts since it was removed in bedrock.
function test_setGasPrice_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = address(gasOracle).call(
abi.encodeWithSignature("setGasPrice(uint256)", 1)
);
(bool success, bytes memory returndata) =
address(gasOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1));
assertEq(success, false);
assertEq(returndata, hex"");
......@@ -104,9 +103,8 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock.
function test_setL1BaseFee_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = address(gasOracle).call(
abi.encodeWithSignature("setL1BaseFee(uint256)", 1)
);
(bool success, bytes memory returndata) =
address(gasOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1));
assertEq(success, false);
assertEq(returndata, hex"");
......
......@@ -16,10 +16,7 @@ contract Hashing_hashDepositSource_Test is CommonTest {
/// @notice Tests that hashDepositSource returns the correct hash in a simple case.
function test_hashDepositSource_succeeds() external {
assertEq(
Hashing.hashDepositSource(
0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,
0x1
),
Hashing.hashDepositSource(0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959, 0x1),
0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc
);
}
......@@ -35,7 +32,9 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
// Ensure the version is valid.
uint16 version = uint16(bound(uint256(_version), 0, 1));
uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);
......@@ -52,16 +51,11 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest {
address _sender,
bytes memory _message,
uint256 _messageNonce
) external {
assertEq(
keccak256(
LegacyCrossDomainUtils.encodeXDomainCalldata(
_target,
_sender,
_message,
_messageNonce
)
),
external
{
assertEq(
keccak256(LegacyCrossDomainUtils.encodeXDomainCalldata(_target, _sender, _message, _messageNonce)),
Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)
);
}
......@@ -76,11 +70,11 @@ contract Hashing_hashWithdrawal_Test is CommonTest {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
assertEq(
Hashing.hashWithdrawal(
Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)
),
Hashing.hashWithdrawal(Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)),
ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)
);
}
......@@ -92,7 +86,9 @@ contract Hashing_hashOutputRootProof_Test is CommonTest {
bytes32 _stateRoot,
bytes32 _messagePasserStorageRoot,
bytes32 _latestBlockhash
) external {
)
external
{
bytes32 version = 0;
assertEq(
Hashing.hashOutputRootProof(
......@@ -103,12 +99,7 @@ contract Hashing_hashOutputRootProof_Test is CommonTest {
latestBlockhash: _latestBlockhash
})
),
ffi.hashOutputRootProof(
version,
_stateRoot,
_messagePasserStorageRoot,
_latestBlockhash
)
ffi.hashOutputRootProof(version, _stateRoot, _messagePasserStorageRoot, _latestBlockhash)
);
}
}
......@@ -123,7 +114,9 @@ contract Hashing_hashDepositTransaction_Test is CommonTest {
uint64 _gas,
bytes memory _data,
uint64 _logIndex
) external {
)
external
{
assertEq(
Hashing.hashDepositTransaction(
Types.UserDepositTransaction(
......
......@@ -7,13 +7,11 @@ import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { OptimistInviter } from "../src/periphery/op-nft/OptimistInviter.sol";
import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import {
ECDSAUpgradeable
} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
contract TestERC20 is ERC20 {
constructor() ERC20("TEST", "TST", 18) {}
constructor() ERC20("TEST", "TST", 18) { }
function mint(address to, uint256 value) public {
_mint(to, value);
......@@ -21,13 +19,13 @@ contract TestERC20 is ERC20 {
}
contract TestERC721 is ERC721 {
constructor() ERC721("TEST", "TST") {}
constructor() ERC721("TEST", "TST") { }
function mint(address to, uint256 tokenId) public {
_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 {
......@@ -71,14 +69,11 @@ contract SimpleStorage {
/// in OptimistInviter.t.sol for reusability.
contract OptimistInviterHelper {
/// @notice EIP712 typehash for the ClaimableInvite type.
bytes32 public constant CLAIMABLE_INVITE_TYPEHASH =
keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
/// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature.
bytes32 public constant EIP712_DOMAIN_TYPEHASH =
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/// @notice Address of OptimistInviter contract we are testing.
OptimistInviter public optimistInviter;
......@@ -102,14 +97,7 @@ contract OptimistInviterHelper {
pure
returns (bytes32)
{
return
keccak256(
abi.encode(
CLAIMABLE_INVITE_TYPEHASH,
_claimableInvite.issuer,
_claimableInvite.nonce
)
);
return keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce));
}
/// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use
......@@ -122,23 +110,15 @@ contract OptimistInviterHelper {
/// @notice Returns a ClaimableInvite with the issuer and current nonce.
/// @param _issuer Issuer to include in the ClaimableInvite.
/// @return ClaimableInvite that can be hashed & signed.
function getClaimableInviteWithNewNonce(address _issuer)
public
returns (OptimistInviter.ClaimableInvite memory)
{
function getClaimableInviteWithNewNonce(address _issuer) public returns (OptimistInviter.ClaimableInvite memory) {
return OptimistInviter.ClaimableInvite(_issuer, consumeNonce());
}
/// @notice Computes the EIP712 digest with default correct parameters.
/// @param _claimableInvite ClaimableInvite struct to hash.
/// @return EIP-712 compatible digest.
function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite)
public
view
returns (bytes32)
{
return
getDigestWithEIP712Domain(
function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite) public view returns (bytes32) {
return getDigestWithEIP712Domain(
_claimableInvite,
bytes(name),
bytes(optimistInviter.EIP712_VERSION()),
......@@ -161,18 +141,15 @@ contract OptimistInviterHelper {
bytes memory _version,
uint256 _chainid,
address _verifyingContract
) public pure returns (bytes32) {
bytes32 domainSeparator = keccak256(
abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(_name),
keccak256(_version),
_chainid,
_verifyingContract
)
public
pure
returns (bytes32)
{
bytes32 domainSeparator = keccak256(
abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract)
);
return
ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite));
return ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite));
}
}
......@@ -184,28 +161,19 @@ contract TestERC1271Wallet is Ownable, IERC1271 {
transferOwnership(originalOwner);
}
function isValidSignature(bytes32 hash, bytes memory signature)
public
view
override
returns (bytes4 magicValue)
{
return
ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
function isValidSignature(bytes32 hash, bytes memory signature) public 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.
contract FaucetHelper {
/// @notice EIP712 typehash for the Proof type.
bytes32 public constant PROOF_TYPEHASH =
keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
/// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature.
bytes32 public constant EIP712_DOMAIN_TYPEHASH =
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/// @notice Keeps track of current nonce to generate new nonces for each drip.
uint256 public currentNonce;
......@@ -220,11 +188,7 @@ contract FaucetHelper {
/// @notice Returns the hash of the struct Proof.
/// @param _proof Proof struct to hash.
/// @return EIP-712 typed struct hash.
function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof)
public
pure
returns (bytes32)
{
function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof) public pure returns (bytes32) {
return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id));
}
......@@ -244,15 +208,13 @@ contract FaucetHelper {
bytes memory _version,
uint256 _chainid,
address _verifyingContract
) public pure returns (bytes32) {
bytes32 domainSeparator = keccak256(
abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(_name),
keccak256(_version),
_chainid,
_verifyingContract
)
public
pure
returns (bytes32)
{
bytes32 domainSeparator = keccak256(
abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract)
);
return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof));
}
......
......@@ -40,7 +40,9 @@ contract L1BlockTest is CommonTest {
bytes32 bt,
uint256 fo,
uint256 fs
) external {
)
external
{
vm.prank(depositor);
lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);
assertEq(lb.number(), n);
......
......@@ -44,14 +44,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
0,
L1Messenger.baseGas(hex"ff", 100),
false,
Encoding.encodeCrossDomainMessage(
L1Messenger.messageNonce(),
alice,
recipient,
0,
100,
hex"ff"
)
Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff")
)
);
......@@ -64,14 +57,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
0,
L1Messenger.baseGas(hex"ff", 100),
false,
Encoding.encodeCrossDomainMessage(
L1Messenger.messageNonce(),
alice,
recipient,
0,
100,
hex"ff"
)
Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff")
);
// SentMessage event
......@@ -112,9 +98,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Expect a revert.
vm.expectRevert(
"CrossDomainMessenger: only version 0 or 1 messages are supported at this time"
);
vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
// Try to relay a v2 message.
vm.prank(address(op));
......@@ -143,12 +127,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true);
bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
sender,
target,
0,
0,
hex"1111"
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, hex"1111"
);
emit RelayedMessage(hash);
......@@ -179,23 +158,13 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.prank(address(op));
vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
sender,
target,
0,
0,
message
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
);
vm.store(address(op), 0, bytes32(abi.encode(sender)));
vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
sender,
target,
0,
0,
message
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
);
}
......@@ -206,16 +175,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
bytes memory message = hex"1111";
vm.expectRevert(
"CrossDomainMessenger: value must be zero unless message is from a system address"
);
vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address");
L1Messenger.relayMessage{ value: 100 }(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
sender,
target,
0,
0,
message
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
);
}
......@@ -230,12 +192,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.prank(address(op));
L1Messenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
address(0),
address(0),
0,
0,
hex""
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), address(0), address(0), 0, 0, hex""
);
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
......@@ -253,12 +210,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectCall(target, hex"1111");
bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
sender,
target,
value,
0,
hex"1111"
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, value, 0, hex"1111"
);
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
......
......@@ -14,7 +14,7 @@ import { L1ERC721Bridge } from "../src/L1/L1ERC721Bridge.sol";
/// @dev Test ERC721 contract.
contract TestERC721 is ERC721 {
constructor() ERC721("Test", "TST") {}
constructor() ERC721("Test", "TST") { }
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
......@@ -78,14 +78,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
address(L2Bridge),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(
address(remoteToken),
address(localToken),
alice,
alice,
tokenId,
hex"5678"
)
(address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
),
1234
)
......@@ -94,14 +87,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Bridge the token.
vm.prank(alice);
......@@ -182,25 +168,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated(
address(localToken),
address(remoteToken),
alice,
bob,
tokenId,
hex"5678"
);
emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678");
// Bridge the token.
vm.prank(alice);
L1Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
L1Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
......@@ -239,14 +211,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner");
L1Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
L1Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
......@@ -261,14 +226,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeFinalized(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Finalize a withdrawal.
vm.mockCall(
......@@ -277,14 +235,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encode(Predeploys.L2_ERC721_BRIDGE)
);
vm.prank(address(L1Messenger));
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
......@@ -297,14 +248,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that the ERC721 bridge finalize reverts when not called
......@@ -312,20 +256,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
address(L1Messenger),
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),
abi.encode(alice)
address(L1Messenger), abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encode(alice)
);
vm.prank(address(L1Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that the ERC721 bridge finalize reverts when the local token
......@@ -339,14 +274,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: local token cannot be self");
L1Bridge.finalizeBridgeERC721(
address(L1Bridge),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L1Bridge.finalizeBridgeERC721(address(L1Bridge), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that the ERC721 bridge finalize reverts when the remote token
......@@ -360,13 +288,6 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge");
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
}
......@@ -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 {
/// @dev Tests receive bridges ETH successfully.
......@@ -63,25 +63,19 @@ contract L1StandardBridge_Receive_Test is Bridge_Initializer {
abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
abi.encodeWithSelector(
StandardBridge.finalizeBridgeETH.selector,
alice,
alice,
100,
hex""
),
abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""),
200_000
)
);
vm.prank(alice, alice);
(bool success, ) = address(L1Bridge).call{ value: 100 }(hex"");
(bool success,) = address(L1Bridge).call{ value: 100 }(hex"");
assertEq(success, true);
assertEq(address(op).balance, 100);
}
}
contract L1StandardBridge_Receive_TestFail {}
contract L1StandardBridge_Receive_TestFail { }
contract PreBridgeETH is Bridge_Initializer {
/// @dev Asserts the expected calls and events for bridging ETH depending
......@@ -92,46 +86,24 @@ contract PreBridgeETH is Bridge_Initializer {
uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeETH.selector,
alice,
alice,
500,
hex"dead"
);
bytes memory message =
abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 500, hex"dead");
if (isLegacy) {
vm.expectCall(
address(L1Bridge),
500,
abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex"dead")
address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex"dead")
);
} else {
vm.expectCall(
address(L1Bridge),
500,
abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex"dead")
);
vm.expectCall(address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex"dead"));
}
vm.expectCall(
address(L1Messenger),
500,
abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
50000
)
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 50000)
);
bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector,
nonce,
address(L1Bridge),
address(L2Bridge),
500,
50000,
message
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 500, 50000, message
);
uint64 baseGas = L1Messenger.baseGas(message, 50000);
......@@ -139,22 +111,11 @@ contract PreBridgeETH is Bridge_Initializer {
address(op),
500,
abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector,
address(L2Messenger),
500,
baseGas,
false,
innerMessage
OptimismPortal.depositTransaction.selector, address(L2Messenger), 500, baseGas, false, innerMessage
)
);
bytes memory opaqueData = abi.encodePacked(
uint256(500),
uint256(500),
baseGas,
false,
innerMessage
);
bytes memory opaqueData = abi.encodePacked(uint256(500), uint256(500), baseGas, false, innerMessage);
vm.expectEmit(true, true, true, true, address(L1Bridge));
emit ETHDepositInitiated(alice, alice, 500, hex"dead");
......@@ -225,68 +186,37 @@ contract PreBridgeETHTo is Bridge_Initializer {
if (isLegacy) {
vm.expectCall(
address(L1Bridge),
600,
abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex"dead")
address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex"dead")
);
} else {
vm.expectCall(
address(L1Bridge),
600,
abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex"dead")
address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex"dead")
);
}
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeETH.selector,
alice,
bob,
600,
hex"dead"
);
bytes memory message =
abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, bob, 600, hex"dead");
// the L1 bridge should call
// L1CrossDomainMessenger.sendMessage
vm.expectCall(
address(L1Messenger),
abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
60000
)
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 60000)
);
bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector,
nonce,
address(L1Bridge),
address(L2Bridge),
600,
60000,
message
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 600, 60000, message
);
uint64 baseGas = L1Messenger.baseGas(message, 60000);
vm.expectCall(
address(op),
abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector,
address(L2Messenger),
600,
baseGas,
false,
innerMessage
OptimismPortal.depositTransaction.selector, address(L2Messenger), 600, baseGas, false, innerMessage
)
);
bytes memory opaqueData = abi.encodePacked(
uint256(600),
uint256(600),
baseGas,
false,
innerMessage
);
bytes memory opaqueData = abi.encodePacked(uint256(600), uint256(600), baseGas, false, innerMessage);
vm.expectEmit(true, true, true, true, address(L1Bridge));
emit ETHDepositInitiated(alice, bob, 600, hex"dead");
......@@ -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 {
using stdStorage for StdStorage;
......@@ -365,61 +295,32 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {
// The L1Bridge should transfer alice's tokens to itself
vm.expectCall(
address(L1Token),
abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)
address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)
);
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L2Token),
address(L1Token),
alice,
alice,
100,
hex""
StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, alice, 100, hex""
);
// the L1 bridge should call L1CrossDomainMessenger.sendMessage
vm.expectCall(
address(L1Messenger),
abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
10000
)
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000)
);
bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector,
nonce,
address(L1Bridge),
address(L2Bridge),
0,
10000,
message
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message
);
uint64 baseGas = L1Messenger.baseGas(message, 10000);
vm.expectCall(
address(op),
abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector,
address(L2Messenger),
0,
baseGas,
false,
innerMessage
OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage
)
);
bytes memory opaqueData = abi.encodePacked(
uint256(0),
uint256(0),
baseGas,
false,
innerMessage
);
bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage);
// Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L1Bridge));
......@@ -472,33 +373,15 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L2Token),
address(L1Token),
alice,
bob,
1000,
hex""
StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, bob, 1000, hex""
);
bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector,
nonce,
address(L1Bridge),
address(L2Bridge),
0,
10000,
message
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message
);
uint64 baseGas = L1Messenger.baseGas(message, 10000);
bytes memory opaqueData = abi.encodePacked(
uint256(0),
uint256(0),
baseGas,
false,
innerMessage
);
bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage);
deal(address(L1Token), alice, 100000, true);
......@@ -527,28 +410,17 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {
// the L1 bridge should call L1CrossDomainMessenger.sendMessage
vm.expectCall(
address(L1Messenger),
abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector,
address(L2Bridge),
message,
10000
)
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000)
);
// The L1 XDM should call OptimismPortal.depositTransaction
vm.expectCall(
address(op),
abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector,
address(L2Messenger),
0,
baseGas,
false,
innerMessage
OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage
)
);
vm.expectCall(
address(L1Token),
abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)
address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)
);
vm.prank(alice);
......@@ -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 {
using stdStorage for StdStorage;
......@@ -602,12 +474,8 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
function test_finalizeERC20Withdrawal_succeeds() external {
deal(address(L1Token), address(L1Bridge), 100, true);
uint256 slot = stdstore
.target(address(L1Bridge))
.sig("deposits(address,address)")
.with_key(address(L1Token))
.with_key(address(L2Token))
.find();
uint256 slot = stdstore.target(address(L1Bridge)).sig("deposits(address,address)").with_key(address(L1Token))
.with_key(address(L2Token)).find();
// Give the L1 bridge some ERC20 tokens
vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));
......@@ -619,10 +487,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
vm.expectEmit(true, true, true, true, address(L1Bridge));
emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex"");
vm.expectCall(
address(L1Token),
abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)
);
vm.expectCall(address(L1Token), abi.encodeWithSelector(ERC20.transfer.selector, alice, 100));
vm.mockCall(
address(L1Bridge.messenger()),
......@@ -630,14 +495,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
abi.encode(address(L1Bridge.OTHER_BRIDGE()))
);
vm.prank(address(L1Bridge.messenger()));
L1Bridge.finalizeERC20Withdrawal(
address(L1Token),
address(L2Token),
alice,
alice,
100,
hex""
);
L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
assertEq(L1Token.balanceOf(address(L1Bridge)), 0);
assertEq(L1Token.balanceOf(address(alice)), 100);
......@@ -654,14 +512,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer
);
vm.prank(address(28));
vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal(
address(L1Token),
address(L2Token),
alice,
alice,
100,
hex""
);
L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
}
/// @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
);
vm.prank(address(L1Bridge.messenger()));
vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal(
address(L1Token),
address(L2Token),
alice,
alice,
100,
hex""
);
L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
}
}
......
......@@ -29,14 +29,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
/// @dev Tests that `sendMessage` executes successfully.
function test_sendMessage_succeeds() external {
bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(
L2Messenger.messageNonce(),
alice,
recipient,
0,
100,
hex"ff"
);
bytes memory xDomainCallData =
Encoding.encodeCrossDomainMessage(L2Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff");
vm.expectCall(
address(messagePasser),
abi.encodeWithSelector(
......@@ -95,9 +89,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
// Expect a revert.
vm.expectRevert(
"CrossDomainMessenger: only version 0 or 1 messages are supported at this time"
);
vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
// Try to relay a v2 message.
vm.prank(caller);
......@@ -123,14 +115,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true);
bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce(0, 1),
sender,
target,
0,
0,
hex"1111"
);
bytes32 hash =
Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, hex"1111");
emit RelayedMessage(hash);
......@@ -159,14 +145,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
vm.prank(caller);
vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage(
Encoding.encodeVersionedNonce(0, 1),
sender,
target,
0,
0,
message
);
L1Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message);
}
/// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender`
......@@ -177,14 +156,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
vm.prank(caller);
L2Messenger.relayMessage(
Encoding.encodeVersionedNonce(0, 1),
address(0),
address(0),
0,
0,
hex""
);
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex"");
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender();
......@@ -199,14 +171,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
uint256 value = 100;
bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce(0, 1),
sender,
target,
value,
0,
hex"1111"
);
bytes32 hash =
Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, value, 0, hex"1111");
vm.etch(target, address(new Reverter()).code);
vm.deal(address(caller), value);
......
......@@ -13,7 +13,7 @@ import { OptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.
import { L2ERC721Bridge } from "../src/L2/L2ERC721Bridge.sol";
contract TestERC721 is ERC721 {
constructor() ERC721("Test", "TST") {}
constructor() ERC721("Test", "TST") { }
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
......@@ -21,9 +21,12 @@ contract TestERC721 is ERC721 {
}
contract TestMintableERC721 is OptimismMintableERC721 {
constructor(address _bridge, address _remoteToken)
constructor(
address _bridge,
address _remoteToken
)
OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST")
{}
{ }
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
......@@ -88,14 +91,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
address(L1Bridge),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(
address(remoteToken),
address(localToken),
alice,
alice,
tokenId,
hex"5678"
)
(address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
),
1234
)
......@@ -104,14 +100,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Bridge the token.
vm.prank(alice);
......@@ -188,25 +177,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated(
address(localToken),
address(remoteToken),
alice,
bob,
tokenId,
hex"5678"
);
emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678");
// Bridge the token.
vm.prank(alice);
L2Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
L2Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is burned.
vm.expectRevert("ERC721: invalid token ID");
......@@ -240,14 +215,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
L2Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
L2Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -261,14 +229,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeFinalized(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Finalize a withdrawal.
vm.mockCall(
......@@ -277,14 +238,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encode(L1Bridge)
);
vm.prank(address(L2Messenger));
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -310,12 +264,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token interface is not compliant");
L2Bridge.finalizeBridgeERC721(
address(address(nonCompliantToken)),
address(address(0x01)),
alice,
alice,
tokenId,
hex"5678"
address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678"
);
}
......@@ -324,34 +273,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge.
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(alice)
address(L2Messenger), abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encode(alice)
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the
......@@ -365,14 +298,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token cannot be self");
L2Bridge.finalizeBridgeERC721(
address(L2Bridge),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L2Bridge.finalizeBridgeERC721(address(L2Bridge), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that `finalizeBridgeERC721` reverts when already finalized.
......@@ -385,14 +311,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721: token already minted");
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
}
......
......@@ -190,16 +190,10 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer {
assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);
// check timestamp for the first block after the starting block
assertEq(
oracle.computeL2Timestamp(startingBlockNumber + 1),
startingTimestamp + l2BlockTime
);
assertEq(oracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime);
// check timestamp for some other block number
assertEq(
oracle.computeL2Timestamp(startingBlockNumber + 96024),
startingTimestamp + l2BlockTime * 96024
);
assertEq(oracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024);
}
}
......@@ -271,15 +265,8 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer {
uint256 nextBlockNumber = oracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber);
vm.prank(proposer);
vm.expectRevert(
"L2OutputOracle: block hash does not match the hash at the expected height"
);
oracle.proposeL2Output(
nonZeroHash,
nextBlockNumber,
bytes32(uint256(0x01)),
block.number - 1
);
vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number - 1);
}
/// @dev Tests that `proposeL2Output` reverts when given a block number
......@@ -297,9 +284,7 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer {
vm.prank(proposer);
// This will fail when foundry no longer returns zerod block hashes
vm.expectRevert(
"L2OutputOracle: block hash does not match the hash at the expected height"
);
vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);
}
}
......@@ -478,10 +463,7 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
NextImpl nextImpl = new NextImpl();
vm.startPrank(multisig);
proxy.upgradeToAndCall(
address(nextImpl),
abi.encodeWithSelector(NextImpl.initialize.selector, 3)
);
proxy.upgradeToAndCall(address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 3));
assertEq(proxy.implementation(), address(nextImpl));
// Verify that the NextImpl contract initialized its values according as expected
......
......@@ -33,13 +33,8 @@ contract L2StandardBridge_Test is Bridge_Initializer {
assertEq(address(messagePasser).balance, 0);
uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeETH.selector,
alice,
alice,
100,
hex""
);
bytes memory message =
abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex"");
uint64 baseGas = L2Messenger.baseGas(message, 200_000);
bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector,
......@@ -70,13 +65,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
// L2ToL1MessagePasser will emit a MessagePassed event
vm.expectEmit(true, true, true, true, address(messagePasser));
emit MessagePassed(
nonce,
address(L2Messenger),
address(L1Messenger),
100,
baseGas,
withdrawalData,
withdrawalHash
nonce, address(L2Messenger), address(L1Messenger), 100, baseGas, withdrawalData, withdrawalHash
);
// SentMessage event emitted by the CrossDomainMessenger
......@@ -100,15 +89,12 @@ contract L2StandardBridge_Test is Bridge_Initializer {
vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector,
address(L1Messenger),
baseGas,
withdrawalData
L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData
)
);
vm.prank(alice, alice);
(bool success, ) = address(L2Bridge).call{ value: 100 }(hex"");
(bool success,) = address(L2Bridge).call{ value: 100 }(hex"");
assertEq(success, true);
assertEq(address(messagePasser).balance, 100);
}
......@@ -161,23 +147,11 @@ contract PreBridgeERC20 is Bridge_Initializer {
assertEq(ERC20(_l2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L1Token),
_l2Token,
alice,
alice,
100,
hex""
StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex""
);
uint64 baseGas = L2Messenger.baseGas(message, 1000);
bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector,
nonce,
address(L2Bridge),
address(L1Bridge),
0,
1000,
message
CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message
);
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({
......@@ -192,48 +166,29 @@ contract PreBridgeERC20 is Bridge_Initializer {
if (_isLegacy) {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"")
address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"")
);
} else {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.bridgeERC20.selector,
_l2Token,
address(L1Token),
100,
1000,
hex""
)
abi.encodeWithSelector(L2Bridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex"")
);
}
vm.expectCall(
address(L2Messenger),
abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector,
address(L1Bridge),
message,
1000
)
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000)
);
vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector,
address(L1Messenger),
baseGas,
withdrawalData
L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData
)
);
// The L2Bridge should burn the tokens
vm.expectCall(
_l2Token,
abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)
);
vm.expectCall(_l2Token, abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100));
vm.expectEmit(true, true, true, true);
emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex"");
......@@ -243,13 +198,7 @@ contract PreBridgeERC20 is Bridge_Initializer {
vm.expectEmit(true, true, true, true);
emit MessagePassed(
nonce,
address(L2Messenger),
address(L1Messenger),
0,
baseGas,
withdrawalData,
withdrawalHash
nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash
);
// SentMessage event emitted by the CrossDomainMessenger
......@@ -318,23 +267,11 @@ contract PreBridgeERC20To is Bridge_Initializer {
assertEq(ERC20(L2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L1Token),
_l2Token,
alice,
bob,
100,
hex""
StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex""
);
uint64 baseGas = L2Messenger.baseGas(message, 1000);
bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector,
nonce,
address(L2Bridge),
address(L1Bridge),
0,
1000,
message
CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message
);
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({
......@@ -355,13 +292,7 @@ contract PreBridgeERC20To is Bridge_Initializer {
vm.expectEmit(true, true, true, true, address(messagePasser));
emit MessagePassed(
nonce,
address(L2Messenger),
address(L1Messenger),
0,
baseGas,
withdrawalData,
withdrawalHash
nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash
);
// SentMessage event emitted by the CrossDomainMessenger
......@@ -374,56 +305,31 @@ contract PreBridgeERC20To is Bridge_Initializer {
if (_isLegacy) {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.withdrawTo.selector,
_l2Token,
bob,
100,
1000,
hex""
)
address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"")
);
} else {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.bridgeERC20To.selector,
_l2Token,
address(L1Token),
bob,
100,
1000,
hex""
L2Bridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex""
)
);
}
vm.expectCall(
address(L2Messenger),
abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector,
address(L1Bridge),
message,
1000
)
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000)
);
vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector,
address(L1Messenger),
baseGas,
withdrawalData
L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData
)
);
// The L2Bridge should burn the tokens
vm.expectCall(
address(L2Token),
abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)
);
vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100));
vm.prank(alice, alice);
}
......@@ -460,10 +366,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
abi.encode(address(L2Bridge.OTHER_BRIDGE()))
);
vm.expectCall(
address(L2Token),
abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)
);
vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100));
// Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L2Bridge));
......
......@@ -40,7 +40,9 @@ contract L2ToL1MessagePasserTest is CommonTest {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
uint256 nonce = messagePasser.messageNonce();
bytes32 withdrawalHash = Hashing.hashWithdrawal(
......@@ -72,28 +74,13 @@ contract L2ToL1MessagePasserTest is CommonTest {
/// log when called by a contract.
function test_initiateWithdrawal_fromContract_succeeds() external {
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction(
messagePasser.messageNonce(),
address(this),
address(4),
100,
64000,
hex""
)
Types.WithdrawalTransaction(messagePasser.messageNonce(), address(this), address(4), 100, 64000, hex"")
);
vm.expectEmit(true, true, true, true);
emit MessagePassed(
messagePasser.messageNonce(),
address(this),
address(4),
100,
64000,
hex"",
withdrawalHash
);
emit MessagePassed(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"");
}
......@@ -108,10 +95,9 @@ contract L2ToL1MessagePasserTest is CommonTest {
// EOA emulation
vm.prank(alice, alice);
vm.deal(alice, 2**64);
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)
);
vm.deal(alice, 2 ** 64);
bytes32 withdrawalHash =
Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data));
vm.expectEmit(true, true, true, true);
emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);
......@@ -126,11 +112,7 @@ contract L2ToL1MessagePasserTest is CommonTest {
/// @dev Tests that `burn` succeeds and destroys the ETH held in the contract.
function test_burn_succeeds() external {
messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS,
NON_ZERO_GASLIMIT,
NON_ZERO_DATA
);
messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(NON_ZERO_ADDRESS, NON_ZERO_GASLIMIT, NON_ZERO_DATA);
assertEq(address(messagePasser).balance, NON_ZERO_VALUE);
vm.expectEmit(true, false, false, false);
......
......@@ -15,7 +15,7 @@ contract LibPosition_Test is Test {
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal view returns (uint64) {
// Index at depth bound: [0, 2 ** _depth-1]
if (_depth > 0) {
return uint64(bound(_indexAtDepth, 0, 2**(_depth - 1)));
return uint64(bound(_indexAtDepth, 0, 2 ** (_depth - 1)));
} else {
return 0;
}
......@@ -29,7 +29,8 @@ contract LibPosition_Test is Test {
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 {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......@@ -76,9 +77,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `traceAncestor` function correctly computes the position of the
/// highest ancestor that commits to the same trace index.
function testFuzz_traceAncestor_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth)
public
{
function testFuzz_traceAncestor_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......@@ -94,11 +93,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
/// to a given position.
function testFuzz_rightIndex_correctness_succeeds(
uint64 _maxDepth,
uint8 _depth,
uint64 _indexAtDepth
) public {
function testFuzz_rightIndex_correctness_succeeds(uint64 _maxDepth, uint8 _depth, uint64 _indexAtDepth) public {
// Max depth bound: [1, 63]
// The max game depth MUST be at least 1.
_maxDepth = uint8(bound(_maxDepth, 1, MAX_DEPTH));
......
......@@ -34,7 +34,8 @@ contract MIPS_Test is Test {
step: 1,
registers: registers
});
bytes memory proof = hex"3c10bfff3610fff0341100013c08ffff3508fffd34090003010950202d420001ae020008ae11000403e000080000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618db8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
bytes memory proof =
hex"3c10bfff3610fff0341100013c08ffff3508fffd34090003010950202d420001ae020008ae11000403e000080000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618db8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
bytes32 postState = mips.step(encodeState(state), proof);
assertTrue(postState != bytes32(0));
......@@ -42,7 +43,7 @@ contract MIPS_Test is Test {
function encodeState(MIPS.State memory state) internal pure returns (bytes memory) {
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]));
}
return abi.encodePacked(
......
......@@ -10,12 +10,9 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b6579326262";
bytes memory val = hex"6176616c32";
bytes[] memory proof = new bytes[](3);
proof[
0
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[
1
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[1] =
hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[2] = hex"ca83206262856176616c32";
assertEq(val, MerkleTrie.get(key, proof, root));
......@@ -24,18 +21,12 @@ contract MerkleTrie_get_Test is CommonTest {
function test_get_validProof2_succeeds() external {
bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
bytes memory key = hex"6b6579316161";
bytes
memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
bytes memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
bytes[] memory proof = new bytes[](3);
proof[
0
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[
1
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[
2
] = hex"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[1] =
hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[2] = hex"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
assertEq(val, MerkleTrie.get(key, proof, root));
}
......@@ -43,12 +34,10 @@ contract MerkleTrie_get_Test is CommonTest {
function test_get_validProof3_succeeds() external {
bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;
bytes memory key = hex"6b6579316161";
bytes
memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
bytes memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
bytes[] memory proof = new bytes[](1);
proof[
0
] = hex"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
proof[0] =
hex"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
assertEq(val, MerkleTrie.get(key, proof, root));
}
......@@ -66,18 +55,14 @@ contract MerkleTrie_get_Test is CommonTest {
function test_get_validProof5_succeeds() external {
bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;
bytes memory key = hex"6b657931";
bytes
memory val = hex"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
bytes memory val =
hex"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
bytes[] memory proof = new bytes[](3);
proof[
0
] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
proof[
1
] = hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[
2
] = hex"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
proof[1] =
hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[2] =
hex"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
assertEq(val, MerkleTrie.get(key, proof, root));
}
......@@ -87,12 +72,9 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b657932";
bytes memory val = hex"73686f7274";
bytes[] memory proof = new bytes[](3);
proof[
0
] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
proof[
1
] = hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
proof[1] =
hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[2] = hex"df808080808080c9823262856176616c338080808080808080808573686f7274";
assertEq(val, MerkleTrie.get(key, proof, root));
......@@ -103,15 +85,11 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b657933";
bytes memory val = hex"31323334353637383930313233343536373839303132333435363738393031";
bytes[] memory proof = new bytes[](3);
proof[
0
] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
proof[
1
] = hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[
2
] = hex"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031";
proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
proof[1] =
hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
proof[2] =
hex"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031";
assertEq(val, MerkleTrie.get(key, proof, root));
}
......@@ -156,12 +134,9 @@ contract MerkleTrie_get_Test is CommonTest {
bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
bytes memory key = hex"6b657932";
bytes[] memory proof = new bytes[](3);
proof[
0
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[
1
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[1] =
hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[2] = hex"ca83206262856176616c32";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
......@@ -172,9 +147,7 @@ contract MerkleTrie_get_Test is CommonTest {
bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
bytes memory key = hex"616e7972616e646f6d6b6579";
bytes[] memory proof = new bytes[](1);
proof[
0
] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
MerkleTrie.get(key, proof, root);
......@@ -185,9 +158,8 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b6579316161";
bytes[] memory proof = new bytes[](3);
proof[0] = hex"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f";
proof[
1
] = hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
proof[1] =
hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
proof[2] = hex"d687206e6f746865728d33343938683472697568677765";
vm.expectRevert("MerkleTrie: invalid internal node hash");
......@@ -199,15 +171,11 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"6b6579326262";
bytes[] memory proof = new bytes[](5);
proof[0] = hex"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2";
proof[
1
] = hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
proof[
2
] = hex"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[
3
] = hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[1] =
hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
proof[2] = hex"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
proof[3] =
hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
proof[4] = hex"ca83206262856176616c32";
vm.expectRevert("RLPReader: decoded item type for list is not a list item");
......@@ -231,9 +199,8 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"aa";
bytes[] memory proof = new bytes[](3);
proof[0] = hex"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157";
proof[
1
] = hex"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080";
proof[1] =
hex"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080";
proof[2] = hex"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f";
vm.expectRevert("MerkleTrie: invalid internal node hash");
......@@ -278,9 +245,8 @@ contract MerkleTrie_get_Test is CommonTest {
bytes memory key = hex"aa";
bytes[] memory proof = new bytes[](3);
proof[0] = hex"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905";
proof[
1
] = hex"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080";
proof[1] =
hex"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080";
proof[2] = hex"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
......@@ -303,8 +269,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
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.
(bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi
.getMerkleTrieFuzzCase("valid");
(bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("valid");
// Assert that our expected value is equal to our actual value.
assertEq(val, MerkleTrie.get(key, proof, root));
......@@ -313,9 +278,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_invalidRoot_reverts(bytes4) external {
// Get a random test case with a valid trie / proof
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(
"valid"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("valid");
bytes32 rootHash = keccak256(abi.encodePacked(root));
vm.expectRevert("MerkleTrie: invalid root hash");
......@@ -326,9 +289,7 @@ contract MerkleTrie_get_Test is CommonTest {
function testFuzz_get_extraProofElements_reverts(bytes4) external {
// Generate an invalid test case with an extra proof element attached to an otherwise
// valid proof of inclusion for the passed k/v.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(
"extra_proof_elems"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("extra_proof_elems");
vm.expectRevert("MerkleTrie: value node must be last node in proof (leaf)");
MerkleTrie.get(key, proof, root);
......@@ -337,9 +298,8 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {
// 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(
"invalid_large_internal_hash"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) =
ffi.getMerkleTrieFuzzCase("invalid_large_internal_hash");
vm.expectRevert("MerkleTrie: invalid large internal hash");
MerkleTrie.get(key, proof, root);
......@@ -348,9 +308,8 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {
// 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(
"invalid_internal_node_hash"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) =
ffi.getMerkleTrieFuzzCase("invalid_internal_node_hash");
vm.expectRevert("MerkleTrie: invalid internal node hash");
MerkleTrie.get(key, proof, root);
......@@ -359,9 +318,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_corruptedProof_reverts(bytes4) external {
// Generate an invalid test case where the proof is malformed.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(
"corrupted_proof"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("corrupted_proof");
vm.expectRevert("RLPReader: decoded item type for list is not a list item");
MerkleTrie.get(key, proof, root);
......@@ -371,9 +328,7 @@ contract MerkleTrie_get_Test is CommonTest {
function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {
// Generate an invalid test case where a random element of the proof has more bytes than the
// length designates within the RLP list encoding.
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(
"invalid_data_remainder"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("invalid_data_remainder");
vm.expectRevert("RLPReader: list item has an invalid data remainder");
MerkleTrie.get(key, proof, root);
......@@ -383,9 +338,7 @@ contract MerkleTrie_get_Test is CommonTest {
function testFuzz_get_prefixedValidKey_reverts(bytes4) external {
// Get a random test case with a valid trie / proof and a valid key that is prefixed
// with random bytes
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(
"prefixed_valid_key"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("prefixed_valid_key");
// Ambiguous revert check- all that we care is that it *does* fail. This case may
// fail within different branches.
......@@ -396,9 +349,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_emptyKey_reverts(bytes4) external {
// Get a random test case with a valid trie / proof and an empty key
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(
"empty_key"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("empty_key");
vm.expectRevert("MerkleTrie: empty key");
MerkleTrie.get(key, proof, root);
......@@ -407,9 +358,7 @@ contract MerkleTrie_get_Test is CommonTest {
/// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
function testFuzz_get_partialProof_reverts(bytes4) external {
// Get a random test case with a valid trie / partially correct proof
(bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(
"partial_proof"
);
(bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("partial_proof");
vm.expectRevert("MerkleTrie: ran out of proof elements");
MerkleTrie.get(key, proof, root);
......
......@@ -2,10 +2,7 @@
pragma solidity 0.8.15;
import { Bridge_Initializer } from "./CommonTest.t.sol";
import {
ILegacyMintableERC20,
IOptimismMintableERC20
} from "../src/universal/IOptimismMintableERC20.sol";
import { ILegacyMintableERC20, IOptimismMintableERC20 } from "../src/universal/IOptimismMintableERC20.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
contract OptimismMintableERC20_Test is Bridge_Initializer {
......@@ -87,10 +84,8 @@ contract OptimismMintableERC20_Test is Bridge_Initializer {
assertEq(iface2, type(ILegacyMintableERC20).interfaceId);
assert(L2Token.supportsInterface(iface2));
bytes4 iface3 = L2Token.remoteToken.selector ^
L2Token.bridge.selector ^
L2Token.mint.selector ^
L2Token.burn.selector;
bytes4 iface3 =
L2Token.remoteToken.selector ^ L2Token.bridge.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;
assertEq(iface3, type(IOptimismMintableERC20).interfaceId);
assert(L2Token.supportsInterface(iface3));
}
......
......@@ -6,11 +6,7 @@ import { LibRLP } from "./RLP.t.sol";
contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);
event OptimismMintableERC20Created(
address indexed localToken,
address indexed remoteToken,
address deployer
);
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
function setUp() public override {
super.setUp();
......
......@@ -2,16 +2,11 @@
pragma solidity 0.8.15;
import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {
IERC721Enumerable
} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { ERC721Bridge_Initializer } from "./CommonTest.t.sol";
import {
OptimismMintableERC721,
IOptimismMintableERC721
} from "../src/universal/OptimismMintableERC721.sol";
import { OptimismMintableERC721, IOptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.sol";
contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
ERC721 internal L1Token;
......
......@@ -10,11 +10,7 @@ import { OptimismMintableERC721Factory } from "../src/universal/OptimismMintable
contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
OptimismMintableERC721Factory internal factory;
event OptimismMintableERC721Created(
address indexed localToken,
address indexed remoteToken,
address deployer
);
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
function setUp() public override {
super.setUp();
......@@ -41,9 +37,8 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
// Create the token.
vm.prank(alice);
OptimismMintableERC721 created = OptimismMintableERC721(
factory.createOptimismMintableERC721(address(1234), "L2Token", "L2T")
);
OptimismMintableERC721 created =
OptimismMintableERC721(factory.createOptimismMintableERC721(address(1234), "L2Token", "L2T"));
// Token address should be correct.
assertEq(address(created), predicted);
......
......@@ -100,9 +100,9 @@ contract OptimismPortal_Test is Portal_Initializer {
emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex"");
// give alice money and send as an eoa
vm.deal(alice, 2**64);
vm.deal(alice, 2 ** 64);
vm.prank(alice, alice);
(bool s, ) = address(op).call{ value: 100 }(hex"");
(bool s,) = address(op).call{ value: 100 }(hex"");
assert(s);
assertEq(address(op).balance, 100);
......@@ -134,21 +134,12 @@ contract OptimismPortal_Test is Portal_Initializer {
/// @dev Tests that `depositTransaction` reverts when the gas limit is too small.
function test_depositTransaction_smallGasLimit_reverts() external {
vm.expectRevert("OptimismPortal: gas limit too small");
op.depositTransaction({
_to: address(1),
_value: 0,
_gasLimit: 0,
_isCreation: false,
_data: hex""
});
op.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" });
}
/// @dev Tests that `depositTransaction` succeeds for small,
/// but sufficient, gas limits.
function testFuzz_depositTransaction_smallGasLimit_succeeds(
bytes memory _data,
bool _shouldFail
) external {
function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external {
vm.assume(_data.length <= type(uint64).max);
uint64 gasLimit = op.minimumGasLimit(uint64(_data.length));
......@@ -157,13 +148,7 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectRevert("OptimismPortal: gas limit too small");
}
op.depositTransaction({
_to: address(0x40),
_value: 0,
_gasLimit: gasLimit,
_isCreation: false,
_data: _data
});
op.depositTransaction({ _to: address(0x40), _value: 0, _gasLimit: gasLimit, _isCreation: false, _data: _data });
}
/// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes.
......@@ -181,22 +166,10 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.prank(address(this), address(this));
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
address(this),
NON_ZERO_ADDRESS,
ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
address(this), NON_ZERO_ADDRESS, ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
);
op.depositTransaction(
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
);
op.depositTransaction(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.
......@@ -212,13 +185,7 @@ contract OptimismPortal_Test is Portal_Initializer {
NON_ZERO_DATA
);
op.depositTransaction(
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
);
op.depositTransaction(NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA);
}
/// @dev Tests that `depositTransaction` succeeds for an EOA
......@@ -229,13 +196,7 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
address(this),
ZERO_ADDRESS,
ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
NON_ZERO_DATA
address(this), 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);
......@@ -265,21 +226,11 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
address(this),
NON_ZERO_ADDRESS,
NON_ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
address(this), NON_ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
);
op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
);
assertEq(address(op).balance, NON_ZERO_VALUE);
}
......@@ -298,11 +249,7 @@ contract OptimismPortal_Test is Portal_Initializer {
);
op.depositTransaction{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
false,
NON_ZERO_DATA
NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA
);
}
......@@ -313,22 +260,10 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
address(this),
ZERO_ADDRESS,
NON_ZERO_VALUE,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
hex""
address(this), ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex""
);
op.depositTransaction{ value: NON_ZERO_VALUE }(
ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
hex""
);
op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex"");
assertEq(address(op).balance, NON_ZERO_VALUE);
}
......@@ -345,13 +280,7 @@ contract OptimismPortal_Test is Portal_Initializer {
NON_ZERO_DATA
);
op.depositTransaction{ value: NON_ZERO_VALUE }(
ZERO_ADDRESS,
ZERO_VALUE,
NON_ZERO_GASLIMIT,
true,
NON_ZERO_DATA
);
op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);
assertEq(address(op).balance, NON_ZERO_VALUE);
}
......@@ -361,9 +290,7 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.mockCall(
address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(
Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))
)
abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber)))
);
// warp to the finalization period
......@@ -428,8 +355,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
data: hex""
});
// Get withdrawal proof data we can use for testing.
(_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi
.getProveWithdrawalTransactionInputs(_defaultTx);
(_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) =
ffi.getProveWithdrawalTransactionInputs(_defaultTx);
// Setup a dummy output root proof for reuse.
_outputRootProof = Types.OutputRootProof({
......@@ -450,11 +377,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed.
vm.warp(
oracle.getL2Output(_proposedOutputIndex).timestamp +
oracle.FINALIZATION_PERIOD_SECONDS() +
1
);
vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF);
}
......@@ -487,12 +410,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_onSelfCall_reverts() external {
_defaultTx.target = address(op);
vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract");
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
}
/// @dev Tests that `proveWithdrawalTransaction` reverts when
......@@ -501,12 +419,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Modify the version to invalidate the withdrawal proof.
_outputRootProof.version = bytes32(uint256(1));
vm.expectRevert("OptimismPortal: invalid output root proof");
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
}
/// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing.
......@@ -514,12 +427,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// modify the default test values to invalidate the proof.
_defaultTx.data = hex"abcd";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
}
/// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already
......@@ -527,20 +435,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_replayProve_reverts() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.expectRevert("OptimismPortal: withdrawal hash has already been proven");
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
}
/// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already
......@@ -548,12 +446,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`
// inside of the `provenWithdrawal`s mapping.
......@@ -575,31 +468,19 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// our proof with a changed outputRoot
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Ensure that the withdrawal was updated within the mapping
(, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);
(, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash);
assertEq(timestamp, block.timestamp);
}
/// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already
/// been proven and the output root, output index, and l2BlockNumber have changed.
function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()
external
{
function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`
// inside of the `provenWithdrawal`s mapping.
......@@ -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.
vm.startPrank(op.L2_ORACLE().PROPOSER());
op.L2_ORACLE().proposeL2Output(
proposal.outputRoot,
op.L2_ORACLE().nextBlockNumber(),
blockhash(block.number),
block.number
proposal.outputRoot, op.L2_ORACLE().nextBlockNumber(), blockhash(block.number), block.number
);
vm.stopPrank();
......@@ -634,15 +512,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// our proof with a changed outputRoot + a different output index
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex + 1,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof);
// Ensure that the withdrawal was updated within the mapping
(, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);
(, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash);
assertEq(timestamp, block.timestamp);
}
......@@ -650,12 +523,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
}
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds.
......@@ -664,12 +532,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, false, true);
......@@ -705,12 +568,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Mock a call where the resulting output root is anything but the original output root. In
// this case we just use bytes32(uint256(1)).
......@@ -734,27 +592,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock a startingTimestamp change on the L2 Oracle
vm.mockCall(
address(op.L2_ORACLE()),
abi.encodeWithSignature("startingTimestamp()"),
abi.encode(block.timestamp + 1)
address(op.L2_ORACLE()), abi.encodeWithSignature("startingTimestamp()"), abi.encode(block.timestamp + 1)
);
// Attempt to finalize the withdrawal
vm.expectRevert(
"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp"
);
vm.expectRevert("OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp");
op.finalizeWithdrawalTransaction(_defaultTx);
// Ensure that bob's balance has remained the same
......@@ -769,12 +618,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
......@@ -785,18 +629,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(
Types.OutputProposal(
bytes32(uint256(0)),
uint128(block.timestamp),
uint128(_proposedBlockNumber)
)
Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber))
)
);
// Attempt to finalize the withdrawal
vm.expectRevert(
"OptimismPortal: output root proven is not the same as current output root"
);
vm.expectRevert("OptimismPortal: output root proven is not the same as current output root");
op.finalizeWithdrawalTransaction(_defaultTx);
// Ensure that bob's balance has remained the same
......@@ -811,12 +649,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
......@@ -826,13 +659,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.mockCall(
address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(
Types.OutputProposal(
_outputRoot,
uint128(block.timestamp + 1),
uint128(_proposedBlockNumber)
)
)
abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber)))
);
// Attempt to finalize the withdrawal
......@@ -850,12 +677,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true);
......@@ -873,21 +695,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.mockCall(
address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(
Types.OutputProposal(
_outputRoot,
uint128(recentTimestamp),
uint128(_proposedBlockNumber)
)
)
abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber)))
);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed");
op.finalizeWithdrawalTransaction(_defaultTx);
......@@ -898,12 +709,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_finalizeWithdrawalTransaction_onReplay_reverts() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true);
......@@ -929,8 +735,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
});
// Get updated proof inputs.
(bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi
.getProveWithdrawalTransactionInputs(insufficientGasTx);
(bytes32 stateRoot, bytes32 storageRoot,,, bytes[] memory withdrawalProof) =
ffi.getProveWithdrawalTransactionInputs(insufficientGasTx);
Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({
version: bytes32(0),
stateRoot: stateRoot,
......@@ -950,12 +756,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
)
);
op.proveWithdrawalTransaction(
insufficientGasTx,
_proposedOutputIndex,
outputRootProof,
withdrawalProof
);
op.proveWithdrawalTransaction(insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectRevert("SafeCall: Not enough gas");
......@@ -993,23 +794,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.mockCall(
address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(
Types.OutputProposal(
outputRoot,
uint128(finalizedTimestamp),
uint128(_proposedBlockNumber)
)
)
abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber)))
);
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(withdrawalHash, alice, address(this));
op.proveWithdrawalTransaction(
_testTx,
_proposedBlockNumber,
outputRootProof,
withdrawalProof
);
op.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectCall(address(this), _testTx.data);
......@@ -1028,12 +818,14 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
vm.assume(
_target != address(op) && // Cannot call the optimism portal or a contract
_target.code.length == 0 && // No accounts with code
_target != CONSOLE && // The console has no code but behaves like a contract
uint160(_target) > 9 // No precompiles (or zero address)
_target != address(op) // Cannot call the optimism portal or a contract
&& _target.code.length == 0 // No accounts with code
&& _target != CONSOLE // The console has no code but behaves like a contract
&& uint160(_target) > 9 // No precompiles (or zero address)
);
// Total ETH supply is currently about 120M ETH.
......@@ -1086,7 +878,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
proof,
withdrawalProof
);
(bytes32 _root, , ) = op.provenWithdrawals(withdrawalHash);
(bytes32 _root,,) = op.provenWithdrawals(withdrawalHash);
assertTrue(_root != bytes32(0));
// Warp past the finalization period
......@@ -1154,10 +946,7 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
vm.startPrank(multisig);
// The value passed to the initialize must be larger than the last value
// that initialize was called with.
proxy.upgradeToAndCall(
address(nextImpl),
abi.encodeWithSelector(NextImpl.initialize.selector, 3)
);
proxy.upgradeToAndCall(address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 3));
assertEq(proxy.implementation(), address(nextImpl));
// Verify that the NextImpl contract initialized its values according as expected
......@@ -1187,7 +976,9 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
uint64 _prevBoughtGas,
uint128 _prevBaseFee,
uint8 _blockDiff
) external {
)
external
{
// Get the set system gas limit
uint64 gasLimit = systemConfig.gasLimit();
// Bound resource config
......@@ -1200,10 +991,7 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
vm.assume(_baseFeeMaxChangeDenominator > 1);
vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit);
vm.assume(_elasticityMultiplier > 0);
vm.assume(
((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) ==
_maxResourceLimit
);
vm.assume(((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) == _maxResourceLimit);
_prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit));
_blockDiff = uint8(bound(_blockDiff, 0, 3));
......@@ -1217,9 +1005,7 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
maximumBaseFee: _maximumBaseFee
});
vm.mockCall(
address(systemConfig),
abi.encodeWithSelector(systemConfig.resourceConfig.selector),
abi.encode(rcfg)
address(systemConfig), abi.encodeWithSelector(systemConfig.resourceConfig.selector), abi.encode(rcfg)
);
// Set the resource params
......
......@@ -23,10 +23,7 @@ interface IMulticall3 {
bytes returnData;
}
function aggregate3(Call3[] calldata calls)
external
payable
returns (Result[] memory returnData);
function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);
}
library Multicall {
......@@ -38,17 +35,11 @@ library Multicall {
contract Optimist_Initializer is Test {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Initialized(uint8);
event AttestationCreated(
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
string constant name = "Optimist name";
string constant symbol = "OPTIMISTSYMBOL";
string constant base_uri =
"https://storageapi.fleek.co/6442819a1b05-bucket/optimist-nft/attributes";
string constant base_uri = "https://storageapi.fleek.co/6442819a1b05-bucket/optimist-nft/attributes";
AttestationStation attestationStation;
Optimist optimist;
OptimistAllowlist optimistAllowlist;
......@@ -70,21 +61,12 @@ contract Optimist_Initializer is Test {
/// @notice BaseURI attestor sets the baseURI of the Optimist NFT.
function _attestBaseURI(string memory _baseUri) internal {
bytes32 baseURIAttestationKey = optimist.BASE_URI_ATTESTATION_KEY();
AttestationStation.AttestationData[]
memory attestationData = new AttestationStation.AttestationData[](1);
attestationData[0] = AttestationStation.AttestationData(
address(optimist),
baseURIAttestationKey,
bytes(_baseUri)
);
AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
attestationData[0] =
AttestationStation.AttestationData(address(optimist), baseURIAttestationKey, bytes(_baseUri));
vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(
carol_baseURIAttestor,
address(optimist),
baseURIAttestationKey,
bytes(_baseUri)
);
emit AttestationCreated(carol_baseURIAttestor, address(optimist), baseURIAttestationKey, bytes(_baseUri));
vm.prank(carol_baseURIAttestor);
attestationStation.attest(attestationData);
}
......@@ -92,14 +74,10 @@ contract Optimist_Initializer is Test {
/// @notice Allowlist attestor creates an attestation for an address.
function _attestAllowlist(address _about) internal {
bytes32 attestationKey = optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY();
AttestationStation.AttestationData[]
memory attestationData = new AttestationStation.AttestationData[](1);
AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({
about: _about,
key: attestationKey,
val: bytes("true")
});
attestationData[0] =
AttestationStation.AttestationData({ about: _about, key: attestationKey, val: bytes("true") });
vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(alice_allowlistAttestor, _about, attestationKey, bytes("true"));
......@@ -113,14 +91,10 @@ contract Optimist_Initializer is Test {
/// @notice Coinbase Quest attestor creates an attestation for an address.
function _attestCoinbaseQuest(address _about) internal {
bytes32 attestationKey = optimistAllowlist.COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY();
AttestationStation.AttestationData[]
memory attestationData = new AttestationStation.AttestationData[](1);
AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({
about: _about,
key: attestationKey,
val: bytes("true")
});
attestationData[0] =
AttestationStation.AttestationData({ about: _about, key: attestationKey, val: bytes("true") });
vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(ted_coinbaseAttestor, _about, attestationKey, bytes("true"));
......@@ -145,15 +119,12 @@ contract Optimist_Initializer is Test {
optimistInviter.setInviteCounts(addresses, 3);
// issue a new invite
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper
.getClaimableInviteWithNewNonce(inviter);
OptimistInviter.ClaimableInvite memory claimableInvite =
optimistInviterHelper.getClaimableInviteWithNewNonce(inviter);
// EIP-712 sign with Inviter's private key
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
inviterPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(inviterPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
bytes memory signature = abi.encodePacked(r, s, v);
bytes32 hashedCommit = keccak256(abi.encode(_about, signature));
......@@ -492,10 +463,7 @@ contract OptimistTest is Optimist_Initializer {
// expect approval amount to stil be 0
assertEq(optimist.getApproved(_getTokenId(bob)), address(0));
// isApprovedForAll should return false
assertEq(
optimist.isApprovedForAll(alice_allowlistAttestor, alice_allowlistAttestor),
false
);
assertEq(optimist.isApprovedForAll(alice_allowlistAttestor, alice_allowlistAttestor), false);
}
/// @notice Only owner should be able to burn token.
......@@ -554,15 +522,12 @@ contract OptimistTest is Optimist_Initializer {
optimistInviter.setInviteCounts(addresses, 3);
// issue a new invite
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper
.getClaimableInviteWithNewNonce(inviter);
OptimistInviter.ClaimableInvite memory claimableInvite =
optimistInviterHelper.getClaimableInviteWithNewNonce(inviter);
// EIP-712 sign with Inviter's private key
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
inviterPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(inviterPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
bytes memory signature = abi.encodePacked(r, s, v);
bytes32 hashedCommit = keccak256(abi.encode(bob, signature));
......@@ -579,12 +544,7 @@ contract OptimistTest is Optimist_Initializer {
// First call is to claim the invite, receiving the attestation
calls[0] = IMulticall3.Call3({
target: address(optimistInviter),
callData: abi.encodeWithSelector(
optimistInviter.claimInvite.selector,
bob,
claimableInvite,
signature
),
callData: abi.encodeWithSelector(optimistInviter.claimInvite.selector, bob, claimableInvite, signature),
allowFailure: false
});
......
......@@ -10,12 +10,8 @@ import { OptimistInviterHelper } from "./Helpers.sol";
import { OptimistConstants } from "../src/periphery/op-nft/libraries/OptimistConstants.sol";
contract OptimistAllowlist_Initializer is Test {
event AttestationCreated(
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
address internal alice_allowlistAttestor;
address internal sally_coinbaseQuestAttestor;
address internal ted;
......@@ -49,8 +45,7 @@ contract OptimistAllowlist_Initializer is Test {
}
function attestAllowlist(address _about) internal {
AttestationStation.AttestationData[]
memory attestationData = new AttestationStation.AttestationData[](1);
AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({
about: _about,
......@@ -62,8 +57,7 @@ contract OptimistAllowlist_Initializer is Test {
}
function attestCoinbaseQuest(address _about) internal {
AttestationStation.AttestationData[]
memory attestationData = new AttestationStation.AttestationData[](1);
AttestationStation.AttestationData[] memory attestationData = new AttestationStation.AttestationData[](1);
// we are using true but it can be any non empty value
attestationData[0] = AttestationStation.AttestationData({
about: _about,
......@@ -84,14 +78,11 @@ contract OptimistAllowlist_Initializer is Test {
optimistInviter.setInviteCounts(addresses, 3);
// issue a new invite
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper
.getClaimableInviteWithNewNonce(bob);
OptimistInviter.ClaimableInvite memory claimableInvite =
optimistInviterHelper.getClaimableInviteWithNewNonce(bob);
// EIP-712 sign with Bob's private key
bytes memory signature = _getSignature(
bobPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
bytes memory signature = _getSignature(bobPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
bytes32 hashedCommit = keccak256(abi.encode(claimer, signature));
......@@ -107,11 +98,7 @@ contract OptimistAllowlist_Initializer is Test {
}
/// @notice Get signature as a bytes blob, since SignatureChecker takes arbitrary signature blobs.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest)
internal
pure
returns (bytes memory)
{
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v);
......@@ -173,11 +160,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
function test_isAllowedToMint_fromWrongAllowlistAttestor_fails() external {
// Ted is not the allowlist attestor
vm.prank(ted);
attestationStation.attest(
bob,
optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(),
bytes("true")
);
attestationStation.attest(bob, optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(), bytes("true"));
assertFalse(optimistAllowlist.isAllowedToMint(bob));
}
......@@ -185,11 +168,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
function test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() external {
// Ted is not the coinbase quest attestor
vm.prank(ted);
attestationStation.attest(
bob,
optimistAllowlist.COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY(),
bytes("true")
);
attestationStation.attest(bob, optimistAllowlist.COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY(), bytes("true"));
assertFalse(optimistAllowlist.isAllowedToMint(bob));
}
......@@ -197,11 +176,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
/// minting.
function test_isAllowedToMint_fromWrongOptimistInviter_fails() external {
vm.prank(ted);
attestationStation.attest(
bob,
OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY,
bytes("true")
);
attestationStation.attest(bob, OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY, bytes("true"));
assertFalse(optimistAllowlist.isAllowedToMint(bob));
}
......@@ -215,11 +190,7 @@ contract OptimistAllowlistTest is OptimistAllowlist_Initializer {
// A invalid attestation, as Ted is not allowlist attestor
vm.prank(ted);
attestationStation.attest(
bob,
optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(),
bytes("true")
);
attestationStation.attest(bob, optimistAllowlist.OPTIMIST_CAN_MINT_ATTESTATION_KEY(), bytes("true"));
// Since Bob has at least one valid attestation, he should be allowed to mint
assertTrue(optimistAllowlist.isAllowedToMint(bob));
......
......@@ -15,12 +15,7 @@ contract OptimistInviter_Initializer is Test {
event InviteClaimed(address indexed issuer, address indexed claimer);
event Initialized(uint8 version);
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event AttestationCreated(
address indexed creator,
address indexed about,
bytes32 indexed key,
bytes val
);
event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val);
bytes32 EIP712_DOMAIN_TYPEHASH;
......@@ -62,9 +57,8 @@ contract OptimistInviter_Initializer is Test {
vm.deal(ted, 1 ether);
vm.deal(eve, 1 ether);
EIP712_DOMAIN_TYPEHASH = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
EIP712_DOMAIN_TYPEHASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
_initializeContracts();
}
......@@ -94,19 +88,13 @@ contract OptimistInviter_Initializer is Test {
/// @notice Returns true if claimer has the proper attestation from OptimistInviter to mint.
function _hasMintAttestation(address _claimer) internal view returns (bool) {
bytes memory attestation = attestationStation.attestations(
address(optimistInviter),
_claimer,
OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
address(optimistInviter), _claimer, OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY
);
return attestation.length > 0;
}
/// @notice Get signature as a bytes blob, since SignatureChecker takes arbitrary signature blobs.
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest)
internal
pure
returns (bytes memory)
{
function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);
bytes memory signature = abi.encodePacked(r, s, v);
......@@ -119,8 +107,7 @@ contract OptimistInviter_Initializer is Test {
internal
returns (OptimistInviter.ClaimableInvite memory, bytes memory)
{
return
_issueInviteWithEIP712Domain(
return _issueInviteWithEIP712Domain(
_privateKey,
bytes("OptimistInviter"),
bytes(optimistInviter.EIP712_VERSION()),
......@@ -138,20 +125,19 @@ contract OptimistInviter_Initializer is Test {
bytes memory _eip712Version,
uint256 _eip712Chainid,
address _eip712VerifyingContract
) internal returns (OptimistInviter.ClaimableInvite memory, bytes memory) {
)
internal
returns (OptimistInviter.ClaimableInvite memory, bytes memory)
{
address issuer = vm.addr(_issuerPrivateKey);
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper
.getClaimableInviteWithNewNonce(issuer);
OptimistInviter.ClaimableInvite memory claimableInvite =
optimistInviterHelper.getClaimableInviteWithNewNonce(issuer);
return (
claimableInvite,
_getSignature(
_issuerPrivateKey,
optimistInviterHelper.getDigestWithEIP712Domain(
claimableInvite,
_eip712Name,
_eip712Version,
_eip712Chainid,
_eip712VerifyingContract
claimableInvite, _eip712Name, _eip712Version, _eip712Chainid, _eip712VerifyingContract
)
)
);
......@@ -170,24 +156,22 @@ contract OptimistInviter_Initializer is Test {
/// @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
/// correctly. Returns the signature and invite for use in tests.
function _issueThenClaimShouldSucceed(uint256 _issuerPrivateKey, address _claimer)
function _issueThenClaimShouldSucceed(
uint256 _issuerPrivateKey,
address _claimer
)
internal
returns (OptimistInviter.ClaimableInvite memory, bytes memory)
{
address issuer = vm.addr(_issuerPrivateKey);
uint256 prevInviteCount = _getInviteCount(issuer);
(
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteAs(_issuerPrivateKey);
(OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) =
_issueInviteAs(_issuerPrivateKey);
_commitInviteAs(_claimer, signature);
// The hash(claimer ++ signature) should be committed
assertEq(
optimistInviter.commitmentTimestamps(keccak256(abi.encode(_claimer, signature))),
block.timestamp
);
assertEq(optimistInviter.commitmentTimestamps(keccak256(abi.encode(_claimer, signature))), block.timestamp);
_passMinCommitmentPeriod();
......@@ -227,10 +211,7 @@ contract OptimistInviter_Initializer is Test {
vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(
address(optimistInviter),
_to,
optimistInviter.CAN_INVITE_ATTESTATION_KEY(),
bytes("true")
address(optimistInviter), _to, optimistInviter.CAN_INVITE_ATTESTATION_KEY(), bytes("true")
);
vm.prank(alice_inviteGranter);
......@@ -258,18 +239,12 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(
address(optimistInviter),
bob,
optimistInviter.CAN_INVITE_ATTESTATION_KEY(),
bytes("true")
address(optimistInviter), bob, optimistInviter.CAN_INVITE_ATTESTATION_KEY(), bytes("true")
);
vm.expectEmit(true, true, true, true, address(attestationStation));
emit AttestationCreated(
address(optimistInviter),
sally,
optimistInviter.CAN_INVITE_ATTESTATION_KEY(),
bytes("true")
address(optimistInviter), sally, optimistInviter.CAN_INVITE_ATTESTATION_KEY(), bytes("true")
);
vm.expectEmit(true, true, true, true, address(attestationStation));
......@@ -348,10 +323,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// @notice Bob issues signature, and Ted commits the invite for Sally. Eve claims for Sally.
function test_claimInvite_claimForSomeoneElse_succeeds() external {
_grantInvitesTo(bob);
(
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteAs(bobPrivateKey);
(OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteAs(bobPrivateKey);
vm.prank(ted);
optimistInviter.commitInvite(keccak256(abi.encode(sally, signature)));
......@@ -379,10 +351,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() external {
_grantInvitesTo(bob);
(
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteAs(bobPrivateKey);
(OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteAs(bobPrivateKey);
_commitInviteAs(sally, signature);
......@@ -397,15 +366,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// @notice Signature issued for previous versions of the contract should fail.
function test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() external {
_grantInvitesTo(bob);
(
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteWithEIP712Domain(
bobPrivateKey,
"OptimismInviter",
"0.9.1",
block.chainid,
address(optimistInviter)
(OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteWithEIP712Domain(
bobPrivateKey, "OptimismInviter", "0.9.1", block.chainid, address(optimistInviter)
);
_commitInviteAs(sally, signature);
......@@ -420,15 +382,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// should fail.
function test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() external {
_grantInvitesTo(bob);
(
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteWithEIP712Domain(
bobPrivateKey,
"OptimismInviter",
bytes(optimistInviter.EIP712_VERSION()),
1,
address(optimistInviter)
(OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteWithEIP712Domain(
bobPrivateKey, "OptimismInviter", bytes(optimistInviter.EIP712_VERSION()), 1, address(optimistInviter)
);
_commitInviteAs(sally, signature);
......@@ -443,15 +398,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// on a different address should fail.
function test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() external {
_grantInvitesTo(bob);
(
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueInviteWithEIP712Domain(
bobPrivateKey,
"OptimismInviter",
bytes(optimistInviter.EIP712_VERSION()),
block.chainid,
address(0xBEEF)
(OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) = _issueInviteWithEIP712Domain(
bobPrivateKey, "OptimismInviter", bytes(optimistInviter.EIP712_VERSION()), block.chainid, address(0xBEEF)
);
_commitInviteAs(sally, signature);
......@@ -466,10 +414,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_replayingUsedNonce_reverts() external {
_grantInvitesTo(bob);
(
OptimistInviter.ClaimableInvite memory claimableInvite,
bytes memory signature
) = _issueThenClaimShouldSucceed(bobPrivateKey, sally);
(OptimistInviter.ClaimableInvite memory claimableInvite, bytes memory signature) =
_issueThenClaimShouldSucceed(bobPrivateKey, sally);
// Sally tries to claim the invite using the same signature
vm.expectRevert("OptimistInviter: nonce has already been used");
......@@ -491,13 +437,10 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_usingERC1271Wallet_succeeds() external {
_grantInvitesTo(address(carolERC1271Wallet));
OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper
.getClaimableInviteWithNewNonce(address(carolERC1271Wallet));
OptimistInviter.ClaimableInvite memory claimableInvite =
optimistInviterHelper.getClaimableInviteWithNewNonce(address(carolERC1271Wallet));
bytes memory signature = _getSignature(
carolPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
bytes memory signature = _getSignature(carolPrivateKey, optimistInviterHelper.getDigest(claimableInvite));
// Sally tries to claim the invite
_commitInviteAs(sally, signature);
......@@ -520,10 +463,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// claim the Bob's invite without committing the signature first.
function test_claimInvite_withoutCommittingHash_reverts() external {
_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.prank(sally);
......@@ -534,10 +474,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_withIncorrectSignature_reverts() external {
_grantInvitesTo(carol);
_grantInvitesTo(bob);
(
OptimistInviter.ClaimableInvite memory bobClaimableInvite,
bytes memory bobSignature
) = _issueInviteAs(bobPrivateKey);
(OptimistInviter.ClaimableInvite memory bobClaimableInvite, bytes memory bobSignature) =
_issueInviteAs(bobPrivateKey);
(, bytes memory carolSignature) = _issueInviteAs(carolPrivateKey);
_commitInviteAs(sally, bobSignature);
......@@ -554,10 +492,7 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
/// fail.
function test_claimInvite_whenIssuerNeverReceivedInvites_reverts() external {
// 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);
_passMinCommitmentPeriod();
......@@ -580,10 +515,8 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
assertEq(_getInviteCount(bob), 0);
(
OptimistInviter.ClaimableInvite memory claimableInvite4,
bytes memory signature4
) = _issueInviteAs(bobPrivateKey);
(OptimistInviter.ClaimableInvite memory claimableInvite4, bytes memory signature4) =
_issueInviteAs(bobPrivateKey);
_commitInviteAs(eve, signature4);
_passMinCommitmentPeriod();
......
......@@ -53,7 +53,9 @@ contract PreimageOracle_Test is Test {
bytes32 word,
uint256 size,
uint256 partOffset
) public {
)
public
{
// Bound the size to [0, 32]
size = bound(size, 0, 32);
// Bound the part offset to [0, size + 8]
......
......@@ -29,8 +29,7 @@ contract Proxy_Test is Test {
address alice = address(64);
bytes32 internal constant IMPLEMENTATION_KEY =
bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1);
bytes32 internal constant IMPLEMENTATION_KEY = bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1);
bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1);
......@@ -155,10 +154,7 @@ contract Proxy_Test is Test {
vm.expectEmit(true, true, true, true);
emit Upgraded(address(simpleStorage));
vm.prank(alice);
proxy.upgradeToAndCall(
address(simpleStorage),
abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
);
proxy.upgradeToAndCall(address(simpleStorage), abi.encodeWithSelector(simpleStorage.set.selector, 1, 1));
// The call should have impacted the state
uint256 result = SimpleStorage(address(proxy)).get(1);
......@@ -191,10 +187,7 @@ contract Proxy_Test is Test {
// The attempt to `upgradeToAndCall`
// should revert when it is not called by the owner.
vm.expectRevert();
proxy.upgradeToAndCall(
address(simpleStorage),
abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
);
proxy.upgradeToAndCall(address(simpleStorage), abi.encodeWithSelector(simpleStorage.set.selector, 1, 1));
}
function test_upgradeToAndCall_isPayable_succeeds() external {
......@@ -204,8 +197,7 @@ contract Proxy_Test is Test {
// value.
vm.prank(alice);
proxy.upgradeToAndCall{ value: 1 ether }(
address(simpleStorage),
abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
address(simpleStorage), abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)
);
// The implementation address should be correct
......@@ -267,10 +259,7 @@ contract Proxy_Test is Test {
(bool success, bytes memory returndata) = address(proxy).call(hex"");
assertEq(success, false);
bytes memory err = abi.encodeWithSignature(
"Error(string)",
"Proxy: implementation not initialized"
);
bytes memory err = abi.encodeWithSignature("Error(string)", "Proxy: implementation not initialized");
assertEq(returndata, err);
}
......
......@@ -86,14 +86,8 @@ contract ProxyAdmin_Test is Test {
function test_proxyType_succeeds() external {
assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));
assertEq(
uint256(admin.proxyType(address(chugsplash))),
uint256(ProxyAdmin.ProxyType.CHUGSPLASH)
);
assertEq(
uint256(admin.proxyType(address(resolved))),
uint256(ProxyAdmin.ProxyType.RESOLVED)
);
assertEq(uint256(admin.proxyType(address(chugsplash))), uint256(ProxyAdmin.ProxyType.CHUGSPLASH));
assertEq(uint256(admin.proxyType(address(resolved))), uint256(ProxyAdmin.ProxyType.RESOLVED));
}
function test_erc1967GetProxyImplementation_succeeds() external {
......@@ -222,11 +216,7 @@ contract ProxyAdmin_Test is Test {
function upgradeAndCall(address payable _proxy) internal {
vm.prank(alice);
admin.upgradeAndCall(
_proxy,
address(implementation),
abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)
);
admin.upgradeAndCall(_proxy, address(implementation), abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1));
address impl = admin.getProxyImplementation(_proxy);
assertEq(impl, address(implementation));
......
......@@ -9,60 +9,38 @@ library LibRLP {
using Bytes32AddressLib for bytes32;
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.
// A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it.
if (nonce == 0x00)
return
keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))
// 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.
// A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix
// that comes before it.
if (nonce == 0x00) {
return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))).fromLast20Bytes();
}
if (nonce <= 0x7f) {
return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))).fromLast20Bytes();
}
// Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix
// of 0x80 + length.
if (nonce <= type(uint8).max) {
return keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))
.fromLast20Bytes();
if (nonce <= 0x7f)
return
keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))
}
if (nonce <= type(uint16).max) {
return keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))
.fromLast20Bytes();
// Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.
if (nonce <= type(uint8).max)
return
keccak256(
abi.encodePacked(
bytes1(0xd7),
bytes1(0x94),
deployer,
bytes1(0x81),
uint8(nonce)
)
).fromLast20Bytes();
if (nonce <= type(uint16).max)
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();
}
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
// 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)
// 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.
return
keccak256(
abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))
).fromLast20Bytes();
return keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))
.fromLast20Bytes();
}
}
......@@ -24,16 +24,12 @@ contract RLPReader_readBytes_Test is CommonTest {
}
function test_readBytes_invalidStringLength_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be > than length of string length (long string)"
);
vm.expectRevert("RLPReader: length of content must be > than length of string length (long string)");
RLPReader.readBytes(hex"b9");
}
function test_readBytes_invalidListLength_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be > than length of list length (long list)"
);
vm.expectRevert("RLPReader: length of content must be > than length of list length (long list)");
RLPReader.readBytes(hex"ff");
}
......@@ -43,9 +39,7 @@ contract RLPReader_readBytes_Test is CommonTest {
}
function test_readBytes_invalidPrefix_reverts() external {
vm.expectRevert(
"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)"
);
vm.expectRevert("RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)");
RLPReader.readBytes(hex"810a");
}
}
......@@ -109,9 +103,7 @@ contract RLPReader_readList_Test is CommonTest {
function test_readList_listLongerThan32Elements_reverts() external {
vm.expectRevert(stdError.indexOOBError);
RLPReader.readList(
hex"e1454545454545454545454545454545454545454545454545454545454545454545"
);
RLPReader.readList(hex"e1454545454545454545454545454545454545454545454545454545454545454545");
}
function test_readList_listOfLists_succeeds() external {
......@@ -143,64 +135,44 @@ contract RLPReader_readList_Test is CommonTest {
}
function test_readList_invalidShortList_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than list length (short list)"
);
vm.expectRevert("RLPReader: length of content must be greater than list length (short list)");
RLPReader.readList(hex"efdebd");
}
function test_readList_longStringLength_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than list length (short list)"
);
vm.expectRevert("RLPReader: length of content must be greater than list length (short list)");
RLPReader.readList(hex"efb83600");
}
function test_readList_notLongEnough_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than list length (short list)"
);
RLPReader.readList(
hex"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
);
vm.expectRevert("RLPReader: length of content must be greater than list length (short list)");
RLPReader.readList(hex"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
function test_readList_int32Overflow_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than total length (long string)"
);
vm.expectRevert("RLPReader: length of content must be greater than total length (long string)");
RLPReader.readList(hex"bf0f000000000000021111");
}
function test_readList_int32Overflow2_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than total length (long list)"
);
vm.expectRevert("RLPReader: length of content must be greater than total length (long list)");
RLPReader.readList(hex"ff0f000000000000021111");
}
function test_readList_incorrectLengthInArray_reverts() external {
vm.expectRevert(
"RLPReader: length of content must not have any leading zeros (long string)"
);
RLPReader.readList(
hex"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0"
);
vm.expectRevert("RLPReader: length of content must not have any leading zeros (long string)");
RLPReader.readList(hex"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0");
}
function test_readList_leadingZerosInLongLengthArray1_reverts() external {
vm.expectRevert(
"RLPReader: length of content must not have any leading zeros (long string)"
);
vm.expectRevert("RLPReader: length of content must not have any leading zeros (long string)");
RLPReader.readList(
hex"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
);
}
function test_readList_leadingZerosInLongLengthArray2_reverts() external {
vm.expectRevert(
"RLPReader: length of content must not have any leading zeros (long string)"
);
vm.expectRevert("RLPReader: length of content must not have any leading zeros (long string)");
RLPReader.readList(hex"b800");
}
......@@ -222,9 +194,7 @@ contract RLPReader_readList_Test is CommonTest {
}
function test_readList_invalidValue_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than string length (short string)"
);
vm.expectRevert("RLPReader: length of content must be greater than string length (short string)");
RLPReader.readList(hex"91");
}
......@@ -234,30 +204,22 @@ contract RLPReader_readList_Test is CommonTest {
}
function test_readList_notEnoughContentForString1_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than total length (long string)"
);
vm.expectRevert("RLPReader: length of content must be greater than total length (long string)");
RLPReader.readList(hex"ba010000aabbccddeeff");
}
function test_readList_notEnoughContentForString2_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than total length (long string)"
);
vm.expectRevert("RLPReader: length of content must be greater than total length (long string)");
RLPReader.readList(hex"b840ffeeddccbbaa99887766554433221100");
}
function test_readList_notEnoughContentForList1_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than total length (long list)"
);
vm.expectRevert("RLPReader: length of content must be greater than total length (long list)");
RLPReader.readList(hex"f90180");
}
function test_readList_notEnoughContentForList2_reverts() external {
vm.expectRevert(
"RLPReader: length of content must be greater than total length (long list)"
);
vm.expectRevert("RLPReader: length of content must be greater than total length (long list)");
RLPReader.readList(hex"ffffffffffffffffff0001020304050607");
}
......
......@@ -23,9 +23,7 @@ contract ResolvedDelegateProxy_Test is Test {
addressManager.setAddress("SimpleImplementation", address(impl));
// Set up the proxy.
proxy = SimpleImplementation(
address(new ResolvedDelegateProxy(addressManager, "SimpleImplementation"))
);
proxy = SimpleImplementation(address(new ResolvedDelegateProxy(addressManager, "SimpleImplementation")));
}
/// @dev Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.
......@@ -45,9 +43,7 @@ contract ResolvedDelegateProxy_Test is Test {
/// address manager is not set.
function test_fallback_addressManagerNotSet_reverts() public {
AddressManager am = new AddressManager();
SimpleImplementation p = SimpleImplementation(
address(new ResolvedDelegateProxy(am, "SimpleImplementation"))
);
SimpleImplementation p = SimpleImplementation(address(new ResolvedDelegateProxy(am, "SimpleImplementation")));
vm.expectRevert("ResolvedDelegateProxy: target address must be initialized");
p.foo(0);
......
......@@ -29,22 +29,13 @@ contract MeterUser is ResourceMetering {
return _resourceConfig();
}
function _resourceConfig()
internal
view
override
returns (ResourceMetering.ResourceConfig memory)
{
function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory) {
return innerConfig;
}
function use(uint64 _amount) public metered(_amount) {}
function use(uint64 _amount) public metered(_amount) { }
function set(
uint128 _prevBaseFee,
uint64 _prevBoughtGas,
uint64 _prevBlockNum
) public {
function set(uint128 _prevBaseFee, uint64 _prevBoughtGas, uint64 _prevBlockNum) public {
params = ResourceMetering.ResourceParams({
prevBaseFee: _prevBaseFee,
prevBoughtGas: _prevBoughtGas,
......@@ -145,12 +136,12 @@ contract ResourceMetering_Test is Test {
meter.use(target * elasticityMultiplier);
(, uint64 prevBoughtGas, ) = meter.params();
(, uint64 prevBoughtGas,) = meter.params();
assertEq(prevBoughtGas, target * elasticityMultiplier);
vm.roll(initialBlockNum + 1);
meter.use(0);
(uint128 postBaseFee, , ) = meter.params();
(uint128 postBaseFee,,) = meter.params();
assertEq(postBaseFee, 2125000000);
}
......@@ -165,7 +156,7 @@ contract ResourceMetering_Test is Test {
meter.setParams(rcfg);
meter.use(target * elasticityMultiplier);
(, uint64 prevBoughtGas, ) = meter.params();
(, uint64 prevBoughtGas,) = meter.params();
assertEq(prevBoughtGas, target * elasticityMultiplier);
vm.roll(initialBlockNum + 2);
......@@ -207,11 +198,7 @@ contract CustomMeterUser is ResourceMetering {
uint256 public startGas;
uint256 public endGas;
constructor(
uint128 _prevBaseFee,
uint64 _prevBoughtGas,
uint64 _prevBlockNum
) {
constructor(uint128 _prevBaseFee, uint64 _prevBoughtGas, uint64 _prevBlockNum) {
params = ResourceMetering.ResourceParams({
prevBaseFee: _prevBaseFee,
prevBoughtGas: _prevBoughtGas,
......@@ -219,12 +206,7 @@ contract CustomMeterUser is ResourceMetering {
});
}
function _resourceConfig()
internal
pure
override
returns (ResourceMetering.ResourceConfig memory)
{
function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) {
return Constants.DEFAULT_RESOURCE_CONFIG();
}
......@@ -250,15 +232,13 @@ contract ArtifactResourceMetering_Test is Test {
string internal outfile;
// keccak256(abi.encodeWithSignature("Error(string)", "ResourceMetering: cannot buy more gas than available gas limit"))
bytes32 internal cannotBuyMoreGas =
0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;
// keccak256(abi.encodeWithSignature("Error(string)", "ResourceMetering: cannot buy more gas than available gas
// limit"))
bytes32 internal cannotBuyMoreGas = 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;
// keccak256(abi.encodeWithSignature("Panic(uint256)", 0x11))
bytes32 internal overflowErr =
0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;
bytes32 internal overflowErr = 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;
// keccak256(hex"")
bytes32 internal emptyReturnData =
0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
bytes32 internal emptyReturnData = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
/// @dev Sets up the tests with constants from the ResourceMetering contract.
function setUp() public {
......@@ -272,7 +252,7 @@ contract ArtifactResourceMetering_Test is Test {
targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);
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
......@@ -348,9 +328,7 @@ contract ArtifactResourceMetering_Test is Test {
// Call the metering code and catch the various
// types of errors.
uint256 gasConsumed = 0;
try meter.use{ gas: 30_000_000 }(requestedGas) returns (
uint256 _gasConsumed
) {
try meter.use{ gas: 30_000_000 }(requestedGas) returns (uint256 _gasConsumed) {
gasConsumed = _gasConsumed;
} catch (bytes memory err) {
bytes32 hash = keccak256(err);
......
......@@ -9,12 +9,7 @@ import { SafeCall } from "../src/libraries/SafeCall.sol";
contract SafeCall_Test is CommonTest {
/// @dev Tests that the `send` function succeeds.
function testFuzz_send_succeeds(
address from,
address to,
uint256 gas,
uint64 value
) external {
function testFuzz_send_succeeds(address from, address to, uint256 gas, uint64 value) external {
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles (mainnet)
......@@ -49,13 +44,7 @@ contract SafeCall_Test is CommonTest {
}
/// @dev Tests that `call` succeeds.
function testFuzz_call_succeeds(
address from,
address to,
uint256 gas,
uint64 value,
bytes memory data
) external {
function testFuzz_call_succeeds(address from, address to, uint256 gas, uint64 value, bytes memory data) external {
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles (mainnet)
......@@ -96,7 +85,9 @@ contract SafeCall_Test is CommonTest {
uint64 minGas,
uint64 value,
bytes memory data
) external {
)
external
{
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles (mainnet)
......@@ -145,12 +136,7 @@ contract SafeCall_Test is CommonTest {
if (i < 65_907) {
assertFalse(caller.makeSafeCall(i, 25_000));
} else {
vm.expectCallMinGas(
address(caller),
0,
25_000,
abi.encodeWithSelector(caller.setA.selector, 1)
);
vm.expectCallMinGas(address(caller), 0, 25_000, abi.encodeWithSelector(caller.setA.selector, 1));
assertTrue(caller.makeSafeCall(i, 25_000));
}
......@@ -170,12 +156,7 @@ contract SafeCall_Test is CommonTest {
if (i < 15_278_606) {
assertFalse(caller.makeSafeCall(i, 15_000_000));
} else {
vm.expectCallMinGas(
address(caller),
0,
15_000_000,
abi.encodeWithSelector(caller.setA.selector, 1)
);
vm.expectCallMinGas(address(caller), 0, 15_000_000, abi.encodeWithSelector(caller.setA.selector, 1));
assertTrue(caller.makeSafeCall(i, 15_000_000));
}
......@@ -188,23 +169,11 @@ contract SimpleSafeCaller {
uint256 public a;
function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {
return
SafeCall.call(
address(this),
gas,
0,
abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)
);
return SafeCall.call(address(this), gas, 0, abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas));
}
function makeSafeCallMinGas(uint64 minGas) external returns (bool) {
return
SafeCall.callWithMinGas(
address(this),
minGas,
0,
abi.encodeWithSelector(this.setA.selector, 1)
);
return SafeCall.callWithMinGas(address(this), minGas, 0, abi.encodeWithSelector(this.setA.selector, 1));
}
function setA(uint256 _a) external {
......
......@@ -20,8 +20,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
super.setUp();
vm.etch(
Predeploys.SEQUENCER_FEE_WALLET,
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1))
.code
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code
);
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
}
......@@ -41,7 +40,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
uint256 balance = address(vault).balance;
vm.prank(alice);
(bool success, ) = address(vault).call{ value: 100 }(hex"");
(bool success,) = address(vault).call{ value: 100 }(hex"");
assertEq(success, true);
assertEq(address(vault).balance, balance + 100);
......@@ -52,9 +51,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
function test_withdraw_notEnough_reverts() external {
assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());
vm.expectRevert(
"FeeVault: withdrawal amount must be greater than minimum withdrawal amount"
);
vm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount");
vault.withdraw();
}
......@@ -69,23 +66,13 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(
address(vault).balance,
vault.RECIPIENT(),
address(this),
FeeVault.WithdrawalNetwork.L1
);
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L1);
// The entire vault's balance is withdrawn
vm.expectCall(
Predeploys.L2_STANDARD_BRIDGE,
address(vault).balance,
abi.encodeWithSelector(
StandardBridge.bridgeETHTo.selector,
vault.l1FeeWallet(),
35_000,
bytes("")
)
abi.encodeWithSelector(StandardBridge.bridgeETHTo.selector, vault.l1FeeWallet(), 35_000, bytes(""))
);
vault.withdraw();
......@@ -103,8 +90,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
super.setUp();
vm.etch(
Predeploys.SEQUENCER_FEE_WALLET,
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L2))
.code
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L2)).code
);
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
}
......@@ -120,12 +106,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(
address(vault).balance,
vault.RECIPIENT(),
address(this),
FeeVault.WithdrawalNetwork.L2
);
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L2);
// The entire vault's balance is withdrawn
vm.expectCall(recipient, address(vault).balance, bytes(""));
......@@ -152,9 +133,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
// The entire vault's balance is withdrawn
vm.expectCall(recipient, address(vault).balance, bytes(""));
vm.expectRevert(
"FeeVault: failed to send ETH to L2 fee recipient"
);
vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient");
vault.withdraw();
assertEq(vault.totalProcessed(), 0);
}
......
......@@ -3,47 +3,43 @@ pragma solidity 0.8.15;
import { StandardBridge } from "../src/universal/StandardBridge.sol";
import { CommonTest } from "./CommonTest.t.sol";
import {
OptimismMintableERC20,
ILegacyMintableERC20
} from "../src/universal/OptimismMintableERC20.sol";
import { OptimismMintableERC20, ILegacyMintableERC20 } from "../src/universal/OptimismMintableERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// @title StandardBridgeTester
/// @notice Simple wrapper around the StandardBridge contract that exposes
/// internal functions so they can be more easily tested directly.
contract StandardBridgeTester is StandardBridge {
constructor(address payable _messenger, address payable _otherBridge)
constructor(
address payable _messenger,
address payable _otherBridge
)
StandardBridge(StandardBridge(_otherBridge))
{}
{ }
function isOptimismMintableERC20(address _token) external view returns (bool) {
return _isOptimismMintableERC20(_token);
}
function isCorrectTokenPair(address _mintableToken, address _otherToken)
external
view
returns (bool)
{
function isCorrectTokenPair(address _mintableToken, address _otherToken) external view returns (bool) {
return _isCorrectTokenPair(_mintableToken, _otherToken);
}
receive() external payable override {}
receive() external payable override { }
}
/// @title LegacyMintable
/// @notice Simple implementation of the legacy OptimismMintableERC20.
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) {
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
/// it is how the actual legacy optimism mintable token does the
......@@ -51,9 +47,8 @@ contract LegacyMintable is ERC20, ILegacyMintableERC20 {
/// assuming different compiler version is no problem.
function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^
ILegacyMintableERC20.mint.selector ^
ILegacyMintableERC20.burn.selector;
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^ ILegacyMintableERC20.mint.selector
^ ILegacyMintableERC20.burn.selector;
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
}
}
......
......@@ -318,11 +318,7 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
}
contract SystemConfig_Setters_Test is SystemConfig_Init {
event ConfigUpdate(
uint256 indexed version,
SystemConfig.UpdateType indexed updateType,
bytes data
);
event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data);
/// @dev Tests that `setBatcherHash` updates the batcher hash successfully.
function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {
......@@ -337,11 +333,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
/// @dev Tests that `setGasConfig` updates the overhead and scalar successfully.
function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(
0,
SystemConfig.UpdateType.GAS_CONFIG,
abi.encode(newOverhead, newScalar)
);
emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar));
vm.prank(sysConf.owner());
sysConf.setGasConfig(newOverhead, newScalar);
......@@ -352,9 +344,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
/// @dev Tests that `setGasLimit` updates the gas limit successfully.
function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {
uint64 minimumGasLimit = sysConf.minimumGasLimit();
newGasLimit = uint64(
bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))
);
newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max)));
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));
......@@ -367,11 +357,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
/// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully.
function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(
0,
SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,
abi.encode(newUnsafeSigner)
);
emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner));
vm.prank(sysConf.owner());
sysConf.setUnsafeBlockSigner(newUnsafeSigner);
......
......@@ -25,12 +25,7 @@ contract RelayActor is StdUtils {
Vm vm;
bool doFail;
constructor(
OptimismPortal _op,
L1CrossDomainMessenger _xdm,
Vm _vm,
bool _doFail
) {
constructor(OptimismPortal _op, L1CrossDomainMessenger _xdm, Vm _vm, bool _doFail) {
op = _op;
xdm = _xdm;
vm = _vm;
......@@ -39,11 +34,7 @@ contract RelayActor is StdUtils {
/// @notice Relays a message to the `L1CrossDomainMessenger` with a random `version`,
/// and `_message`.
function relay(
uint8 _version,
uint8 _value,
bytes memory _message
) external {
function relay(uint8 _version, uint8 _value, bytes memory _message) external {
address target = address(0x04); // ID precompile
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
......@@ -65,20 +56,13 @@ contract RelayActor is StdUtils {
// If the message should succeed, supply it `baseGas`. If not, supply it an amount of
// gas that is too low to complete the call.
uint256 gas = doFail
? bound(minGasLimit, 60_000, 80_000)
: xdm.baseGas(_message, minGasLimit);
uint256 gas = doFail ? bound(minGasLimit, 60_000, 80_000) : xdm.baseGas(_message, minGasLimit);
// Compute the cross domain message hash and store it in `hashes`.
// The `relayMessage` function will always encode the message as a version 1
// message after checking that the V0 hash has not already been relayed.
bytes32 _hash = Hashing.hashCrossDomainMessageV1(
Encoding.encodeVersionedNonce(0, _version),
sender,
target,
_value,
minGasLimit,
_message
Encoding.encodeVersionedNonce(0, _version), sender, target, _value, minGasLimit, _message
);
hashes.push(_hash);
numHashes += 1;
......@@ -92,16 +76,9 @@ contract RelayActor is StdUtils {
if (!doFail) {
vm.expectCallMinGas(address(0x04), _value, minGasLimit, _message);
}
try
xdm.relayMessage{ gas: gas, value: _value }(
Encoding.encodeVersionedNonce(0, _version),
sender,
target,
_value,
minGasLimit,
_message
)
{} catch {
try xdm.relayMessage{ gas: gas, value: _value }(
Encoding.encodeVersionedNonce(0, _version), sender, target, _value, minGasLimit, _message
) { } catch {
// 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
// to this function.
......
......@@ -22,7 +22,9 @@ contract Hash_CrossDomainHasher {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
// generate the versioned nonce
uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);
......@@ -46,26 +48,16 @@ contract Hash_CrossDomainHasher {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
// generate the versioned nonce with the version set to 0
uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);
// hash the cross domain message using the unversioned and versioned functions for
// comparison
bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(
encodedNonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(
_target,
_sender,
_data,
encodedNonce
);
bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);
bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(_target, _sender, _data, encodedNonce);
// check that the output of both functions matches
if (sampleHash1 != sampleHash2) {
......@@ -83,28 +75,16 @@ contract Hash_CrossDomainHasher {
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
)
external
{
// generate the versioned nonce with the version set to 1
uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);
// hash the cross domain message using the unversioned and versioned functions for
// comparison
bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(
encodedNonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(
encodedNonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);
bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(encodedNonce, _sender, _target, _value, _gasLimit, _data);
// check that the output of both functions matches
if (sampleHash1 != sampleHash2) {
......
......@@ -20,7 +20,9 @@ contract L2OutputOracle_Proposer {
uint256 _l2BlockNumber,
bytes32 _l1BlockHash,
uint256 _l1BlockNumber
) external {
)
external
{
// Act as the proposer and propose a new output.
vm.prank(oracle.PROPOSER());
oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);
......
......@@ -33,12 +33,7 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
return _resourceConfig();
}
function _resourceConfig()
internal
pure
override
returns (ResourceMetering.ResourceConfig memory)
{
function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) {
ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();
return rcfg;
}
......@@ -50,7 +45,10 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
) public payable {
)
public
payable
{
vm.assume((!_isCreation || _to == address(0)) && _data.length <= 120_000);
uint256 preDepositvalue = bound(_value, 0, type(uint128).max);
......@@ -60,15 +58,11 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
uint256 preDepositBalance = address(this).balance;
uint256 value = bound(preDepositvalue, 0, preDepositBalance);
(, uint64 cachedPrevBoughtGas, ) = ResourceMetering(address(portal)).params();
(, uint64 cachedPrevBoughtGas,) = ResourceMetering(address(portal)).params();
ResourceMetering.ResourceConfig memory rcfg = resourceConfig();
uint256 maxResourceLimit = uint64(rcfg.maxResourceLimit);
uint64 gasLimit = uint64(
bound(
_gasLimit,
portal.minimumGasLimit(uint64(_data.length)),
maxResourceLimit - cachedPrevBoughtGas
)
bound(_gasLimit, portal.minimumGasLimit(uint64(_data.length)), maxResourceLimit - cachedPrevBoughtGas)
);
try portal.depositTransaction{ value: value }(_to, value, gasLimit, _isCreation, _data) {
......@@ -104,8 +98,8 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer {
data: hex""
});
// Get withdrawal proof data we can use for testing.
(_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi
.getProveWithdrawalTransactionInputs(_defaultTx);
(_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) =
ffi.getProveWithdrawalTransactionInputs(_defaultTx);
// Setup a dummy output root proof for reuse.
_outputRootProof = Types.OutputRootProof({
......@@ -123,11 +117,7 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer {
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed.
vm.warp(
oracle.getL2Output(_proposedOutputIndex).timestamp +
oracle.FINALIZATION_PERIOD_SECONDS() +
1
);
vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF);
}
......@@ -164,12 +154,7 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {
super.setUp();
// Prove the withdrawal transaction
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Set the target contract to the portal proxy
targetContract(address(op));
......@@ -193,12 +178,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness
super.setUp();
// Prove the withdrawal transaction
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp past the finalization period.
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
......@@ -228,12 +208,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant
super.setUp();
// Prove the withdrawal transaction
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp past the finalization period.
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
......
......@@ -35,12 +35,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
return _resourceConfig();
}
function _resourceConfig()
internal
pure
override
returns (ResourceMetering.ResourceConfig memory)
{
function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) {
ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();
return rcfg;
}
......@@ -54,8 +49,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);
ResourceMetering.ResourceConfig memory rcfg = resourceConfig();
uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) /
uint256(rcfg.elasticityMultiplier);
uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);
// check that the last block's base fee hasn't dropped below the minimum
if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {
......@@ -72,11 +66,7 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
// raise or lower the baseFee after this block, respectively
uint256 gasToBurn;
if (_raiseBaseFee) {
gasToBurn = bound(
_gasToBurn,
uint256(targetResourceLimit),
uint256(rcfg.maxResourceLimit)
);
gasToBurn = bound(_gasToBurn, uint256(targetResourceLimit), uint256(rcfg.maxResourceLimit));
} else {
gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);
}
......@@ -92,39 +82,35 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
// empty blocks in between), ensure this block's baseFee increased, but not by
// more than the max amount per block
if (
(cachedPrevBoughtGas > uint256(targetResourceLimit)) &&
(uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)
(cachedPrevBoughtGas > uint256(targetResourceLimit))
&& (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)
) {
failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);
failedMaxRaiseBaseFeePerBlock =
failedMaxRaiseBaseFeePerBlock ||
((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);
failedMaxRaiseBaseFeePerBlock || ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);
}
// 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
if (
(cachedPrevBoughtGas < uint256(targetResourceLimit)) ||
(uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)
(cachedPrevBoughtGas < uint256(targetResourceLimit))
|| (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)
) {
// Invariant: baseFee should decrease
failedLowerBaseFee =
failedLowerBaseFee ||
(uint256(params.prevBaseFee) > cachedPrevBaseFee);
failedLowerBaseFee = failedLowerBaseFee || (uint256(params.prevBaseFee) > cachedPrevBaseFee);
if (params.prevBlockNum - cachedPrevBlockNum == 1) {
// No empty blocks
// Invariant: baseFee should not have decreased by more than the maximum amount
failedMaxLowerBaseFeePerBlock =
failedMaxLowerBaseFeePerBlock ||
((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);
failedMaxLowerBaseFeePerBlock = failedMaxLowerBaseFeePerBlock
|| ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);
} else if (params.prevBlockNum - cachedPrevBlockNum > 1) {
// We have at least one empty block
// Update the maxBaseFeeChange to account for multiple blocks having passed
unchecked {
maxBaseFeeChange = uint256(
int256(cachedPrevBaseFee) -
Arithmetic.clamp(
int256(cachedPrevBaseFee)
- Arithmetic.clamp(
Arithmetic.cdexp(
int256(cachedPrevBaseFee),
int256(uint256(rcfg.baseFeeMaxChangeDenominator)),
......@@ -142,14 +128,13 @@ contract ResourceMetering_User is StdUtils, ResourceMetering {
underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;
// Invariant: baseFee should not have decreased by more than the maximum amount
failedMaxLowerBaseFeePerBlock =
failedMaxLowerBaseFeePerBlock ||
((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);
failedMaxLowerBaseFeePerBlock = failedMaxLowerBaseFeePerBlock
|| ((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 {
......
......@@ -80,12 +80,7 @@ contract SafeCaller_Actor is StdUtils {
FAILS = _fails;
}
function performSafeCallMinGas(
uint64 gas,
uint64 minGas,
address to,
uint8 value
) external {
function performSafeCallMinGas(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
// with a selector that doesn't exist due to the foundry hook.
vm.assume(to.code.length == 0 && to != 0x000000000000000000636F6e736F6c652e6c6f67);
......@@ -108,11 +103,7 @@ contract SafeCaller_Actor is StdUtils {
msg.sender,
gas,
value,
abi.encodeWithSelector(
SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector,
to,
minGas
)
abi.encodeWithSelector(SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector, to, minGas)
);
if (success && FAILS) numCalls++;
......
......@@ -52,10 +52,7 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test {
// that can modify the gas limit within the SystemConfig.
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = config.setGasLimit.selector;
FuzzSelector memory selector = FuzzSelector({
addr: address(config),
selectors: selectors
});
FuzzSelector memory selector = FuzzSelector({ addr: address(config), selectors: selectors });
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