From 0b7258bf39eb565f8310b7f447c7adef4a7da504 Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 11:08:30 +1000 Subject: [PATCH 1/9] WIP fork --- .../modules/MainModuleDynamicAuthLog.sol | 52 +++++++++++ tests/EIP712Debug.ts | 89 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/contracts/modules/MainModuleDynamicAuthLog.sol create mode 100644 tests/EIP712Debug.ts diff --git a/src/contracts/modules/MainModuleDynamicAuthLog.sol b/src/contracts/modules/MainModuleDynamicAuthLog.sol new file mode 100644 index 00000000..149ce806 --- /dev/null +++ b/src/contracts/modules/MainModuleDynamicAuthLog.sol @@ -0,0 +1,52 @@ +// Copyright Immutable Pty Ltd 2018 - 2023 +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.17; + +import "./commons/ModuleAuthDynamic.sol"; +import "./commons/ModuleReceivers.sol"; +import "./commons/ModuleCalls.sol"; +import "./commons/ModuleUpdate.sol"; + + +/** + * TODO Peter update docs + * @notice Contains the core functionality arcadeum wallets will inherit with + * the added functionality that the main-module can be changed. + * @dev If using a new main module, developpers must ensure that all inherited + * contracts by the mainmodule don't conflict and are accounted for to be + * supported by the supportsInterface method. + */ +contract MainModuleDynamicAuth is + ModuleAuthDynamic, + ModuleCalls, + ModuleReceivers, + ModuleUpdate +{ + + // solhint-disable-next-line no-empty-blocks + constructor(address _factory, address _startup) ModuleAuthDynamic (_factory, _startup) { } + + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @dev If using a new main module, developpers must ensure that all inherited + * contracts by the mainmodule don't conflict and are accounted for to be + * supported by the supportsInterface method. + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface( + bytes4 _interfaceID + ) public override( + ModuleAuthUpgradable, + ModuleCalls, + ModuleReceivers, + ModuleUpdate + ) pure returns (bool) { + return super.supportsInterface(_interfaceID); + } + + function version() external pure virtual returns (uint256) { + return 1; + } +} diff --git a/tests/EIP712Debug.ts b/tests/EIP712Debug.ts new file mode 100644 index 00000000..2a5becbe --- /dev/null +++ b/tests/EIP712Debug.ts @@ -0,0 +1,89 @@ +import { ethers, network } from 'hardhat' + +// Fork network @ https://rpc.testnet.immutable.com/ +// Attach contract at LatestWalletImplLocator +// Get MainModuleDynamicAuth address +// Deploy MainModuleDynamicAuth (with console logs) +// Get code at the newly deployed MainModuleDynamicAuth (w/ logs) +// Set the code at the MainModuleDynamicAuth to be the newly deployed MainModuleDynamicAuth (w/ logs) +// Do signature verification +// inspect console.log lines + +async function main() { + // Get signature values + const typedHash = '0x0b8f209be8d541a4ded6b82c0414aac2cee9cb89f19518b6ee1502ba555cb16c' + const messageSubDigest = '0xede3e129db20579573bccededc094e9a0f3cb8c8df59bbf3526eb7072bffa6f3' + const packedAggregateSignature = + '0x000202011b1d383526a2815d26550eb314b5d7e0551327330043c9d1d1d25201bd592da3eb99a5c4568105a79c168b93eebe2444ddf1f7a61174394b2b8616ba8ce9aae7741e2131caf66b80773f3557e18ec0d93a68a17090cb1b010300014f84dcc8d9fe6c2d8ed83d2edc01cc1fc81e29a6a75bce6301072b3e30f972b744f259055466795f372eb5d82c5314a781209c827c634fd3435d617ce58639481c02' + const relayerSig = + '0xc9d1d1d25201bd592da3eb99a5c4568105a79c168b93eebe2444ddf1f7a61174394b2b8616ba8ce9aae7741e2131caf66b80773f3557e18ec0d93a68a17090cb1b01' + + // Recover signer + const signer = await ethers.getContractFactory('SignerCheck') + const signerDeployed = await signer.deploy() + await signerDeployed.deployed() + const signerRet = await signerDeployed.recover(messageSubDigest, relayerSig) + + // Verify supplied signature against Immutable signer + const immutableSignerAddr = '0x1B1D383526A2815d26550eb314B5d7e055132733' + const immutableSigner = await ethers.getContractAt('ImmutableSigner', immutableSignerAddr) + const immutableSignerPubKey = await immutableSigner.primarySigner() + + // Verify returned signer against Immutable signer + if (signerRet !== immutableSignerPubKey) { + console.log('Signer mismatch') + process.exit(0) + } + + // Set addresses + const scwAddr = '0x3878cadc6a521dceb1f46599913ce726c430a8e1' + const factoryAddr = '0x55b9d1cd803d5acA8ea23ccd96f6a756DED9f5a9' + const startupAddr = '0x8df826438e652f7124fe07F413fA3556cd57edB5' + const walletImplLocatorAddr = '0x657d339b8616033fee25f66ea1d00c3f30b14171' + + // Get MainModuleDynamicAuth address + const walletImplLocator = await ethers.getContractAt('LatestWalletImplLocator', walletImplLocatorAddr) + const mainModuleAddr = await walletImplLocator.latestWalletImplementation() + + // Deploy new MainModuleDynamicAuthLog + const ModuleLog = await ethers.getContractFactory('MainModuleDynamicAuthLog') + const moduleLog = await ModuleLog.deploy(factoryAddr, startupAddr) + await moduleLog.deployed() + + // Get code for logging + const modLogCode = await ethers.provider.getCode(moduleLog.address) + + // Get address for main module + const walletProxy = await ethers.getContractAt('IWalletProxy', scwAddr) + + // Set code + // await network.provider.send('hardhat_setCode', [mainModuleAddr, modLogCode]) +// await network.provider.send('hardhat_setStorageAt', [scwAddr, scwAddr, moduleLog.address]) + // await network.provider.send('hardhat_mine', ["0x100"]) +// console.log('MAIN MODULE ADDDR: ', moduleLog.address) + console.log("STORAGE AT: ", await ethers.provider.getStorageAt(scwAddr, scwAddr)); + console.log('PROXY IMPLEMENTATION: ', await walletProxy.PROXY_getImplementation()) + const implementationValue = "0x0000000000000000000000000" + moduleLog.address.substring(2); + console.log("MOD CODE ADDR: ", "0x0000000000000000000000000" + moduleLog.address.substring(2)) + console.log('Equal ', modLogCode == (await ethers.provider.getCode(mainModuleAddr))) + + // Verify code update + const newCode = await ethers.provider.getCode(mainModuleAddr) + if (newCode !== modLogCode) { + console.log('Code not updated') + process.exit(0) + } + + // Do signature verification + // Attatch to SCW + const moduleAuth = await ethers.getContractAt('ModuleAuth', scwAddr) + // Verify 2-of-2 signature + const magicValue = await moduleAuth['isValidSignature(bytes32,bytes)'](typedHash, packedAggregateSignature) + + console.log('MAGIC VALUE', magicValue) +} + +main().catch(error => { + console.error(error) + process.exit(1) +}) From 1d74009aa07640fdda344378325a952a600dc465 Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 11:10:56 +1000 Subject: [PATCH 2/9] hardhat config --- hardhat.config.ts | 102 +++++++++++++++++++++++++++++-------------- tests/EIP712Debug.ts | 5 +-- 2 files changed, 71 insertions(+), 36 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 7e432cf8..93a04d63 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,18 +1,22 @@ -import { HardhatUserConfig } from 'hardhat/config'; -import { networkConfig } from './utils/config-loader'; -import * as dotenv from 'dotenv'; +import { HardhatUserConfig } from 'hardhat/config' +import { networkConfig } from './utils/config-loader' -import '@nomiclabs/hardhat-truffle5'; -import '@nomiclabs/hardhat-ethers'; -import '@nomiclabs/hardhat-web3'; -import '@nomiclabs/hardhat-etherscan'; -import '@nomicfoundation/hardhat-chai-matchers'; +import '@nomiclabs/hardhat-truffle5' +import '@nomiclabs/hardhat-ethers' +import '@nomiclabs/hardhat-web3' +import '@nomiclabs/hardhat-etherscan' +import '@nomicfoundation/hardhat-chai-matchers' -import 'hardhat-gas-reporter'; -import 'solidity-coverage'; +import 'hardhat-gas-reporter' +import 'solidity-coverage' +import { HardhatConfig } from 'hardhat/types' -dotenv.config(); -loadAndValidateEnvironment(); +require('dotenv').config(); + +const ganacheNetwork = { + url: 'http://127.0.0.1:8545', + blockGasLimit: 6000000000 +} const config: HardhatUserConfig = { solidity: { @@ -29,36 +33,68 @@ const config: HardhatUserConfig = { }, paths: { root: 'src', - tests: 'tests' + tests: '../tests' }, networks: { - // Define here to easily specify private keys - localhost: { - url: 'http://127.0.0.1:8545', - accounts: [process.env.DEPLOYER_PRIV_KEY!, process.env.WALLET_IMPL_CHANGER_PRIV_KEY!] + hardhat: { + chainId: 13473, + forking: { + url: "https://rpc.testnet.immutable.com/", + }, }, - devnet: { - url: 'https://rpc.dev.immutable.com', - accounts: [process.env.DEPLOYER_PRIV_KEY!, process.env.WALLET_IMPL_CHANGER_PRIV_KEY!] + fork: { + url: "http://127.0.0.1:8545/" }, - testnet: { - url: 'https://rpc.testnet.immutable.com', - accounts: [process.env.DEPLOYER_PRIV_KEY!, process.env.WALLET_IMPL_CHANGER_PRIV_KEY!] + // Define here to easily specify private keys + zkevm: validateEnvironment() ? { + url: "https://rpc.testnet.immutable.com/", + accounts: ["1f6f17db77bf966ae1bb2fa0fc32868a3d5913f1b931f085ffe6522d5966f8d3"] + } : { + url: "SET ENVIRONMENT VARIABLES", + accounts: [], }, - mainnet: { - url: 'https://rpc.immutable.com', - accounts: [process.env.DEPLOYER_PRIV_KEY!, process.env.WALLET_IMPL_CHANGER_PRIV_KEY!] + zkevmdevnet: { + url: "0xEB7FFb9fb0c80437120f6F97EdE60aB59055EAE0", + accounts: [] }, + sepolia: networkConfig('sepolia'), + mainnet: networkConfig('mainnet'), + ropsten: networkConfig('ropsten'), + rinkeby: networkConfig('rinkeby'), + kovan: networkConfig('kovan'), + goerli: networkConfig('goerli'), + matic: networkConfig('matic'), + mumbai: networkConfig('mumbai'), + arbitrum: networkConfig('arbitrum'), + arbitrumTestnet: networkConfig('arbitrum-testnet'), + optimism: networkConfig('optimism'), + metis: networkConfig('metis'), + nova: networkConfig('nova'), + avalanche: networkConfig('avalanche'), + avalancheTestnet: networkConfig('avalanche-testnet'), + ganache: ganacheNetwork, + coverage: { + url: 'http://localhost:8555' + } + }, + etherscan: { + // Your API key for Etherscan + // Obtain one at https://etherscan.io/ + apiKey: networkConfig('mainnet').etherscan }, mocha: { timeout: process.env.COVERAGE ? 15 * 60 * 1000 : 30 * 1000 }, -}; + gasReporter: { + enabled: !!process.env.REPORT_GAS === true, + currency: 'USD', + gasPrice: 21, + showTimeSpent: true + }, +} -export default config; +export default config -function loadAndValidateEnvironment(): boolean { - return !!process.env.DEPLOYER_PRIV_KEY && - !!process.env.WALLET_IMPL_CHANGER_PRIV_KEY && - !!process.env.DEPLOYER_CONTRACT_ADDRESS; -} +function validateEnvironment(): boolean { + return !!process.env.DEPLOYER_PRIV_KEY && !!process.env.WALLET_IMPL_CHANGER_PRIV_KEY +} \ No newline at end of file diff --git a/tests/EIP712Debug.ts b/tests/EIP712Debug.ts index 2a5becbe..660572a9 100644 --- a/tests/EIP712Debug.ts +++ b/tests/EIP712Debug.ts @@ -58,14 +58,13 @@ async function main() { // Set code // await network.provider.send('hardhat_setCode', [mainModuleAddr, modLogCode]) -// await network.provider.send('hardhat_setStorageAt', [scwAddr, scwAddr, moduleLog.address]) // await network.provider.send('hardhat_mine', ["0x100"]) // console.log('MAIN MODULE ADDDR: ', moduleLog.address) console.log("STORAGE AT: ", await ethers.provider.getStorageAt(scwAddr, scwAddr)); console.log('PROXY IMPLEMENTATION: ', await walletProxy.PROXY_getImplementation()) const implementationValue = "0x0000000000000000000000000" + moduleLog.address.substring(2); - console.log("MOD CODE ADDR: ", "0x0000000000000000000000000" + moduleLog.address.substring(2)) - console.log('Equal ', modLogCode == (await ethers.provider.getCode(mainModuleAddr))) + await network.provider.send('hardhat_setStorageAt', [scwAddr, scwAddr, implementationValue]) + // Verify code update const newCode = await ethers.provider.getCode(mainModuleAddr) From d212ec184d16d09ff2c87903b893f34ae6db8423 Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 11:15:00 +1000 Subject: [PATCH 3/9] comment out unused contract --- tests/EIP712Debug.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/EIP712Debug.ts b/tests/EIP712Debug.ts index 660572a9..e5703922 100644 --- a/tests/EIP712Debug.ts +++ b/tests/EIP712Debug.ts @@ -19,21 +19,21 @@ async function main() { '0xc9d1d1d25201bd592da3eb99a5c4568105a79c168b93eebe2444ddf1f7a61174394b2b8616ba8ce9aae7741e2131caf66b80773f3557e18ec0d93a68a17090cb1b01' // Recover signer - const signer = await ethers.getContractFactory('SignerCheck') - const signerDeployed = await signer.deploy() - await signerDeployed.deployed() - const signerRet = await signerDeployed.recover(messageSubDigest, relayerSig) +// const signer = await ethers.getContractFactory('SignerCheck') +// const signerDeployed = await signer.deploy() +// await signerDeployed.deployed() +// const signerRet = await signerDeployed.recover(messageSubDigest, relayerSig) // Verify supplied signature against Immutable signer - const immutableSignerAddr = '0x1B1D383526A2815d26550eb314B5d7e055132733' - const immutableSigner = await ethers.getContractAt('ImmutableSigner', immutableSignerAddr) - const immutableSignerPubKey = await immutableSigner.primarySigner() - - // Verify returned signer against Immutable signer - if (signerRet !== immutableSignerPubKey) { - console.log('Signer mismatch') - process.exit(0) - } +// const immutableSignerAddr = '0x1B1D383526A2815d26550eb314B5d7e055132733' +// const immutableSigner = await ethers.getContractAt('ImmutableSigner', immutableSignerAddr) +// const immutableSignerPubKey = await immutableSigner.primarySigner() + +// // Verify returned signer against Immutable signer +// if (signerRet !== immutableSignerPubKey) { +// console.log('Signer mismatch') +// process.exit(0) +// } // Set addresses const scwAddr = '0x3878cadc6a521dceb1f46599913ce726c430a8e1' From 13411eb4f5c8a944da3c5170be0b0c11c906ad3e Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 11:20:48 +1000 Subject: [PATCH 4/9] add storage --- src/contracts/modules/MainModuleDynamicAuthLog.sol | 2 +- tests/EIP712Debug.ts | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/contracts/modules/MainModuleDynamicAuthLog.sol b/src/contracts/modules/MainModuleDynamicAuthLog.sol index 149ce806..29eebd33 100644 --- a/src/contracts/modules/MainModuleDynamicAuthLog.sol +++ b/src/contracts/modules/MainModuleDynamicAuthLog.sol @@ -16,7 +16,7 @@ import "./commons/ModuleUpdate.sol"; * contracts by the mainmodule don't conflict and are accounted for to be * supported by the supportsInterface method. */ -contract MainModuleDynamicAuth is +contract MainModuleDynamicAuthLog is ModuleAuthDynamic, ModuleCalls, ModuleReceivers, diff --git a/tests/EIP712Debug.ts b/tests/EIP712Debug.ts index e5703922..c1f348ef 100644 --- a/tests/EIP712Debug.ts +++ b/tests/EIP712Debug.ts @@ -62,17 +62,10 @@ async function main() { // console.log('MAIN MODULE ADDDR: ', moduleLog.address) console.log("STORAGE AT: ", await ethers.provider.getStorageAt(scwAddr, scwAddr)); console.log('PROXY IMPLEMENTATION: ', await walletProxy.PROXY_getImplementation()) - const implementationValue = "0x0000000000000000000000000" + moduleLog.address.substring(2); + const implementationValue = "0x000000000000000000000000" + moduleLog.address.substring(2); await network.provider.send('hardhat_setStorageAt', [scwAddr, scwAddr, implementationValue]) - // Verify code update - const newCode = await ethers.provider.getCode(mainModuleAddr) - if (newCode !== modLogCode) { - console.log('Code not updated') - process.exit(0) - } - // Do signature verification // Attatch to SCW const moduleAuth = await ethers.getContractAt('ModuleAuth', scwAddr) From 5ecf81f194323089f876e93ad05ced18a8afbffb Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 11:38:56 +1000 Subject: [PATCH 5/9] begin adding log lines --- src/contracts/modules/commons/ModuleAuth.sol | 8 +++++++- utils/config-loader.ts | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/contracts/modules/commons/ModuleAuth.sol b/src/contracts/modules/commons/ModuleAuth.sol index 25cdc1d9..46bd596d 100644 --- a/src/contracts/modules/commons/ModuleAuth.sol +++ b/src/contracts/modules/commons/ModuleAuth.sol @@ -9,6 +9,8 @@ import "./interfaces/IModuleAuth.sol"; import "./ModuleERC165.sol"; +import "hardhat/console.sol"; + abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, IERC1271Wallet { using LibBytes for bytes; @@ -115,6 +117,8 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I // Read dynamic size signature bytes memory signature; (signature, rindex) = _signature.readBytes(rindex, size); + console.log("ModuleAuth: isValidSignature"); + console.logBytes4(isValidSignature(_hash, addr, signature)); require(isValidSignature(_hash, addr, signature), "ModuleAuth#_signatureValidation: INVALID_SIGNATURE"); // Acumulate total weight of the signature @@ -166,7 +170,7 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I // solhint-disable-next-line no-empty-blocks function updateImageHashInternal(bytes32 _imageHash) internal virtual { // Default implementation does nothing - } +} @@ -183,6 +187,7 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I bytes calldata _data, bytes calldata _signatures ) external override view returns (bytes4) { + console.log("====== IS VALID SIGNATURE ======"); // Validate signatures if (_signatureValidationInternal(_subDigest(keccak256(_data)), _signatures)) { return SELECTOR_ERC1271_BYTES_BYTES; @@ -203,6 +208,7 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I bytes32 _hash, bytes calldata _signatures ) external override view returns (bytes4) { + console.log("====== IS VALID SIGNATURE bytes32 HASH ======"); // Validate signatures if (_signatureValidationInternal(_subDigest(_hash), _signatures)) { return SELECTOR_ERC1271_BYTES32_BYTES; diff --git a/utils/config-loader.ts b/utils/config-loader.ts index d59135ea..20942fd8 100644 --- a/utils/config-loader.ts +++ b/utils/config-loader.ts @@ -10,7 +10,7 @@ export const getEnvConfig = (env: string) => { const envLoad = dotenv.config({ path: envFile }) if (envLoad.error) { - console.warn('No config found, using default') + // console.warn('No config found, using default') return { ETH_MNEMONIC: ethers.Wallet.createRandom().mnemonic.phrase } } From 5344a7e54d4b20b4a74b78390e58046de23851f8 Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 11:46:58 +1000 Subject: [PATCH 6/9] more log lines --- src/contracts/modules/commons/ModuleAuth.sol | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/contracts/modules/commons/ModuleAuth.sol b/src/contracts/modules/commons/ModuleAuth.sol index 46bd596d..e33e1e80 100644 --- a/src/contracts/modules/commons/ModuleAuth.sol +++ b/src/contracts/modules/commons/ModuleAuth.sol @@ -103,7 +103,6 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I bytes memory signature; (signature, rindex) = _signature.readBytes66(rindex); addr = recoverSigner(_hash, signature); - // Acumulate total weight of the signature totalWeight += addrWeight; } else if (flag == FLAG_DYNAMIC_SIGNATURE) { @@ -118,7 +117,7 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I bytes memory signature; (signature, rindex) = _signature.readBytes(rindex, size); console.log("ModuleAuth: isValidSignature"); - console.logBytes4(isValidSignature(_hash, addr, signature)); + console.logBool(isValidSignature(_hash, addr, signature)); require(isValidSignature(_hash, addr, signature), "ModuleAuth#_signatureValidation: INVALID_SIGNATURE"); // Acumulate total weight of the signature @@ -132,6 +131,10 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I } (bool verified, bool needsUpdate) = _isValidImage(imageHash); + console.log("Verified"); + console.logBool(verified); + console.log("Needs update"); + console.logBool(needsUpdate); return ((totalWeight >= threshold && verified), needsUpdate, imageHash); } From 7a06e3c3948dd2349bafc107c453aa644e058cb7 Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 13:23:19 +1000 Subject: [PATCH 7/9] add debug2 --- src/contracts/modules/commons/ModuleAuth.sol | 3 +- .../modules/commons/ModuleAuthDynamic.sol | 31 ++++++- tests/EIP712Debug.ts | 4 + tests/EIP712Debug2.ts | 85 +++++++++++++++++++ 4 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 tests/EIP712Debug2.ts diff --git a/src/contracts/modules/commons/ModuleAuth.sol b/src/contracts/modules/commons/ModuleAuth.sol index e33e1e80..5c5d6092 100644 --- a/src/contracts/modules/commons/ModuleAuth.sol +++ b/src/contracts/modules/commons/ModuleAuth.sol @@ -118,7 +118,7 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I (signature, rindex) = _signature.readBytes(rindex, size); console.log("ModuleAuth: isValidSignature"); console.logBool(isValidSignature(_hash, addr, signature)); - require(isValidSignature(_hash, addr, signature), "ModuleAuth#_signatureValidation: INVALID_SIGNATURE"); + require(isValidSignature(_hash, addr, signature), "ModuleAuth#_signatureValidation: INVALID_SIGNATURE"); // Acumulate total weight of the signature totalWeight += addrWeight; @@ -127,6 +127,7 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I } // Write weight and address to image + console.log("Calculating image hash for %s with weight %s", addr, addrWeight); imageHash = keccak256(abi.encode(imageHash, addrWeight, addr)); } diff --git a/src/contracts/modules/commons/ModuleAuthDynamic.sol b/src/contracts/modules/commons/ModuleAuthDynamic.sol index 505c4ed8..bec28050 100644 --- a/src/contracts/modules/commons/ModuleAuthDynamic.sol +++ b/src/contracts/modules/commons/ModuleAuthDynamic.sol @@ -28,7 +28,36 @@ abstract contract ModuleAuthDynamic is ModuleAuthUpgradable { * @return true if the signature image is valid, and true if the image hash needs to be updated */ function _isValidImage(bytes32 _imageHash) internal view override returns (bool, bool) { + console.log("IS VALID IMAGE 1:"); + console.logBytes32(_imageHash); + console.log("GOT %s", address( + uint160(uint256( + keccak256( + abi.encodePacked( + bytes1(0xff), + FACTORY, + _imageHash, + INIT_CODE_HASH + ) + ) + )) + )); + console.log("WANT %s", address(this)); bytes32 storedImageHash = ModuleStorage.readBytes32(ImageHashKey.IMAGE_HASH_KEY); + console.log("STORED IMAGE HASH: "); + console.logBytes32(storedImageHash); + address( + uint160(uint256( + keccak256( + abi.encodePacked( + bytes1(0xff), + FACTORY, + _imageHash, + INIT_CODE_HASH + ) + ) + )) + ); if (storedImageHash == 0) { // No image hash stored. Check that the image hash was used as the salt when // deploying the wallet proxy contract. @@ -47,7 +76,7 @@ abstract contract ModuleAuthDynamic is ModuleAuthUpgradable { // Indicate need to update = true. This will trigger a call to store the image hash return (authenticated, true); } - + // Image hash has been stored. return ((_imageHash != bytes32(0) && _imageHash == storedImageHash), false); } diff --git a/tests/EIP712Debug.ts b/tests/EIP712Debug.ts index c1f348ef..438b39b6 100644 --- a/tests/EIP712Debug.ts +++ b/tests/EIP712Debug.ts @@ -9,6 +9,10 @@ import { ethers, network } from 'hardhat' // Do signature verification // inspect console.log lines +// "passport": { +// "zkevm_eth_address": "0x3878cadc6a521dceb1f46599913ce726c430a8e1", +// "zkevm_user_admin_address": "0xa110e9ccdc3714d1dabb2f25e8883061f75011bd" + async function main() { // Get signature values const typedHash = '0x0b8f209be8d541a4ded6b82c0414aac2cee9cb89f19518b6ee1502ba555cb16c' diff --git a/tests/EIP712Debug2.ts b/tests/EIP712Debug2.ts new file mode 100644 index 00000000..23c5cf99 --- /dev/null +++ b/tests/EIP712Debug2.ts @@ -0,0 +1,85 @@ +import { ethers, network } from 'hardhat' + +// Fork network @ https://rpc.testnet.immutable.com/ +// Attach contract at LatestWalletImplLocator +// Get MainModuleDynamicAuth address +// Deploy MainModuleDynamicAuth (with console logs) +// Get code at the newly deployed MainModuleDynamicAuth (w/ logs) +// Set the code at the MainModuleDynamicAuth to be the newly deployed MainModuleDynamicAuth (w/ logs) +// Do signature verification +// inspect console.log lines + +// "passport": { + // "zkevm_eth_address": "0x3878cadc6a521dceb1f46599913ce726c430a8e1", + // "zkevm_user_admin_address": "0xa110e9ccdc3714d1dabb2f25e8883061f75011bd" + +async function main() { + // Get signature values + const typedHash = '0xe8a936e6c05a3cfea78c9df4bbcec02a3253d7358ba15b42f78aba327e25c180' + const messageSubDigest = '0xede3e129db20579573bccededc094e9a0f3cb8c8df59bbf3526eb7072bffa6f3' + const packedAggregateSignature = + '0x000202011b1d383526a2815d26550eb314b5d7e0551327330043a9b3a8608b3f49eaeedaa13f60967982a8b40abe3203f027787b125b273f780f669b07583967f86e2ad0f4100094b91586b5d89bde8e6fcd0236f5ece8ffd4391b01030001294c4e19c04efff53c34ed7a2997bb9161b0c7f33db3af1148c66eb63d6593a668bb0da9bd32fcc3bbed426d515dff22886245a3583d2e275add28418ca2c63e1b02' + const relayerSig = + '0xc9d1d1d25201bd592da3eb99a5c4568105a79c168b93eebe2444ddf1f7a61174394b2b8616ba8ce9aae7741e2131caf66b80773f3557e18ec0d93a68a17090cb1b01' + + // Recover signer +// const signer = await ethers.getContractFactory('SignerCheck') +// const signerDeployed = await signer.deploy() +// await signerDeployed.deployed() +// const signerRet = await signerDeployed.recover(messageSubDigest, relayerSig) + + // Verify supplied signature against Immutable signer +// const immutableSignerAddr = '0x1B1D383526A2815d26550eb314B5d7e055132733' +// const immutableSigner = await ethers.getContractAt('ImmutableSigner', immutableSignerAddr) +// const immutableSignerPubKey = await immutableSigner.primarySigner() + +// // Verify returned signer against Immutable signer +// if (signerRet !== immutableSignerPubKey) { +// console.log('Signer mismatch') +// process.exit(0) +// } + + // Set addresses + const scwAddr = '0x0aa0bbd0bde831fd2288bc397b6b76f73d960650' + const factoryAddr = '0x55b9d1cd803d5acA8ea23ccd96f6a756DED9f5a9' + const startupAddr = '0x8df826438e652f7124fe07F413fA3556cd57edB5' + const walletImplLocatorAddr = '0x657d339b8616033fee25f66ea1d00c3f30b14171' + + // Get MainModuleDynamicAuth address + const walletImplLocator = await ethers.getContractAt('LatestWalletImplLocator', walletImplLocatorAddr) + const mainModuleAddr = await walletImplLocator.latestWalletImplementation() + + // Deploy new MainModuleDynamicAuthLog + const ModuleLog = await ethers.getContractFactory('MainModuleDynamicAuthLog') + const moduleLog = await ModuleLog.deploy(factoryAddr, startupAddr) + await moduleLog.deployed() + + // Get code for logging + const modLogCode = await ethers.provider.getCode(moduleLog.address) + + // Get address for main module + const walletProxy = await ethers.getContractAt('IWalletProxy', scwAddr) + + // Set code + // await network.provider.send('hardhat_setCode', [mainModuleAddr, modLogCode]) + // await network.provider.send('hardhat_mine', ["0x100"]) +// console.log('MAIN MODULE ADDDR: ', moduleLog.address) + console.log("STORAGE AT: ", await ethers.provider.getStorageAt(scwAddr, scwAddr)); + console.log('PROXY IMPLEMENTATION: ', await walletProxy.PROXY_getImplementation()) + const implementationValue = "0x000000000000000000000000" + moduleLog.address.substring(2); + await network.provider.send('hardhat_setStorageAt', [scwAddr, scwAddr, implementationValue]) + + + // Do signature verification + // Attatch to SCW + const moduleAuth = await ethers.getContractAt('ModuleAuth', scwAddr) + // Verify 2-of-2 signature + const magicValue = await moduleAuth['isValidSignature(bytes32,bytes)'](typedHash, packedAggregateSignature) + + console.log('MAGIC VALUE', magicValue) +} + +main().catch(error => { + console.error(error) + process.exit(1) +}) From 211fcfe2f815199b932b1eda8c632d9ec8c3db5f Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 13:25:11 +1000 Subject: [PATCH 8/9] add debug2 --- tests/EIP712Debug2.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/EIP712Debug2.ts b/tests/EIP712Debug2.ts index 23c5cf99..b06ee6f2 100644 --- a/tests/EIP712Debug2.ts +++ b/tests/EIP712Debug2.ts @@ -9,9 +9,9 @@ import { ethers, network } from 'hardhat' // Do signature verification // inspect console.log lines -// "passport": { - // "zkevm_eth_address": "0x3878cadc6a521dceb1f46599913ce726c430a8e1", - // "zkevm_user_admin_address": "0xa110e9ccdc3714d1dabb2f25e8883061f75011bd" +// "passport": { +// "zkevm_eth_address": "0x3878cadc6a521dceb1f46599913ce726c430a8e1", +// "zkevm_user_admin_address": "0xa110e9ccdc3714d1dabb2f25e8883061f75011bd" async function main() { // Get signature values @@ -67,6 +67,7 @@ async function main() { console.log("STORAGE AT: ", await ethers.provider.getStorageAt(scwAddr, scwAddr)); console.log('PROXY IMPLEMENTATION: ', await walletProxy.PROXY_getImplementation()) const implementationValue = "0x000000000000000000000000" + moduleLog.address.substring(2); + console.log() await network.provider.send('hardhat_setStorageAt', [scwAddr, scwAddr, implementationValue]) From 7824b5f24b2e0eb2dc465ecb5cd71f3984556b73 Mon Sep 17 00:00:00 2001 From: James Snewin Date: Thu, 18 Jan 2024 14:35:31 +1000 Subject: [PATCH 9/9] console log changes --- src/contracts/modules/commons/ModuleAuth.sol | 2 +- src/contracts/modules/commons/ModuleAuthDynamic.sol | 12 ++++++++++++ tests/EIP712Debug2.ts | 3 +-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/contracts/modules/commons/ModuleAuth.sol b/src/contracts/modules/commons/ModuleAuth.sol index 5c5d6092..2f736beb 100644 --- a/src/contracts/modules/commons/ModuleAuth.sol +++ b/src/contracts/modules/commons/ModuleAuth.sol @@ -130,7 +130,7 @@ abstract contract ModuleAuth is IModuleAuth, ModuleERC165, SignatureValidator, I console.log("Calculating image hash for %s with weight %s", addr, addrWeight); imageHash = keccak256(abi.encode(imageHash, addrWeight, addr)); } - + (bool verified, bool needsUpdate) = _isValidImage(imageHash); console.log("Verified"); console.logBool(verified); diff --git a/src/contracts/modules/commons/ModuleAuthDynamic.sol b/src/contracts/modules/commons/ModuleAuthDynamic.sol index bec28050..58668420 100644 --- a/src/contracts/modules/commons/ModuleAuthDynamic.sol +++ b/src/contracts/modules/commons/ModuleAuthDynamic.sol @@ -44,6 +44,18 @@ abstract contract ModuleAuthDynamic is ModuleAuthUpgradable { )); console.log("WANT %s", address(this)); bytes32 storedImageHash = ModuleStorage.readBytes32(ImageHashKey.IMAGE_HASH_KEY); + console.log("WANT (calculate) %s", address( + uint160(uint256( + keccak256( + abi.encodePacked( + bytes1(0xff), + FACTORY, + storedImageHash, + INIT_CODE_HASH + ) + ) + )) + )); console.log("STORED IMAGE HASH: "); console.logBytes32(storedImageHash); address( diff --git a/tests/EIP712Debug2.ts b/tests/EIP712Debug2.ts index b06ee6f2..3a41a43a 100644 --- a/tests/EIP712Debug2.ts +++ b/tests/EIP712Debug2.ts @@ -67,8 +67,7 @@ async function main() { console.log("STORAGE AT: ", await ethers.provider.getStorageAt(scwAddr, scwAddr)); console.log('PROXY IMPLEMENTATION: ', await walletProxy.PROXY_getImplementation()) const implementationValue = "0x000000000000000000000000" + moduleLog.address.substring(2); - console.log() - await network.provider.send('hardhat_setStorageAt', [scwAddr, scwAddr, implementationValue]) + await network.provider.send('hardhat_setStorageAt', [scwAddr, "0xaa0bbd0bde831fd2288bc397b6b76f73d960650", implementationValue]) // Do signature verification