Kleros
Kleros.ioGithub
  • Introduction to Kleros
  • Kleros FAQ
  • Governance
  • PNK Token
  • They talk about Kleros
  • Products
    • Court
      • Kleros Juror Tutorial
      • Famous Kleros Cases
      • What happens during a dispute?
      • Kleros & Credible Neutrality
    • Court V2
    • Proof of Humanity
      • Proof of Humanity 2.0 Tutorial: (Register & Vouch)
      • Proof of Humanity 2.0 Tutorial (Remove & Challenge)
      • Proof of Humanity 2.0 Tutorial (Transferring a Profile)
      • Proof of Humanity 2.0 Integration Guide
      • Proof of Humanity FAQ
        • Proof of Humanity 2.0 launch FAQ
    • Curate
      • Kleros Curate Tutorial
      • Kleros Scout
        • Tutorial
        • Earn With Kleros Scout
        • Partnerships
        • Kleros Scout - Metamask Snaps
          • Knowledge Base
        • FAQs
    • Oracle
    • Governor
    • Escrow
      • Kleros Escrow Tutorial
      • Kleros Escrow Specifications
    • Linguo
      • Kleros Linguo Tutorial
      • Step-by-step Tutorial
        • Requesting translations
        • Working as a translator
        • Reviewing translations
      • F.A.Q
      • High-level Overview
    • Moderate
      • Susie
        • Getting Started
          • Add Susie
          • Start Susie
        • Basics
          • Welcome
          • Language
          • Notifications
        • Rules
        • Reports
        • Evidence
        • Federations
  • INTEGRATIONS
    • Overview
    • Industry use cases
    • Types of Integrations
      • 1. Dispute resolution integration plan
        • Smart contract integration with Kleros Court (Arbitrator)
        • Use Cases
          • DeFi Insurance
          • Gaming
          • Recognition of Jurisdiction Integration
            • Integración por Reconocimiento de Jurisdicción
        • Channel partners
          • How to use Reality.eth + Kleros as an oracle
          • Safe Zodiac integration
          • Kleros Reality Module
        • Integration Tools
          • Centralized Arbitrator
          • Dispute Resolver
      • 2. Curated-data integration plan
        • Retrieving information from Kleros Dapps
    • Policy writing guide
    • Live & Upcoming Integrations
    • Kleros Analytics
    • Scalability & Cross-chain
      • Using Kleros arbitration for Dapps on xDai/Gnosis
    • Integrations FAQ
  • Developers
    • Arbitration Development
      • ERC-792: Arbitration Standard
      • ERC 1497: Evidence Standard
      • Arbitrable Proxy
    • Arbitration by Example
      • ArbitrableDeposit.sol
      • TwoPartyArbitrable.sol
      • Rental.sol
      • ArbitrableTransaction.sol
      • MultipleArbitrableTransaction.sol
      • MultipleArbitrableTokenTransaction.sol
    • Deployment Addresses
    • Curate Classic: Integration for Devs
    • Light Curate: Integration for Devs
    • Guide for Preparing Transactions
  • Contribution Guidelines
    • Overview
    • General Dev. Workflow
      • Task Tracking & Lifecycle
      • Releases
    • Smart Contract Workflow
      • Task Tracking & Lifecycle
      • RAB - Review, Audit, Bounty
      • RABd (+ Deploy)
      • Reporting Vulnerabilities
    • Code Style and Guidelines
      • Git
      • Solidity
      • Web Languages
    • License & Code of Conduct
      • License
      • Code of Conduct
  • Additional Resources
    • Discord
    • Telegram
    • Governance Forum
    • Twitter
    • Blog
    • Reddit
    • Github
    • Slack
Powered by GitBook
On this page
  • Style
  • Comments & Documentation
  • When to Comment
  • Good Practices
  • Code
  • Mindset

Was this helpful?

Edit on GitHub
  1. Contribution Guidelines
  2. Code Style and Guidelines

Solidity

Our standards for smart contract code.

PreviousGitNextWeb Languages

Last updated 2 years ago

Was this helpful?

Style

We follow the and use for linting.

Comments & Documentation

When to Comment

Comments should be used for:

  • Documenting all functions using the (ENSF).

  • Explaining all non-obvious parts of code. A smart contract must work, but must also convince external reviewers that it works.

  • Explaining security choices.

Computational Complexity

If a function is not O(1) , the first line of the @dev part of the ENSF comment should be followed by what the big O complexity is and a brief explanation. This is so that callers know what they are getting into in terms of gas consumption. It is common for some gas intensive functions to only be called from clients and not from other contracts.

External Trust

For functions that make an external call with enough gas for re-entry, not send or transfer, specify "UN/TRUSTED." at the end of the @dev part of the ENSF comment. This tells readers whether the external call receiver is trusted or not, i.e. the code it executes is controlled.

Note that specifying a contract type for a variable does not guarantee that it will reference a contract of that type as any address can be coerced into any contract, and vice-versa.

Work in Progress

Mark unsecured functions or functions that are not finished yet with "TODO." at the end of the @dev part of the ENSF comment.

Good Practices

Code

A lot of these apply to software in general.

  • Do not use magic numbers or values, define a constant or enum.

  • If you need special testing functions that expose functionality not intended for production, make a test contract inheriting from the original one, rather than adding the testing functions to the original contract.

Mindset

Traditional back ends do most of the heavy lifting for the front end, because computation is cheap and faster than on the client. But, smart contract backends, leave most of the heavy lifting for the front end, because computation is expensive and slower than on the client. This is an inherent property of consensus based systems that involve lots of parties. Improvements will always be made, but it will also always be cheaper to execute code on the front end.

This and the security risks of smart contracts that interact with other smart contracts with complex and stateful interdependencies require that we take a unique approach and mindset when developing smart contracts. Here are some general guidelines:

  • If possible, i.e. does not lead to a significant increase in computation, externally called functions should follow this 3-step pattern:

    • Verify that the call is authorized. Modifiers can be used for this.

    • Execute state changes.

    • Interact with other accounts by making external calls other than send and transfer.

    This protects the function from being re-entered through the external calls and having some effect running more times than was intended. Note that despite what the official documentation indicates, send and transfer are not to be counted as interactions as they do not give enough gas to make a callback or change contract state.

  • Be aware of gas consumption. Smart contracts differ to traditional software where you can "Get it correct the first time, fast the second.", being slow in a smart contract is being incorrect. Out of gas transactions fail and high TX fees can place a huge burden on users.

  • Be OK with "doing 0". A function that sends 0 tokens, gives a penalty of 0%, and/or can't be called again unless 0 seconds pass is fine. Smart contracts should have the minimum amount of code possible and this ties into the next point.

  • Don't protect the user from himself. Client execution is almost free, but smart contract execution isn't, so limit smart contracts to blocking malicious behavior and let clients prevent the stupid ones.

  • As a general rule, your priorities should be in this order:

    • Security: Prevent vulnerabilities, unexpected behaviour, and reduce the impact of those which could arise.

    • Gas: Lower the gas usage to save on TX fees.

    • Convincibility: Write code that allows other parties to be easily convinced that it works. Remember that more time is spent in reviews/audits/bug bounties than in actually writing the code.

    • Reusability: Write code that is generic enough to avoid starting from scratch every time. This should not hinder the 3 previous priorities.

  • Smart contracts should only do what is required, no more, no less. Do not abstract contracts into more generic contracts if the deployed version will only use a subset of the functionality. E.g. if you can only have 2 parties in your contract, only write code for 2 parties. Do not write code supporting an arbitrary number of parties and then set it to 2 at deployment. This is a stark contrast to traditional software where generic abstractions can save time in the long run. In smart contract development, there is no continuous deployments and the additional time spent in security practices that a generic contract requires far outweighs the potential benefit of its reusability.

  • Contrary to what the compiler warnings may tell you, send is generally more secure than transfer as transfer allows the recipient to block the call. Don't use transfer unless there is a good reason to.

Abstractions can be made to make front end developers' lives easier. Our does just that for ERC 792 contracts.

Do not over-engineer. Over-engineering lowers security, increases gas costs, and decreases convincibility. ♥.

However, abstraction can be useful when contracts need to interact with contracts which are not known in advance, either because they won't be finished by the time of deployment or because they will be developed by other projects you don't have control over. and are good examples of this.

Official Solidity Style Guide
Kathari
Ethereum Natural Specification Format
archon
Kiss
ERC20
ERC792