solidity-audit
Version:
Solidity Audit Code
519 lines (448 loc) โข 18.4 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="header" style="display: flex; position: relative;">
<div style="z-index: 0;">
<img class="bgr-header"
src="/Volumes/Extreme SSD/nextjs/solidity-metrics/public/images/bgr-header.png"
alt="Background Header"
style="
position: absolute;
width: 100%;
height: 100vh;
background-repeat: no-repeat;
object-fit: cover;
"
/>
<div style="position: absolute; top: 72px; bottom: 0; left: 64px; height: 80vh;">
<div style="margin-bottom: auto; justify-content: space-between;">
<img class="ic-logo"
src="/Volumes/Extreme SSD/nextjs/solidity-metrics/public/images/Logo.svg"
/>
<p id="p-security" style="color: #6B7280; padding: 0; margin: 0; margin-top: 64px;">Security Assessment</p>
<h2 id="h2-defi" style="color: white; z-index: 100; padding: 4px 0 8px 0; margin: 0;">DeFi Exchange - Audit</h2>
<p id="p-verified" style="color: #6B7280; z-index: 100; padding: 0; margin: 0;" color: white;>TechRight Verified on Mar 18th, 2023</p>
</div>
<img
src="/Volumes/Extreme SSD/nextjs/solidity-metrics/public/images/ic-qr.png"
style="height: 98px; width: 98px; margin-bottom: 64px; margin-top: calc(80vh - 248px);"
/>
</div>
</div>
</div>
<!-- <a onclick="/*toggleVisibility('doppelganger-contracts', this)*/">[โ]</a> -->
<div id="doppelganger-contracts" style="display: none">
<img
src="./public/images/bgr-header.png"
alt="Background Header"
style="width: 100%; height: 100vh"
/>
<img
width="200"
alt="get in touch with Consensys Diligence"
src="https://user-images.githubusercontent.com/2865694/56826101-91dcf380-685b-11e9-937c-af49c2510aa0.png"
/>(https://diligence.consensys.net)<br />
<div>
<a href="https://diligence.consensys.net">
<img src="๐" alt="https://diligence.consensys.net"
/></a>
<a href="mailto:diligence@consensys.net"
><img src="๐ฉ" alt="mailto:diligence@consensys.net"
/></a>
<a href="https://consensys.github.io/diligence/"
><img src="๐ฅ" alt="https://consensys.github.io/diligence/"
/></a>
</div>
<!-- [[ ๐ ](https://diligence.consensys.net) [ ๐ฉ ](mailto:diligence@consensys.net) [ ๐ฅ ](https://consensys.github.io/diligence/)] -->
</div>
<!-- # Solidity Metrics for ${this.name}
## Table of contents
- [Scope](#t-scope)
- [Source Units in Scope](#t-source-Units-in-Scope)
- [Out of Scope](#t-out-of-scope)
- [Excluded Source Units](#t-out-of-scope-excluded-source-units)
- [Duplicate Source Units](#t-out-of-scope-duplicate-source-units)${doppelgangerToC}
- [Report Overview](#t-report)
- [Risk Summary](#t-risk)
- [Source Lines](#t-source-lines)
- [Inline Documentation](#t-inline-documentation)
- [Components](#t-components)
- [Exposed Functions](#t-exposed-functions)
- [StateVariables](#t-statevariables)
- [Capabilities](#t-capabilities)
- [Dependencies](#t-package-imports)
- [Totals](#t-totals)
## <span id=t-scope>Scope</span>
This section lists files that are in scope for the metrics report.
- **Project:** \`${this.name}\`
- **Included Files:** ${
`\n` +
this.inputFileGlob
.replace("{", "")
.replace("}", "")
.split(",")
.map((g) => ` - \`${g}\``)
.join("\n")
}
- **Excluded Paths:** ${
`\n` +
this.inputFileGlobExclusions
.replace("{", "")
.replace("}", "")
.split(",")
.map((g) => ` - \`${g}\``)
.join("\n")
}
- **File Limit:** \`${this.inputFileGlobLimit}\`
- **Exclude File list Limit:** \`${this.excludeFileGlobLimit}\`
- **Workspace Repository:** \`${this.repoInfo.remote || "unknown"}\` (\`${
this.repoInfo.branch
}\`@\`${this.repoInfo.commit}\`)
### <span id=t-source-Units-in-Scope>Source Units in Scope</span>
Source Units Analyzed: **\`${this.seenFiles.length}\`**<br>
Source Units in Scope: **\`${this.metrics.length}\`** (**${Math.round(
(this.metrics.length / this.seenFiles.length) * 100
)}%**)
| Type | File | Logic Contracts | Interfaces | Lines | nLines | nSLOC | Comment Lines | Complex. Score | Capabilities |
| ---- | ------ | --------------- | ---------- | ----- | ------ | ----- | ------------- | -------------- | ------------ |
${this.metrics
.map(
(m) =>
`| ${m.metrics.num.contracts ? "๐" : ""}${
m.metrics.num.libraries ? "๐" : ""
}${m.metrics.num.interfaces ? "๐" : ""}${
m.metrics.num.abstract ? "๐จ" : ""
} | ${m.filename.replace(this.basePath, "")} | ${
m.metrics.num.contracts +
m.metrics.num.libraries +
m.metrics.num.abstract || "****"
} | ${m.metrics.num.interfaces || "****"} | ${
m.metrics.sloc.total || "****"
} | ${m.metrics.nsloc.total || "****"} | ${
m.metrics.nsloc.source || "****"
} | ${m.metrics.sloc.comment || "****"} | ${
m.metrics.complexity.perceivedNaiveScore || "****"
} | **${
m.metrics.capabilities.assembly
? "<abbr title='Uses Assembly'>๐ฅ</abbr>"
: ""
}${
m.metrics.capabilities.experimental.length
? "<abbr title='Experimental Features'>๐งช</abbr>"
: ""
}${
m.metrics.capabilities.canReceiveFunds
? "<abbr title='Payable Functions'>๐ฐ</abbr>"
: ""
}${
m.metrics.capabilities.destroyable
? "<abbr title='Destroyable Contract'>๐ฃ</abbr>"
: ""
}${
m.metrics.capabilities.explicitValueTransfer
? "<abbr title='Initiates ETH Value Transfer'>๐ค</abbr>"
: ""
}${
m.metrics.capabilities.lowLevelCall
? "<abbr title='Performs Low-Level Calls'>โก</abbr>"
: ""
}${
m.metrics.capabilities.delegateCall
? "<abbr title='DelegateCall'>๐ฅ</abbr>"
: ""
}${
m.metrics.capabilities.hashFuncs
? "<abbr title='Uses Hash-Functions'>๐งฎ</abbr>"
: ""
}${
m.metrics.capabilities.ecrecover
? "<abbr title='Handles Signatures: ecrecover'>๐</abbr>"
: ""
}${
m.metrics.capabilities.deploysContract
? "<abbr title='create/create2'>๐</abbr>"
: ""
}${
doppelGanger !== undefined &&
pathToDoppelganger &&
pathToDoppelganger[m.filename.replace(this.basePath, "")]
? "<abbr title='doppelganger(" +
pathToDoppelganger[m.filename.replace(this.basePath, "")]
.map((r) => r.target.name)
.join(", ") +
")'>๐</abbr>"
: ""
}${
m.metrics.capabilities.tryCatchBlocks
? "<abbr title='TryCatch Blocks'>โป๏ธ</abbr>"
: ""
}${
m.metrics.capabilities.uncheckedBlocks
? "<abbr title='Unchecked Blocks'>ฮฃ</abbr>"
: ""
}** |`
)
.join("\n")}
| ${totals.totals.num.contracts ? "๐" : ""}${
totals.totals.num.libraries ? "๐" : ""
}${totals.totals.num.interfaces ? "๐" : ""}${
totals.totals.num.abstract ? "๐จ" : ""
} | **Totals** | **${
totals.totals.num.contracts +
totals.totals.num.libraries +
totals.totals.num.abstract || ""
}** | **${totals.totals.num.interfaces || ""}** | **${
totals.totals.sloc.total
}** | **${totals.totals.nsloc.total}** | **${
totals.totals.nsloc.source
}** | **${totals.totals.sloc.comment}** | **${
totals.totals.complexity.perceivedNaiveScore
}** | **${
totals.totals.capabilities.assembly
? "<abbr title='Uses Assembly'>๐ฅ</abbr>"
: ""
}${
totals.totals.capabilities.experimental.length
? "<abbr title='Experimental Features'>๐งช</abbr>"
: ""
}${
totals.totals.capabilities.canReceiveFunds
? "<abbr title='Payable Functions'>๐ฐ</abbr>"
: ""
}${
totals.totals.capabilities.destroyable
? "<abbr title='Destroyable Contract'>๐ฃ</abbr>"
: ""
}${
totals.totals.capabilities.explicitValueTransfer
? "<abbr title='Initiates ETH Value Transfer'>๐ค</abbr>"
: ""
}${
totals.totals.capabilities.lowLevelCall
? "<abbr title='Performs Low-Level Calls'>โก</abbr>"
: ""
}${
totals.totals.capabilities.delegateCall
? "<abbr title='DelegateCall'>๐ฅ</abbr>"
: ""
}${
totals.totals.capabilities.hashFuncs
? "<abbr title='Uses Hash-Functions'>๐งฎ</abbr>"
: ""
}${
totals.totals.capabilities.ecrecover
? "<abbr title='Handles Signatures: ecrecover'>๐</abbr>"
: ""
}${
totals.totals.capabilities.deploysContract
? "<abbr title='create/create2'>๐</abbr>"
: ""
}${
doppelGanger !== undefined &&
pathToDoppelganger &&
Object.keys(pathToDoppelganger).length
? "<abbr title='doppelganger'>๐</abbr>"
: ""
}${
totals.totals.capabilities.tryCatchBlocks
? "<abbr title='TryCatch Blocks'>โป๏ธ</abbr>"
: ""
}${
totals.totals.capabilities.uncheckedBlocks
? "<abbr title='Unchecked Blocks'>ฮฃ</abbr>"
: ""
}** |
<sub>
Legend: <a onclick="toggleVisibility('table-legend', this)">[โ]</a>
<div id="table-legend" style="display:none">
<ul>
<li> <b>Lines</b>: total lines of the source unit </li>
<li> <b>nLines</b>: normalized lines of the source unit (e.g. normalizes functions spanning multiple lines) </li>
<li> <b>nSLOC</b>: normalized source lines of code (only source-code lines; no comments, no blank lines) </li>
<li> <b>Comment Lines</b>: lines containing single or block comments </li>
<li> <b>Complexity Score</b>: a custom complexity score derived from code statements that are known to introduce code complexity (branches, loops, calls, external interfaces, ...) </li>
</ul>
</div>
</sub>
#### <span id=t-out-of-scope>Out of Scope</span>
##### <span id=t-out-of-scope-excluded-source-units>Excluded Source Units</span>
Source Units Excluded: **\`${this.excludedFiles.length}\`**
<a onclick="toggleVisibility('excluded-files', this)">[โ]</a>
<div id="excluded-files" style="display:none">
| File |
| ------ |
${
this.excludedFiles.length
? this.excludedFiles
.map((f) => `|${f.replace(this.basePath, "")}|`)
.join("\n")
: "| None |"
}
</div>
##### <span id=t-out-of-scope-duplicate-source-units>Duplicate Source Units</span>
Duplicate Source Units Excluded: **\`${this.seenDuplicates.length}\`**
<a onclick="toggleVisibility('duplicate-files', this)">[โ]</a>
<div id="duplicate-files" style="display:none">
| File |
| ------ |
${
this.seenDuplicates.length
? this.seenDuplicates
.map((f) => `|${f.replace(this.basePath, "")}|`)
.join("\n")
: "| None |"
}
</div>
${doppelgangerSection}
</div>
## <span id=t-report>Report</span>
### Overview
The analysis finished with **\`${this.errors.length}\`** errors and **\`${
this.seenDuplicates.length
}\`** duplicate files.
${this.errors.length ? "**Errors:**\n\n" + this.errors.join("\n* ") : ""}
${
this.truffleProjectLocations.length
? "**Truffle Project Locations Observed:**\n* " +
this.truffleProjectLocations
.map((f) => "./" + f.replace(this.basePath, ""))
.join("\n* ")
: ""
}
#### <span id=t-risk>Risk</span>
<div class="wrapper" style="max-width: 512px; margin: auto">
<canvas id="chart-risk-summary"></canvas>
</div>
#### <span id=t-source-lines>Source Lines (sloc vs. nsloc)</span>
<div class="wrapper" style="max-width: 512px; margin: auto">
<canvas id="chart-nsloc-total"></canvas>
</div>
#### <span id=t-inline-documentation>Inline Documentation</span>
- **Comment-to-Source Ratio:** On average there are\`${
Math.round(
(totals.totals.sloc.source / totals.totals.sloc.comment) * 100
) / 100
}\` code lines per comment (lower=better).
- **ToDo's:** \`${totals.totals.sloc.todo}\`
#### <span id=t-components>Components</span>
| ๐Contracts | ๐Libraries | ๐Interfaces | ๐จAbstract |
| ------------- | ----------- | ------------ | ---------- |
| ${totals.totals.num.contracts} | ${totals.totals.num.libraries} | ${
totals.totals.num.interfaces
} | ${totals.totals.num.abstract} |
#### <span id=t-exposed-functions>Exposed Functions</span>
This section lists functions that are explicitly declared public or payable. Please note that getter methods for public stateVars are not included.
| ๐Public | ๐ฐPayable |
| ---------- | --------- |
| ${totals.totals.num.functionsPublic} | ${
totals.totals.num.functionsPayable
} |
| External | Internal | Private | Pure | View |
| ---------- | -------- | ------- | ---- | ---- |
| ${totals.totals.ast["FunctionDefinition:External"] || 0} | ${
totals.totals.ast["FunctionDefinition:Internal"] || 0
} | ${totals.totals.ast["FunctionDefinition:Private"] || 0} | ${
totals.totals.ast["FunctionDefinition:Pure"] || 0
} | ${totals.totals.ast["FunctionDefinition:View"] || 0} |
#### <span id=t-statevariables>StateVariables</span>
| Total | ๐Public |
| ---------- | --------- |
| ${totals.totals.num.stateVars} | ${totals.totals.num.stateVarsPublic} |
#### <span id=t-capabilities>Capabilities</span>
| Solidity Versions observed | ๐งช Experimental Features | ๐ฐ Can Receive Funds | ๐ฅ Uses Assembly | ๐ฃ Has Destroyable Contracts |
| -------------------------- | ------------------------ | -------------------- | ---------------- | ---------------------------- |
| ${totals.totals.capabilities.solidityVersions
.map((v) => `\`${v}\``)
.join("<br/>")} | ${totals.totals.capabilities.experimental
.map((v) => `\`${v}\``)
.join("<br/>")} | ${
totals.totals.capabilities.canReceiveFunds ? "`yes`" : "****"
} | ${
totals.totals.capabilities.assembly
? `\`yes\` <br/>(${totals.totals.num.assemblyBlocks} asm blocks)`
: "****"
} | ${totals.totals.capabilities.destroyable ? "`yes`" : "****"} |
| ๐ค Transfers ETH | โก Low-Level Calls | ๐ฅ DelegateCall | ๐งฎ Uses Hash Functions | ๐ ECRecover | ๐ New/Create/Create2 |
| ---------------- | ----------------- | --------------- | ---------------------- | ------------ | --------------------- |
| ${totals.totals.capabilities.explicitValueTransfer ? "`yes`" : "****"} | ${
totals.totals.capabilities.lowLevelCall ? "`yes`" : "****"
} | ${totals.totals.capabilities.delegateCall ? "`yes`" : "****"} | ${
totals.totals.capabilities.hashFuncs ? "`yes`" : "****"
} | ${totals.totals.capabilities.ecrecover ? "`yes`" : "****"} | ${
totals.totals.capabilities.deploysContract ? "`yes`<br>" : "****"
}${Object.keys(totals.totals.ast)
.filter((k) =>
k.match(
/(NewContract:|AssemblyCall:Name:create|AssemblyCall:Name:create2)/g
)
)
.map((k) => `โ \`${k}\``)
.join("<br/>")} |
| โป๏ธ TryCatch | ฮฃ Unchecked |
| ---------- | ----------- |
| ${totals.totals.capabilities.tryCatchBlocks ? "`yes`" : "****"} | ${
totals.totals.capabilities.uncheckedBlocks ? "`yes`" : "****"
} |
#### <span id=t-package-imports>Dependencies / External Imports</span>
| Dependency / Import Path | Count |
| ------------------------ | ------ |
${Object.keys(totals.totals.ast)
.filter((k) => k.startsWith("ImportDirective:Path:"))
.sort()
.map(
(ki) =>
`| ${ki.replace("ImportDirective:Path:", "")} | ${
totals.totals.ast[ki]
} |`
)
.join("\n")}
#### <span id=t-totals>Totals</span>
##### Summary
<div class="wrapper" style="max-width: 90%; margin: auto">
<canvas id="chart-num-bar"></canvas>
</div>
##### AST Node Statistics
###### Function Calls
<div class="wrapper" style="max-width: 90%; margin: auto">
<canvas id="chart-num-bar-ast-funccalls"></canvas>
</div>
###### Assembly Calls
<div class="wrapper" style="max-width: 90%; margin: auto">
<canvas id="chart-num-bar-ast-asmcalls"></canvas>
</div>
###### AST Total
<div class="wrapper" style="max-width: 90%; margin: auto">
<canvas id="chart-num-bar-ast"></canvas>
</div>
##### Inheritance Graph
<a onclick="toggleVisibility('surya-inherit', this)">[โ]</a>
<div id="surya-inherit" style="display:none">
<div class="wrapper" style="max-width: 512px; margin: auto">
<div id="surya-inheritance" style="text-align: center;"></div>
</div>
</div>
##### CallGraph
<a onclick="toggleVisibility('surya-call', this)">[โ]</a>
<div id="surya-call" style="display:none">
<div class="wrapper" style="max-width: 512px; margin: auto">
<div id="surya-callgraph" style="text-align: center;"></div>
</div>
</div>
###### Contract Summary
<a onclick="toggleVisibility('surya-mdreport', this)">[โ]</a>
<div id="surya-mdreport" style="display:none">
${suryamdreport}
</div>
____
<sub>
Thinking about smart contract security? We can provide training, ongoing advice, and smart contract auditing. [Contact us](https://diligence.consensys.net/contact/).
</sub>
-->
</body>
</html>