# CompetentIT Solidity Coding Standard Last update: 2021-11-09 ## ***Introduction*** Blockchain SoftWare CompetentIT is written in Solidity, a object-oriented programming language for writing smart contracts. In this document we outline the coding standard that CompetentIT is using for editing Solidity files. :::info :bulb: **Bear in mind**: A coding standard is about consistency. Consistency with this coding standard is important. Consistency within a project is more important. Consistency within one module or function is most important. But most importantly: know when to be inconsistent – sometimes the coding standard just doesn’t apply. When in doubt, use your best judgement. Look at other examples and decide what looks best. And don’t hesitate to ask! ::: ## <i class="fa fa-shield" color = red></i> ***Security Rules*** #### <i class="fa fa-shield" ></i> **Avoid to use `.call.value()()`.** #### <i class="fa fa-shield"></i> **Use `keccak256()` instead of deprecated `sha3()`.** #### <i class="fa fa-shield"></i> **Use `selfdestruct()` instead of deprecated `suicide()`.** #### <i class="fa fa-shield"></i> **Use `revert` instead of deprecated `throw`.** #### <i class="fa fa-shield"></i> **Avoid to use `tx.origin`.** #### <i class="fa fa-shield"></i> **Explicitly mark visibility of state.** #### <i class="fa fa-shield"></i> **Compiler version should be the latest at the moment.** #### <i class="fa fa-shield"></i> **Avoid multiple calls of `send` method in single transaction.** #### <i class="fa fa-shield"></i> **Fallback function must be simple.** #### <i class="fa fa-shield"></i> **Check result of `send()` call.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> result of `send()` call checked with if statement: >> ```solidity= >> if(x.send(55)) {} >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> result of `send()` call ignored: >> ```solidity= >> x.send(55); >> ``` > [color=orange] #### <i class="fa fa-shield"></i> **Explicitly mark visibility in function. Except for the constructor.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Functions explicitly marked with visibility: >> ```solidity= >>function b() internal{} >>function b() external {} >>function b() private {} >>function b() public {} >>constructor() {} >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> Functions without explicitly marked visibility: >> ```solidity= >> function b() {} >> ``` > [color=orange] #### <i class="fa fa-shield"></i> **Possible reentrancy vulnerabilities. Avoid state changes after transfer.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Invulnerable Contract 1: >> ```solidity= >> pragma solidity 0.8.10; >> >> contract A { >> mapping(address => uint) private shares; >> >> function b() external { >> uint amount = shares[msg.sender]; >> shares[msg.sender] = 0; >> msg.sender.transfer(amount); >> }// >> } >> ``` >> Invulnerable Contract 2: >> ```solidity= >>pragma solidity 0.8.10; >> >>contract A { >> >> mapping(address => uint) private shares; >> >> function b() external { >> uint amount = shares[msg.sender]; >> user.test(amount); >> shares[msg.sender] = 0; >> }// >>} >> >> ``` >> Invulnerable Contract 3: >> ```solidity= >>pragma solidity 0.8.10; >> >>contract A { >> mapping(address => uint) private shares; >> >> function b() public { >> uint256[] shares; >> uint256 amount = shares[msg.sender]; >> msg.sender.transfer(amount); >> shares[msg.sender] = 0; >> } >> } >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> Vulnerable Contract 1: >> ```solidity= >>pragma solidity 0.8.10; >> >> >>contract A { >> >> mapping(address => uint) private shares; >> >> function b() external { >> uint amount = shares[msg.sender]; >> bool a = msg.sender.send(amount); >> if (a) { shares[msg.sender] = 0; } >> } >> >>} >> ``` >> Vulnerable Contract 2: >> ```solidity= >>pragma solidity 0.8.10; >> >> >>contract A { >> >> mapping(address => uint) private shares; >> >> function b() external { >> uint amount = shares[msg.sender]; >> msg.sender.transfer(amount); >> shares[msg.sender] = 0; >> } >> >>} >> ``` > [color=orange] ## <i class="fa fa-hourglass-half" aria-hidden="true"></i> Best Practise Rules #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Function has cyclomatic complexity "current" but allowed no more than 7.** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Function body contains "some count" lines but allowed no more than 50.** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Line length must be no more than 120.** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Contract has "some count" states declarations but allowed no more than 15.** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Code mustn't contain empty block.** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **If variable is created, then it must be used.** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Integer variable types must be used with visibly indicated sizes.** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Names of constants, variables, functions, contracts and other must be unambiguously interpreted (don't use meaningless names like `a`, `b` , `c` and etc.).** #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **When fallback is not payable you will not be able to receive ethers.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Fallback is payable: >> ```solidity= >>fallback (bytes calldata _input) external payable returns (bytes memory _output) {} >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> Fallback is not payable: >> ```solidity= >> fallback (bytes calldata _input) external returns (bytes memory _output){} >> ``` > [color=orange] #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Require or revert statement must have a reason string and check that each reason string is at most 32 characters long.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Require with reason string: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> >> function b() public { >> require(!has(role, account), "Roles: account already has role"); >> role.bearer[account] = true; >> role.bearer[account] = true; >> } >> >> } >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> Require without reason string: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> >> function b() public { >> require(!has(role, account)); >> role.bearer[account] = true; >> role.bearer[account] = true; >> } >> >> } >> ``` > [color=orange] > #### <i class="fa fa-hourglass-half" aria-hidden="true"></i> **Constructors should use the constructor keyword.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Require with reason string: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> >> constructor() {} >> >> } >> ``` ## <i class="fa fa-text-height" aria-hidden="true"></i> Style Guide Rules ![](https://hackmd.io/_uploads/HJayWRBJa.jpg) #### <i class="fa fa-text-height" aria-hidden="true"></i> **Constant name must be in capitalized SCREAMING_SNAKE_CASE.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Contract name must be in PascalCase.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Event name must be in PascalCase.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Function name must be in camelCase.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Function param name must be in camelCase** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Modifier name must be in camelCase.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Private and internal names must start with a single underscore.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Avoid to use letters 'I', 'l', 'O' as identifiers.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Variable name must be in camelCase.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Interfaces must be prefixed by "I".** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Error must be prefixed with the name of the contract in which it reverted.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Import statements must be on top.** #### <i class="fa fa-text-height" aria-hidden="true"></i> **Use double quotes for string literals. Values can be 'single' or 'double'.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Require with reason string: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> string private a = "test"; >> } >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> String with single quotes: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> string private a = 'test'; >> } >> ``` > [color=orange] > #### <i class="fa fa-text-height" aria-hidden="true"></i> **Function order is incorrect.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Constructor is placed before other functions: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> >> constructor() public {} >> function () public payable {} >> >> } >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> Constructor is placed after other functions: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> >> function () public payable {} >> constructor() public {} >> >> } >> ``` > [color=orange] #### <i class="fa fa-text-height" aria-hidden="true"></i> **Check order of elements in file and inside each contract, according to the style guide** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> All units are in order: >> ```solidity= >>pragma solidity 0.8.10; >> >>import "./some/library.sol"; >>import "./some/other-library.sol"; >> >> enum MyEnum { >> Foo, >> Bar >> } >> >> struct MyStruct { >> uint x; >> uint y; >> } >> >>interface IBox { >> function getValue() public; >> function setValue(uint) public; >>} >> >>library MyLibrary { >> function add(uint a, uint b, uint c) public returns (uint) { >> return a + b + c; >> } >>} >> >>contract MyContract { >> using MyLibrary for uint; >> >> struct InnerStruct { >> bool flag; >> } >> >> enum InnerEnum { >> A, B, C >> } >> >> address payable owner; >> uint public x; >> uint public y; >> >> event MyEvent(address a); >> >> modifier onlyOwner { >> require( >> msg.sender == owner, >> "Only owner can call this function." >> ); >> _; >> } >> >> constructor () public {} >> >> fallback () external {} >> >> function myExternalFunction() external {} >> function myExternalViewFunction() external view {} >> function myExternalPureFunction() external pure {} >> >> function myPublicFunction() public {} >> function myPublicViewFunction() public view {} >> function myPublicPureFunction() public pure {} >> >> function myInternalFunction() internal {} >> function myInternalViewFunction() internal view {} >> function myInternalPureFunction() internal pure {} >> >> function myPrivateFunction() private {} >> function myPrivateViewFunction() private view {} >> function myPrivatePureFunction() private pure {} >>} >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> State variable declaration after function: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract MyContract { >> function foo() public {} >> >> uint a; >> } >> ``` >> Library after contract: >> ```solidity= >>pragma solidity 0.8.10; >> >> contract MyContract {} >> >> library MyLibrary {} >> ``` >> Interface after library: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> library MyLibrary {} >> >> interface MyInterface {} >> ``` > [color=orange] #### <i class="fa fa-text-height" aria-hidden="true"></i> **Visibility modifier must be first in list of modifiers.** > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> Visibility modifier placed first: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> function a() public ownable() payable {} >> } >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> Visibility modifier not placed first: >> ```solidity= >>pragma solidity 0.8.10; >> >> >> contract A { >> function a() ownable() public payable {} >> } >> ``` > [color=orange] #### <i class="fa fa-text-height" aria-hidden="true"></i> **Recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI).** NatSpec comments written with a triple slash (///) or a double asterisk block (/** ... */) and they should be used directly above function declarations or statements and contain the next tags: | Tag | | Context | :----------------:|:-------------------------------:|:---------------:| |<span style="font-size:14pt;color:#CD5C5C;">`@title`|A title that should describe the contract/interface|contract, library, interface| |<span style=«font-size:14pt;color:#CD5C5C;»>`@author`|The name of the author|contract, library, interface| |<span style=«font-size:14pt;color:#CD5C5C;»>`@notice`|Explain to an end user what this does|contract, library, interface, function, public state variable, event| |<span style=«font-size:14pt;color:#CD5C5C;»>`@dev`|Explain to a developer any extra details|contract, library, interface, function, state variable, event| |<span style=«font-size:14pt;color:#CD5C5C;»>`@param`|Documents a parameter just like in Doxygen (must be followed by parameter name)|function, event| |<span style=«font-size:14pt;color:#CD5C5C;»>`@return`|Documents the return variables of a contract’s function|function, public state variable| |<span style=«font-size:14pt;color:#CD5C5C;»>`@inheritdoc`|Copies all missing tags from the base function (must be followed by the contract name)|function, public state variable| |<span style=«font-size:14pt;color:#CD5C5C;»>`@custom:...`|Custom tag, semantics is application-defined|everywhere| <i class="fa fa-thumbs-up"></i> ***For exemple:*** > Require with reason string: > ```solidity= >pragma solidity 0.8.10; > > >/// @author The Solidity Team >/// @title A simple storage example >contract SimpleStorage { > uint storedData; > > /// Store `x`. > /// @param x the new value to store > /// @dev stores the number in the state variable `storedData` > function set(uint x) public { > storedData = x; > } > > /// Return the stored value. > /// @dev retrieves the value of the state variable `storedData` > /// @return the stored value > function get() public view returns (uint) { > return storedData; > } >} > ``` > [color=orange] > ## <i class="fa fa-plus-circle" aria-hidden="true"></i> Miscellaneous <i class="fa fa-plus-circle" aria-hidden="true"></i> Check that all public or external functions are override. This is useful to make sure that the whole API is extracted in an interface. > <i class="fa fa-thumbs-up"></i> ***Examples of correct code for this rule:*** >> All public functions are overrides: >> ```solidity= >>pragma solidity 0.8.10; >> >> >>contract Foo is FooInterface { >> function foo() public override {} >>} >> ``` > <i class="fa fa-thumbs-down"></i> ***Examples of incorrect code for this rule:*** >> A public function is not an override: >> ```solidity= >>pragma solidity 0.8.10; >> >> >>contract Foo { >> function foo() public {} >>} >> ``` > [color=orange]