Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
7017a693
Commit
7017a693
authored
Dec 19, 2021
by
Indeavr
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: moved code to a separate npm package
parent
609926f2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
3 additions
and
461 deletions
+3
-461
hardhat.config.ts
packages/contracts/hardhat.config.ts
+2
-33
package.json
packages/contracts/package.json
+1
-1
validate-output.ts
packages/contracts/tasks/validate-output.ts
+0
-427
No files found.
packages/contracts/hardhat.config.ts
View file @
7017a693
...
@@ -22,7 +22,7 @@ import './tasks/whitelist'
...
@@ -22,7 +22,7 @@ import './tasks/whitelist'
import
'
./tasks/withdraw-fees
'
import
'
./tasks/withdraw-fees
'
import
'
hardhat-gas-reporter
'
import
'
hardhat-gas-reporter
'
import
'
@primitivefi/hardhat-dodoc
'
import
'
@primitivefi/hardhat-dodoc
'
import
'
./tasks/validate-output
'
import
'
hardhat-output-validator
'
// Load environment variables from .env
// Load environment variables from .env
dotenv
.
config
()
dotenv
.
config
()
...
@@ -30,37 +30,6 @@ dotenv.config()
...
@@ -30,37 +30,6 @@ dotenv.config()
const
enableGasReport
=
!!
process
.
env
.
ENABLE_GAS_REPORT
const
enableGasReport
=
!!
process
.
env
.
ENABLE_GAS_REPORT
const
privateKey
=
process
.
env
.
PRIVATE_KEY
||
'
0x
'
+
'
11
'
.
repeat
(
32
)
// this is to avoid hardhat error
const
privateKey
=
process
.
env
.
PRIVATE_KEY
||
'
0x
'
+
'
11
'
.
repeat
(
32
)
// this is to avoid hardhat error
// Will be moved to a separate package
export
interface
Checks
{
title
?:
boolean
// default: true,
details
?:
boolean
// default: true,
compilationWarnings
?:
boolean
// default: true,
missingUserDoc
?:
boolean
// default: true,
missingDevDoc
?:
boolean
// default: true,
}
declare
module
'
hardhat/types/config
'
{
export
interface
HardhatUserConfig
{
outputChecks
?:
{
include
?:
string
[]
exclude
?:
string
[]
runOnCompile
?:
boolean
errorMode
?:
boolean
checks
?:
Checks
}
}
export
interface
HardhatConfig
{
outputChecks
:
{
include
:
string
[]
exclude
:
string
[]
runOnCompile
:
boolean
errorMode
:
boolean
checks
:
Checks
}
}
}
const
config
:
HardhatUserConfig
=
{
const
config
:
HardhatUserConfig
=
{
networks
:
{
networks
:
{
hardhat
:
{
hardhat
:
{
...
@@ -160,7 +129,7 @@ const config: HardhatUserConfig = {
...
@@ -160,7 +129,7 @@ const config: HardhatUserConfig = {
'
TestLib_MerkleTree
'
,
'
TestLib_MerkleTree
'
,
],
],
},
},
output
Checks
:
{
output
Validator
:
{
runOnCompile
:
true
,
runOnCompile
:
true
,
errorMode
:
true
,
errorMode
:
true
,
exclude
:
[
'
contracts/test-helpers
'
,
'
contracts/test-libraries
'
],
exclude
:
[
'
contracts/test-helpers
'
,
'
contracts/test-libraries
'
],
...
...
packages/contracts/package.json
View file @
7017a693
...
@@ -64,7 +64,7 @@
...
@@ -64,7 +64,7 @@
"@ethersproject/abstract-signer"
:
"^5.4.1"
,
"@ethersproject/abstract-signer"
:
"^5.4.1"
,
"@ethersproject/hardware-wallets"
:
"^5.4.0"
,
"@ethersproject/hardware-wallets"
:
"^5.4.0"
,
"@primitivefi/hardhat-dodoc"
:
"^0.1.3"
,
"@primitivefi/hardhat-dodoc"
:
"^0.1.3"
,
"
chalk"
:
"^4.1.2
"
"
hardhat-output-validator"
:
"^0.1.0
"
},
},
"devDependencies"
:
{
"devDependencies"
:
{
"@codechecks/client"
:
"^0.1.11"
,
"@codechecks/client"
:
"^0.1.11"
,
...
...
packages/contracts/tasks/validate-output.ts
deleted
100644 → 0
View file @
609926f2
'
use strict
'
import
{
task
,
extendConfig
}
from
'
hardhat/config
'
import
{
TASK_COMPILE
}
from
'
hardhat/builtin-tasks/task-names
'
import
chalk
from
'
chalk
'
import
'
hardhat/types/config
'
import
{
HardhatConfig
,
HardhatUserConfig
,
CompilerOutputContract
,
}
from
'
hardhat/types
'
import
{
BuildInfo
}
from
'
hardhat/src/types/artifacts
'
export
interface
Checks
{
title
?:
boolean
// default: true,
details
?:
boolean
// default: true,
compilationWarnings
?:
boolean
// default: true,
missingUserDoc
?:
boolean
// default: true,
missingDevDoc
?:
boolean
// default: true,
}
declare
module
'
hardhat/types/config
'
{
export
interface
HardhatUserConfig
{
outputChecks
?:
{
include
?:
string
[]
exclude
?:
string
[]
runOnCompile
?:
boolean
errorMode
?:
boolean
checks
?:
Checks
}
}
export
interface
HardhatConfig
{
outputChecks
:
{
include
:
string
[]
exclude
:
string
[]
runOnCompile
:
boolean
errorMode
:
boolean
checks
:
Checks
}
}
}
extendConfig
(
(
config
:
HardhatConfig
,
userConfig
:
Readonly
<
HardhatUserConfig
>
)
=>
{
config
.
outputChecks
=
{
errorMode
:
userConfig
.
outputChecks
?.
errorMode
||
false
,
checks
:
{
title
:
true
,
details
:
true
,
compilationWarnings
:
true
,
missingUserDoc
:
true
,
missingDevDoc
:
true
,
...(
userConfig
.
outputChecks
?.
checks
||
{}),
},
include
:
userConfig
.
outputChecks
?.
include
||
[],
exclude
:
userConfig
.
outputChecks
?.
exclude
||
[],
runOnCompile
:
userConfig
.
outputChecks
?.
runOnCompile
||
false
,
}
}
)
interface
ErrorInfo
{
type
:
ErrorType
text
:
string
at
:
string
filePath
:
string
fileName
:
string
}
enum
ErrorType
{
MissingTitle
,
MissingDetails
,
CompilationWarning
,
// User Docs
MissingUserDoc
,
// Dev Docs
MissingDevDoc
,
}
declare
interface
ErrorUserdocArrayItem
{
notice
?:
string
}
export
interface
ErrorDevdocArrayItem
{
details
?:
string
params
?:
{
[
key
:
string
]:
string
}
}
export
interface
CompilerOutputContractWithDocumentation
extends
CompilerOutputContract
{
devdoc
?:
{
author
?:
string
details
?:
string
title
?:
string
errors
?:
{
[
key
:
string
]:
ErrorDevdocArrayItem
[]
}
events
?:
{
[
key
:
string
]:
{
details
:
string
params
:
{
[
key
:
string
]:
string
}
}
}
methods
?:
{
[
key
:
string
]:
{
details
?:
string
params
:
{
[
key
:
string
]:
string
}
returns
:
{
[
key
:
string
]:
string
}
}
}
returns
?:
{
[
key
:
string
]:
{
details
?:
string
params
:
{
[
key
:
string
]:
string
}
}
}
stateVariables
?:
{
[
key
:
string
]:
{
details
?:
string
params
:
{
[
key
:
string
]:
string
}
returns
:
{
[
key
:
string
]:
string
}
}
}
}
userdoc
?:
{
errors
?:
{
[
key
:
string
]:
ErrorUserdocArrayItem
[]
}
events
?:
{
[
key
:
string
]:
{
notice
:
string
}
}
methods
?:
{
[
key
:
string
]:
{
notice
:
string
}
}
notice
?:
string
}
}
export
interface
CompilerOutputWithDocsAndPath
extends
CompilerOutputContractWithDocumentation
{
filePath
:
string
fileName
:
string
}
const
setupErrors
=
(
fileSource
:
string
,
fileName
:
string
)
=>
(
errorType
:
ErrorType
,
extraData
?:
any
)
=>
{
const
typeToMessage
=
()
=>
{
switch
(
errorType
)
{
case
ErrorType
.
MissingTitle
:
return
'
Contract is missing title
'
case
ErrorType
.
MissingDetails
:
return
'
Contract is missing details
'
case
ErrorType
.
CompilationWarning
:
return
`Compilation warnings: \n
${
extraData
}
`
// User DOCS
case
ErrorType
.
MissingUserDoc
:
return
`
${
extraData
}
is missing @notice`
// DEV DOCS
case
ErrorType
.
MissingDevDoc
:
return
`
${
extraData
}
is missing @notice`
default
:
return
undefined
}
}
return
`
${
errorType
!==
ErrorType
.
CompilationWarning
?
'
Comments Error
'
:
''
}
:
${
typeToMessage
()}
\n @
${
fileName
}
\n -->
${
fileSource
}
\n`
}
task
(
TASK_COMPILE
,
async
(
args
,
hre
,
runSuper
)
=>
{
const
config
=
hre
.
config
.
outputChecks
// Updates the compiler settings
for
(
const
compiler
of
hre
.
config
.
solidity
.
compilers
)
{
compiler
.
settings
.
outputSelection
[
'
*
'
][
'
*
'
].
push
(
'
devdoc
'
)
compiler
.
settings
.
outputSelection
[
'
*
'
][
'
*
'
].
push
(
'
userdoc
'
)
}
// Calls the actual COMPILE task
await
runSuper
()
if
(
!
config
.
runOnCompile
)
{
return
}
const
getBuildInfo
=
async
(
qualifiedName
:
string
):
Promise
<
BuildInfo
|
undefined
>
=>
{
return
hre
.
artifacts
.
getBuildInfo
(
qualifiedName
)
}
// Loops through all the qualified names to get all the compiled contracts
const
getContractBuildInfo
=
async
(
qualifiedName
:
string
):
Promise
<
CompilerOutputWithDocsAndPath
|
undefined
>
=>
{
const
[
source
,
name
]
=
qualifiedName
.
split
(
'
:
'
)
const
build
=
await
getBuildInfo
(
qualifiedName
)
const
info
:
CompilerOutputContractWithDocumentation
=
build
?.
output
.
contracts
[
source
][
name
]
return
{
...
info
,
filePath
:
source
,
fileName
:
name
,
}
as
CompilerOutputWithDocsAndPath
return
undefined
}
const
checkForErrors
=
(
info
:
CompilerOutputWithDocsAndPath
):
ErrorInfo
[]
=>
{
const
foundErrors
=
[]
const
getErrorText
=
setupErrors
(
info
.
filePath
,
info
.
fileName
)
const
addError
=
(
errorType
:
ErrorType
,
extraData
?:
any
)
=>
{
const
text
=
getErrorText
(
errorType
,
extraData
)
foundErrors
.
push
({
text
,
type
:
errorType
,
at
:
''
,
filePath
:
info
.
filePath
,
fileName
:
info
.
fileName
,
})
}
const
findByName
=
(
searchInObj
:
object
,
entityName
:
string
)
=>
{
if
(
!
searchInObj
||
!
entityName
)
{
return
}
const
key
=
Object
.
keys
(
searchInObj
).
find
((
methodSigniture
)
=>
{
const
name
=
methodSigniture
.
split
(
'
(
'
)[
0
]
return
name
===
entityName
})
if
(
!
key
)
{
return
}
return
searchInObj
[
key
]
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const
checkConstructor
=
(
entity
)
=>
{
// TODO:
return
}
const
checkEvent
=
(
entity
)
=>
{
if
(
config
.
checks
.
missingUserDoc
&&
info
.
userdoc
)
{
const
userDocEntry
=
findByName
(
info
.
userdoc
.
events
,
entity
.
name
)
if
(
!
userDocEntry
||
!
userDocEntry
.
notice
)
{
addError
(
ErrorType
.
MissingUserDoc
,
`Event: (
${
entity
.
name
}
)`
)
}
}
if
(
config
.
checks
.
missingDevDoc
&&
info
.
devdoc
)
{
const
devDocEntry
=
findByName
(
info
.
devdoc
.
events
,
entity
.
name
)
// TODO: Extend with checks for params, returns
if
(
!
devDocEntry
)
{
addError
(
ErrorType
.
MissingUserDoc
,
`Event: (
${
entity
.
name
}
)`
)
}
}
}
const
checkFunction
=
(
entity
)
=>
{
if
(
config
.
checks
.
missingUserDoc
&&
info
.
userdoc
)
{
const
userDocEntry
=
findByName
(
info
.
userdoc
.
methods
,
entity
.
name
)
if
(
!
userDocEntry
||
!
userDocEntry
.
notice
)
{
addError
(
ErrorType
.
MissingUserDoc
,
`Function: (
${
entity
.
name
}
)`
)
}
}
if
(
config
.
checks
.
missingDevDoc
&&
info
.
devdoc
)
{
const
devDocEntryFunc
=
findByName
(
info
.
devdoc
.
methods
,
entity
.
name
)
const
devDocEntryVar
=
findByName
(
info
.
devdoc
.
stateVariables
,
entity
.
name
)
// TODO: Extend with checks for params, returns
if
(
!
devDocEntryFunc
&&
!
devDocEntryVar
)
{
addError
(
ErrorType
.
MissingUserDoc
,
`Function: (
${
entity
.
name
}
)`
)
}
}
}
if
(
config
.
checks
.
title
&&
!
info
.
devdoc
?.
title
)
{
addError
(
ErrorType
.
MissingTitle
)
}
if
(
config
.
checks
.
details
&&
!
info
.
devdoc
?.
details
)
{
addError
(
ErrorType
.
MissingDetails
)
}
if
(
Array
.
isArray
(
info
.
abi
))
{
// Loops through the abi and for each function/event/var check in the user/dev doc.
info
.
abi
.
forEach
((
entity
)
=>
{
if
(
entity
.
type
===
'
constructor
'
)
{
checkConstructor
(
entity
)
}
else
if
(
entity
.
type
===
'
event
'
)
{
checkEvent
(
entity
)
}
else
if
(
entity
.
type
===
'
function
'
)
{
checkFunction
(
entity
)
}
})
}
// TODO: check for userDoc.errors
return
foundErrors
}
console
.
log
(
'
<<< Starting Output Checks >>>
'
)
const
allContracts
=
await
hre
.
artifacts
.
getAllFullyQualifiedNames
()
// console.log("allContracts", allContracts);
const
qualifiedNames
=
allContracts
.
filter
((
str
)
=>
str
.
startsWith
(
'
contracts
'
))
.
filter
((
path
)
=>
{
// Checks if this contact is included
const
includesPath
=
config
.
include
.
some
((
str
)
=>
path
.
includes
(
str
))
const
excludesPath
=
config
.
exclude
.
some
((
str
)
=>
path
.
includes
(
str
))
return
(
config
.
include
.
length
===
0
||
includesPath
)
&&
!
excludesPath
})
console
.
log
(
'
qualifiedNames
'
,
qualifiedNames
)
// 1. Setup
const
buildInfo
:
BuildInfo
[]
=
(
await
Promise
.
all
(
qualifiedNames
.
map
(
getBuildInfo
))
).
filter
((
inf
)
=>
inf
!==
undefined
)
const
contractBuildInfo
:
CompilerOutputWithDocsAndPath
[]
=
(
await
Promise
.
all
(
qualifiedNames
.
map
(
getContractBuildInfo
))
).
filter
((
inf
)
=>
inf
!==
undefined
)
// 2. Check
const
errors
=
contractBuildInfo
.
reduce
((
foundErrors
,
info
)
=>
{
const
docErrors
=
checkForErrors
(
info
)
if
(
docErrors
&&
docErrors
.
length
>
0
)
{
foundErrors
[
info
.
filePath
]
=
docErrors
}
return
foundErrors
},
{}
as
{
[
file
:
string
]:
ErrorInfo
[]
})
// Check for CompilationWarning
if
(
config
.
checks
.
compilationWarnings
)
{
for
(
const
bi
of
buildInfo
)
{
const
outputErrors
=
(
bi
.
output
as
any
).
errors
if
(
outputErrors
&&
outputErrors
.
length
>
0
)
{
outputErrors
.
forEach
((
err
)
=>
{
if
(
!
errors
[
err
.
sourceLocation
.
file
])
{
errors
[
err
.
sourceLocation
.
file
]
=
[]
}
const
filePath
=
err
.
sourceLocation
.
file
const
fileComponents
=
filePath
.
split
(
'
/
'
)
const
fileName
=
fileComponents
[
fileComponents
.
length
-
1
]
errors
[
err
.
sourceLocation
.
file
].
push
({
text
:
setupErrors
(
filePath
,
fileName
)(
ErrorType
.
CompilationWarning
,
err
.
formattedMessage
),
type
:
ErrorType
.
CompilationWarning
,
at
:
''
,
filePath
,
fileName
,
})
})
break
}
}
}
// 3. Act
const
printErrors
=
(
level
:
'
error
'
|
'
warn
'
=
'
warn
'
)
=>
{
Object
.
keys
(
errors
).
forEach
((
file
)
=>
{
const
errorsInfo
=
errors
[
file
]
if
(
errorsInfo
&&
errorsInfo
.
length
>
0
)
{
errorsInfo
.
forEach
((
erIn
)
=>
{
if
(
level
===
'
error
'
)
{
console
.
error
(
chalk
.
red
(
erIn
.
text
))
}
else
{
console
.
warn
(
chalk
.
yellow
(
erIn
.
text
))
}
})
}
})
}
if
(
config
.
errorMode
&&
Object
.
keys
(
errors
).
length
>
0
)
{
printErrors
(
'
error
'
)
throw
new
Error
(
'
Missing Natspec Comments
'
)
}
printErrors
()
console
.
log
(
'
✅ All Contracts have been checked for missing Natspec comments
'
)
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment