Publish an audit

Once you're registered as an auditor on Trustblock, you will be able to publish your audits. Upon registration, you had to provide a wallet address, which lets you to sign in and submit your audits.

All the publishing costs you nothing since we use gasless transactions.

There are two methods to publish your audits:

Using our platform

Head to beta.trustblock.run to connect your wallet.

Click on the "Go to my profile" button.

At the bottom of your profile's page, you'll see a "Publish an audit" button redirecting you to the audit publication form once you click on it.

Complete the form, submit and you're all set!

Using our API

To publish an audit through our API, you must structure your data object in a specific way involving four parts: audit, issues, contracts, and project.

{
    ...auditObject, // Audit data is at the first level of the full data object.
    issues: issueObject[],
    contracts: contractObject[],
    project: projectObject
}

1. Audit data

The audit data is at the first level of the full data object. To obtain a valid reportFileCid, you will have to perform an upload on our IPFS provider, Pinata. In order to upload a file successfully, you will first have to fetch the necessary authorization to do so by calling our dedicated route.

Once you have retrieved your authorization response from the previous request, you must upload the file effectively. The code should look something like this:

const uploadAuthResponse = // Request to the above route

// Get the response's data from the authorization route
const uploadAuth = uploadAuthResponse.data;

// Create a form data to send the file over to Pinata
const formData = new FormData();
formData.append('file', file);
formData.append(
  'pinataMetadata',
  JSON.stringify({
    name: uploadAuth.fileName // Use the name sent by the authorization route
  })
);

const pinataOptions = JSON.stringify({
  cidVersion: 0
});
formData.append('pinataOptions', pinataOptions);

// Perform a POST request on the URL sent by the authorization route
const uploadResponse = await axios.post<{ IpfsHash: string }>(uploadAuth.url, formData, {
  maxBodyLength: Infinity,
  headers: {
    'Content-Type': `multipart/form-data;`,
    Authorization: `Bearer ${uploadAuth.apiKey}` // Pass the API key sent by the authorization request
  }
});

// Here you get the reportFileCid needed by the publish audit route.
const reportFileCid = uploadResponse.data.IpfsHash;
{
    name: string, // The name of the audit
    description: string, // The description of the audit
    reportFileCid: string // The cid of the IPFS hosted report file
}

The name and description expected here are not supposed to be the ones of the project audit. Still, the audit itself, e.g., If you audited the liquidity locker of a project named TokenA, the name of the audit would be Liquidity Locker.

2. Issues data

Two attributes classify every issue: its status (IssueStatus) and severity (IssueSeverity).

An issue status can either be fixed or not_fixed.

An issue severity can either be low, medium, high or critical.

We know all auditors have different values for these fields; our goal was to simplify so that everyone can adapt their own system to ours. The most important kind of issues are thenot_fixed critical ones. We are always welcoming suggestions, so don't hesitate to contact us!

{
    name: string, // The name of the issue
    description: string, // The description of the issue
    status: IssueStatus, // The status of the issue
    severity: IssueSeverity // The severity of the issue
}

All your issues must be stored inside a list passed to the main request body.

3. Contracts data

Every contract has a type (ContractType) field, which can either be: on_chain or off_chain.

Depending on the type, the contract must have different fields.

Contract on-chain

Additionally, to the type field, two other fields are required to submit an on-chain contract: evmAddress & chain.

chain can either one of the supported chains.

{
    type: 'on_chain', // The type of the contract
    chain: supported_chains, // The chain of the contract
    evmAddress: 'string' // The evmAddress of the contract
}

Contract off-chain

An off-chain contract requires three extra fields: repositoryUrl, repositoryCommitHash & repositoryFilePath.

{
    type: 'off_chain', // The type of the contract
    repositoryUrl: string, // The URL of the repository, e.g. https://github.com/Uniswap/v3-core
    repositoryCommitHash: string, // The commit hash of the repository, e.g. 4024732be626f4b4299a4314150d5c5471d59ed9
    repositoryFilePath: string, // The path to the audited contract, e.g. contracts/NoDelegateCall.sol
}

For now, we only support Github public repositories.

All your issues must be stored inside a list passed to the main request body.

4. Project data

Our system will automatically check if the audit's project already exists in our database by relying on links.website.

{
    name: string, // The name of the project
    description: string, // The description of the project
    links: {
        website: string, // The website URL of the project
        twitter: string, // The twitter URL of the project (optional)
        discord: string, // The discord URL of the project (optional)
        telegram: string, // The telegram URL of the project (optional)
        github: string, // The discord URL of the project (optional)
        youtube: string, // The telegram URL of the project (optional)
        linkedIn: string, // The discord URL of the project (optional)
    },
    tags: ['analytics', 'collectibles', 'finance', 'gaming', 'security', 'social', 'wallet', 'other'], // Pass as many values as relevant
}

Best practice for an automated setup

To make sure your request never fails, pass all the data needed to create a project, including links, name, description and tags.

5. Final data object

{
    name: string, // The name of the audit
    description: string, // The description of the audit
    issues: [
        {
            name: string, // The name of the issue
            description: string, // The description of the issue
            status: IssueStatus, // The status of the issue
            severity: IssueSeverity // The severity of the issue
        }, ...
    ],
    contracts: [
        {
            type: 'off_chain', // The type of the contract
            repositoryUrl: string, // The URL of the repository, e.g. https://github.com/Uniswap/v3-core
            repositoryCommitHash: string, // The commit hash of the repository, e.g. 4024732be626f4b4299a4314150d5c5471d59ed9
            repositoryFilePath: string, // The path to the audited contract, e.g. contracts/NoDelegateCall.sol
        }
    ],
    project: {
        slug: string, // The slug of the project
        domain: string // The domain of the project
        //Only one of the above fields is required.
    } | {
        name: string, // The name of the project
        description: string, // The description of the project
        links: {
            website: string, // The website URL of the project
            twitter: string, // The twitter URL of the project (optional)
            discord: string, // The discord URL of the project (optional)
            telegram: string, // The telegram URL of the project (optional)
            github: string, // The discord URL of the project (optional)
            youtube: string, // The telegram URL of the project (optional)
            linkedIn: string, // The discord URL of the project (optional)
        },
        tags: ['analytics', 'collectibles', 'finance', 'gaming', 'security', 'social', 'wallet', 'other'], // Pass as many values as relevant
    }
}

6. Sending the request

Once your data is ready, you'll have to set up the request. The publish audit route only accepts formdata. The formdata should have two fields: the report file stored under the pdf key and the data (passed as a JSON string) stored under the data key.


And then, what?

That's it! Your audit is published and publicly accessible through our platform.

We refresh metrics on Trustblock every day at a fixed time, and as such, your profile should be updated pretty soon after publishing your audits with the newest metrics.

The audit you publish will now be available from labels and API. Check the links below for more information.

Last updated