Skip to content

Stylus add security contract field #564

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

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
27ebf04
Before running with prettier
CoveMB Feb 21, 2025
7c7828e
After running with prettier
CoveMB Feb 21, 2025
ce5fcd3
Add consistent-type-imports rule
CoveMB Feb 21, 2025
3cd0b59
Add lint step in ci action
CoveMB Feb 21, 2025
31f0c78
resolve prettier conflict
CoveMB Feb 21, 2025
365421b
After running with prettier
CoveMB Feb 21, 2025
cedaeaa
resolve prettier conflict
CoveMB Feb 21, 2025
98bd8af
Add lint step in ci action
CoveMB Feb 21, 2025
a9098d0
resolve prettier conflict
CoveMB Feb 21, 2025
6e9df26
resolve prettier conflict
CoveMB Feb 21, 2025
574a739
Remove .vscode directory from Git tracking
CoveMB Feb 21, 2025
c0e9002
move linter action in it's own job
CoveMB Feb 21, 2025
86c65dc
add lint note in readme
CoveMB Feb 21, 2025
a1111d3
Update .github/workflows/test.yml
CoveMB Feb 21, 2025
abbd5a4
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 21, 2025
beffa34
Merge branch 'master' into master
ericglau Feb 21, 2025
d6bec2a
lint script files
CoveMB Feb 21, 2025
315b775
Merge branch 'master' of github.com:CoveMB/contracts-wizard
CoveMB Feb 21, 2025
6ed6e4f
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 24, 2025
ea90cd1
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 28, 2025
abf687a
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 4, 2025
426b62d
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 20, 2025
ea25cc1
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 20, 2025
0911f87
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 25, 2025
4914083
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 27, 2025
5ce527f
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 4, 2025
03a32fc
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 7, 2025
b3c0347
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 12, 2025
0a52a65
Merge remote-tracking branch 'upstream/master'
CoveMB May 13, 2025
9e74342
Merge remote-tracking branch 'upstream/master'
CoveMB May 19, 2025
d727f51
Merge remote-tracking branch 'upstream/master'
CoveMB May 21, 2025
60fb18f
Merge remote-tracking branch 'upstream/master'
CoveMB May 26, 2025
cbb7631
Merge remote-tracking branch 'upstream/master'
CoveMB May 27, 2025
0f1267f
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 5, 2025
e5ba7c6
Add securityContact to contract model, print function, ai agent and ui
CoveMB Jun 6, 2025
524cb62
Add changeset
CoveMB Jun 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fair-plums-throw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@openzeppelin/wizard-stylus': patch
---

Add security contact in contract info
7 changes: 7 additions & 0 deletions packages/core/stylus/src/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import test from 'ava';
import type { BaseFunction, BaseImplementedTrait } from './contract';
import { ContractBuilder } from './contract';
import { printContract } from './print';
import { TAG_SECURITY_CONTACT } from './set-info';

