-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/fallback selector security check #85
Merged
Merged
Changes from 5 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
67864e1
chore: Fix indentation
Aboudjem d8e1252
🔒 Improve security on fallback handler installation process
Aboudjem 2ced21b
Update gas report file name to uppercase + run prettier
Aboudjem dd22160
feat: Update gas report file name to uppercase
Aboudjem 6d09a7b
chore: Update CI workflow to trigger only on pull requests
Aboudjem ccf87c4
Merge branch 'dev' into feat/fallback-selector-security-check
Aboudjem ae249db
chore: Improve fallback handler comments
Aboudjem c1d0b86
Merge branch 'feat/fallback-selector-security-check' of https://githu…
Aboudjem 4acff06
refactor: Update gas report script paths and improve generation
Aboudjem 9e25afd
refactor: Update gas report script paths and improve generation
Aboudjem c474f45
feat: Update gas report script paths and improve generation
Aboudjem 4115305
Merge branch 'dev' into feat/fallback-selector-security-check
Aboudjem 4e554b4
refactor: Update gas report script paths and improve generation
Aboudjem 983093f
Merge branch 'dev' into feat/fallback-selector-security-check
Aboudjem 3a03ad7
Merge branch 'dev' into feat/fallback-selector-security-check
Aboudjem File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,140 @@ | ||
const fs = require('fs'); | ||
const readline = require('readline'); | ||
const { exec } = require('child_process'); | ||
const fs = require("fs"); | ||
const readline = require("readline"); | ||
const { exec } = require("child_process"); | ||
|
||
// Define the log file and the output markdown file | ||
const LOG_FILE = 'gas.log'; | ||
const OUTPUT_FILE = 'gas_report.md'; | ||
const LOG_FILE = "gas.log"; | ||
const OUTPUT_FILE = "GAS_REPORT.md"; | ||
|
||
// Function to execute the `forge test` command | ||
function runForgeTest() { | ||
return new Promise((resolve, reject) => { | ||
console.log('🚀 Running forge tests, this may take a few minutes...'); | ||
exec('forge test -vv --mt test_Gas > gas.log', (error, stdout, stderr) => { | ||
if (error) { | ||
console.error(`❌ Exec error: ${error}`); | ||
reject(`exec error: ${error}`); | ||
} | ||
console.log('✅ Forge tests completed.'); | ||
resolve(stdout ? stdout : stderr); | ||
}); | ||
return new Promise((resolve, reject) => { | ||
console.log("🚀 Running forge tests, this may take a few minutes..."); | ||
exec("forge test -vv --mt test_Gas > gas.log", (error, stdout, stderr) => { | ||
if (error) { | ||
console.error(`❌ Exec error: ${error}`); | ||
reject(`exec error: ${error}`); | ||
} | ||
console.log("✅ Forge tests completed."); | ||
resolve(stdout ? stdout : stderr); | ||
}); | ||
}); | ||
} | ||
|
||
// Function to parse the log file and generate the report | ||
async function generateReport() { | ||
await runForgeTest(); | ||
|
||
const fileStream = fs.createReadStream(LOG_FILE); | ||
const rl = readline.createInterface({ | ||
input: fileStream, | ||
crlfDelay: Infinity | ||
}); | ||
|
||
const results = []; | ||
|
||
console.log('📄 Parsing log file, please wait...'); | ||
for await (const line of rl) { | ||
console.log(line); | ||
if (line.includes('::')) { | ||
const parts = line.split('::'); | ||
const PROTOCOL = parts[0]; | ||
const ACTION_FUNCTION = parts[1]; | ||
let ACCOUNT_TYPE; | ||
let IS_DEPLOYED; | ||
if (line.includes('EOA')) { | ||
ACCOUNT_TYPE = 'EOA'; | ||
IS_DEPLOYED = 'False'; | ||
} else if (line.includes('Nexus')) { | ||
ACCOUNT_TYPE = 'Smart Account'; | ||
IS_DEPLOYED = 'True'; | ||
} else { | ||
ACCOUNT_TYPE = 'Smart Account'; | ||
IS_DEPLOYED = 'False'; | ||
} | ||
|
||
const WITH_PAYMASTER = line.includes('WithPaymaster') ? 'True' : 'False'; | ||
|
||
const GAS_INFO = parts[4]; | ||
const ACCESS_TYPE = GAS_INFO.split(': ')[0]; | ||
const GAS_USED = GAS_INFO.split(': ')[1]; | ||
|
||
let RECEIVER_ACCESS; | ||
if (ACCESS_TYPE === 'ColdAccess') { | ||
RECEIVER_ACCESS = '🧊 ColdAccess'; | ||
} else if (ACCESS_TYPE === 'WarmAccess') { | ||
RECEIVER_ACCESS = '🔥 WarmAccess'; | ||
} else { | ||
RECEIVER_ACCESS = 'N/A'; | ||
} | ||
|
||
results.push({ | ||
PROTOCOL, | ||
ACTION_FUNCTION, | ||
ACCOUNT_TYPE, | ||
IS_DEPLOYED, | ||
WITH_PAYMASTER, | ||
RECEIVER_ACCESS, | ||
GAS_USED, | ||
FULL_LOG: line.trim() | ||
}); | ||
} | ||
await runForgeTest(); | ||
|
||
const fileStream = fs.createReadStream(LOG_FILE); | ||
const rl = readline.createInterface({ | ||
input: fileStream, | ||
crlfDelay: Infinity, | ||
}); | ||
|
||
const results = []; | ||
|
||
console.log("📄 Parsing log file, please wait..."); | ||
for await (const line of rl) { | ||
console.log(line); | ||
if (line.includes("::")) { | ||
const parts = line.split("::"); | ||
const PROTOCOL = parts[0]; | ||
const ACTION_FUNCTION = parts[1]; | ||
let ACCOUNT_TYPE; | ||
let IS_DEPLOYED; | ||
if (line.includes("EOA")) { | ||
ACCOUNT_TYPE = "EOA"; | ||
IS_DEPLOYED = "False"; | ||
} else if (line.includes("Nexus")) { | ||
ACCOUNT_TYPE = "Smart Account"; | ||
IS_DEPLOYED = "True"; | ||
} else { | ||
ACCOUNT_TYPE = "Smart Account"; | ||
IS_DEPLOYED = "False"; | ||
} | ||
|
||
const WITH_PAYMASTER = line.includes("WithPaymaster") ? "True" : "False"; | ||
|
||
const GAS_INFO = parts[4]; | ||
const ACCESS_TYPE = GAS_INFO.split(": ")[0]; | ||
const GAS_USED = GAS_INFO.split(": ")[1]; | ||
|
||
let RECEIVER_ACCESS; | ||
if (ACCESS_TYPE === "ColdAccess") { | ||
RECEIVER_ACCESS = "🧊 ColdAccess"; | ||
} else if (ACCESS_TYPE === "WarmAccess") { | ||
RECEIVER_ACCESS = "🔥 WarmAccess"; | ||
} else { | ||
RECEIVER_ACCESS = "N/A"; | ||
} | ||
|
||
results.push({ | ||
PROTOCOL, | ||
ACTION_FUNCTION, | ||
ACCOUNT_TYPE, | ||
IS_DEPLOYED, | ||
WITH_PAYMASTER, | ||
RECEIVER_ACCESS, | ||
GAS_USED, | ||
FULL_LOG: line.trim(), | ||
}); | ||
} | ||
|
||
console.log('🔄 Sorting results...'); | ||
// Custom sort: Group by protocol alphabetically, then by EOA first, Smart Account with Is Deployed=True next, then the rest | ||
results.sort((a, b) => { | ||
if (a.PROTOCOL < b.PROTOCOL) return -1; | ||
if (a.PROTOCOL > b.PROTOCOL) return 1; | ||
if (a.ACCOUNT_TYPE === 'EOA' && b.ACCOUNT_TYPE !== 'EOA') return -1; | ||
if (a.ACCOUNT_TYPE !== 'EOA' && b.ACCOUNT_TYPE === 'EOA') return 1; | ||
if (a.IS_DEPLOYED === 'True' && b.IS_DEPLOYED !== 'True') return -1; | ||
if (a.IS_DEPLOYED !== 'True' && b.IS_DEPLOYED === 'True') return 1; | ||
return 0; | ||
} | ||
|
||
console.log("🔄 Sorting results..."); | ||
// Custom sort: Group by protocol alphabetically, then by EOA first, Smart Account with Is Deployed=True next, then the rest | ||
results.sort((a, b) => { | ||
if (a.PROTOCOL < b.PROTOCOL) return -1; | ||
if (a.PROTOCOL > b.PROTOCOL) return 1; | ||
if (a.ACCOUNT_TYPE === "EOA" && b.ACCOUNT_TYPE !== "EOA") return -1; | ||
if (a.ACCOUNT_TYPE !== "EOA" && b.ACCOUNT_TYPE === "EOA") return 1; | ||
if (a.IS_DEPLOYED === "True" && b.IS_DEPLOYED !== "True") return -1; | ||
if (a.IS_DEPLOYED !== "True" && b.IS_DEPLOYED === "True") return 1; | ||
return 0; | ||
}); | ||
|
||
console.log("🖋️ Writing report..."); | ||
// Write the report | ||
const outputStream = fs.createWriteStream(OUTPUT_FILE); | ||
outputStream.write("# Gas Report\n"); | ||
outputStream.write( | ||
"| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Full Log** |\n", | ||
); | ||
outputStream.write( | ||
"|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:-------------:|\n", | ||
); | ||
|
||
results.forEach((result) => { | ||
outputStream.write( | ||
`| ${result.PROTOCOL} | ${result.ACTION_FUNCTION} | ${result.ACCOUNT_TYPE} | ${result.IS_DEPLOYED} | ${result.WITH_PAYMASTER} | ${result.RECEIVER_ACCESS} | ${result.GAS_USED} | ${result.FULL_LOG} |\n`, | ||
); | ||
}); | ||
|
||
console.log(`📊 Gas report generated and saved to ${OUTPUT_FILE}`); | ||
|
||
// Run prettier to format the generated markdown file | ||
return new Promise((resolve, reject) => { | ||
console.log("✨ Running prettier to format the gas report..."); | ||
exec(`npx prettier --write ${OUTPUT_FILE}`, (error, stdout, stderr) => { | ||
if (error) { | ||
console.error(`❌ Prettier error: ${error}`); | ||
reject(`prettier error: ${error}`); | ||
} | ||
console.log("✅ Prettier formatting completed."); | ||
resolve(stdout ? stdout : stderr); | ||
}); | ||
|
||
console.log('🖋️ Writing report...'); | ||
// Write the report | ||
const outputStream = fs.createWriteStream(OUTPUT_FILE); | ||
outputStream.write("# Gas Report\n"); | ||
outputStream.write("| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Full Log** |\n"); | ||
outputStream.write("|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:-------------:|\n"); | ||
|
||
results.forEach(result => { | ||
outputStream.write(`| ${result.PROTOCOL} | ${result.ACTION_FUNCTION} | ${result.ACCOUNT_TYPE} | ${result.IS_DEPLOYED} | ${result.WITH_PAYMASTER} | ${result.RECEIVER_ACCESS} | ${result.GAS_USED} | ${result.FULL_LOG} |\n`); | ||
}); | ||
|
||
console.log(`📊 Gas report generated and saved to ${OUTPUT_FILE}`); | ||
}); | ||
} | ||
|
||
// Function to clean up temporary files | ||
function cleanUp() { | ||
fs.unlink(LOG_FILE, (err) => { | ||
if (err) console.error(`❌ Error deleting ${LOG_FILE}: ${err}`); | ||
else console.log(`🗑️ ${LOG_FILE} deleted successfully.`); | ||
}); | ||
fs.unlink(LOG_FILE, (err) => { | ||
if (err) console.error(`❌ Error deleting ${LOG_FILE}: ${err}`); | ||
else console.log(`🗑️ ${LOG_FILE} deleted successfully.`); | ||
}); | ||
} | ||
|
||
// Run the function to generate the report and then clean up | ||
// Run the function to generate the report, format it with prettier, and then clean up | ||
generateReport() | ||
.then(cleanUp) | ||
.catch(console.error); | ||
.then(cleanUp) | ||
.catch(console.error); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you describe what's the unexpected security behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"If it’s added a fallback method. Anyone can uninstall and reinstall the module. If it’s a validator, this will most likely pwn the account"