test('contract basics', t => {
const Foo = new ContractBuilder('Foo');
Expand Down Expand Up @@ -77,3 +78,9 @@ test('contract with sorted traits', t => {
);
t.snapshot(printContract(Foo));
});

test('contract with info', t => {
const Foo = new ContractBuilder('Foo');
Foo.addDocumentationTag(TAG_SECURITY_CONTACT, '[email protected]');
t.snapshot(printContract(Foo));
});
23 changes: 23 additions & 0 deletions packages/core/stylus/src/contract.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,26 @@ Generated by [AVA](https://avajs.dev).
fn funcSpecial() {}␊
}␊
`

## contract with info

> Snapshot 1

`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0-alpha.4␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
use stylus_sdk::prelude::*;␊
/// @custom:security-contact [email protected]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0xNeshi @bidzyyys Would this be the appropriate placement for the security contact comment (and possibly other contract level comments)?

#[entrypoint]␊
#[storage]␊
struct Foo {}␊
#[public]␊
#[inherit]␊
impl Foo {}␊
`
Binary file modified packages/core/stylus/src/contract.test.ts.snap
Binary file not shown.
14 changes: 14 additions & 0 deletions packages/core/stylus/src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type Name = {
export interface Contract {
license: string;
name: Name;
documentationTags: DocumentationTag[];
useClauses: UseClause[];
implementedTraits: ImplementedTrait[];
constants: Variable[];
Expand Down Expand Up @@ -70,10 +71,17 @@ export interface Argument {
type?: string;
}

export interface DocumentationTag {
key: string;
value: string;
}

export class ContractBuilder implements Contract {
readonly name: Name;
license = 'MIT';

readonly documentationTags: DocumentationTag[] = [];

private implementedTraitsMap: Map<string, ImplementedTrait> = new Map();
private useClausesMap: Map<string, UseClause> = new Map();
private errorsMap: Map<string, Error> = new Map();
Expand Down Expand Up @@ -199,4 +207,10 @@ export class ContractBuilder implements Contract {
const existingFn = this.addFunction(baseTrait, fn);
existingFn.attribute = attribute;
}

addDocumentationTag(key: string, value: string) {
// eslint-disable-next-line no-useless-escape
if (!/^(@custom:)?[a-z][a-z\-]*$/.exec(key)) throw new Error(`Invalid documentation key: ${key}`);
this.documentationTags.push({ key, value });
}
}
7 changes: 6 additions & 1 deletion packages/core/stylus/src/print.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Contract, Argument, ContractFunction, ImplementedTrait, UseClause } from './contract';
import type { Contract, Argument, ContractFunction, ImplementedTrait, UseClause, DocumentationTag } from './contract';

import type { Lines } from './utils/format-lines';
import { formatLines, spaceBetween } from './utils/format-lines';
Expand All @@ -20,6 +20,7 @@ export function printContract(contract: Contract): string {
[`#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]`, `extern crate alloc;`],
spaceBetween(
printUseClauses(contract),
printDocumentationTags(contract.documentationTags),
printConstants(contract),
printStorage(contract.name.identifier, sortedGroups),
contract.eip712Needed ? printEip712(contract.name.stringLiteral) : [],
Expand Down Expand Up @@ -284,3 +285,7 @@ function printArgument(arg: Argument): string {
return `${arg.name}`;
}
}

function printDocumentationTags(tags: DocumentationTag[]): string[] {
return tags.map(({ key, value }) => `/// ${key} ${value}`);
}
9 changes: 8 additions & 1 deletion packages/core/stylus/src/set-info.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import type { ContractBuilder } from './contract';

export const TAG_SECURITY_CONTACT = `@custom:security-contact`;

export const infoOptions = [{}, { license: 'WTFPL' }] as const;

export const defaults: Info = { license: 'MIT' };

export type Info = {
license?: string;
securityContact?: string;
};

export function setInfo(c: ContractBuilder, info: Info): void {
const { license } = info;
const { securityContact, license } = info;

if (securityContact) {
c.addDocumentationTag(TAG_SECURITY_CONTACT, securityContact);
}

if (license) {
c.license = license;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ export const stylusCommonFunctionDescription = {
type: 'object',
description: 'Metadata about the contract and author',
properties: {
securityContact: {
type: 'string',
description:
'Email where people can contact you to report security issues. Will only be visible if contract metadata is verified.',
},

license: {
type: 'string',
description: 'The license used by the contract, default is "MIT"',
Expand Down
11 changes: 11 additions & 0 deletions packages/ui/src/stylus/InfoSection.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import type { Info } from '@openzeppelin/wizard-stylus';
import { infoDefaults } from '@openzeppelin/wizard-stylus';
import HelpTooltip from '../common/HelpTooltip.svelte';

export let info: Info;
</script>
Expand All @@ -13,6 +14,16 @@
</label>
</h1>

<label class="labeled-input">
<span class="flex justify-between pr-2">
Security Contact
<HelpTooltip>
Where people can contact you to report security issues. Will only be visible if contract metadata is verified.
</HelpTooltip>
</span>
<input bind:value={info.securityContact} placeholder="[email protected]" />
</label>

<label class="labeled-input">
<span>License</span>
<input bind:value={info.license} placeholder={infoDefaults.license} />
Expand Down