-
Notifications
You must be signed in to change notification settings - Fork 81
Guidelines contracts
Clément Lesaege edited this page Oct 6, 2018
·
15 revisions
- Use solidity documentation style guide.
- If contract B interacts with contract A, do not write the interface of contract A in the contract B file. Use import instead.
- Comment non-obvious parts of the code. A smart contract must work but must also let external observers be convinced it works.
- Comments should start with an uppercase and end up with a ".".
- Use Doxygen-style tags. For functions and events: @dev, @param and @return. For contracts: @title. For files: @title and @author.
- For functions which call an untrusted account with sufficient gas for reentry (send and transfer do not), specify UNTRUSTED in @dev. If the account is a contract we can trust (because we know its code) specify TRUSTED. Note that specifying a contract type for a variable does not ensure that the address which would be saved will be a contract of this type.
- Specify on files containing non-abstract contract if some bug bounty programs have been run. This avoid using code in production which has not undertaken bug bounty programs.
- If you need some functions for testing purpose which should not be included in production (like creating tokens for free) , don't put it in your contract, but make a testing contract inheriting the production one and put test functions in it.
- Be aware of gas consumption when you code. Else we will end up with out-of-gas and enormous TX fees. Note that this the opposite of other languages where you need to "Get it correct the first time, fast the second", as a code which "out-of-gas" in case of attack is not correct because it will not only be slow: it will fail. It does not mean you need to do in-depth optimization from the beginning. But you should at least take care about computational complexity and that it fits the current gas limit.
- Specify in comments the computational complexity of every function which is not O(1). Note that if a function has not a really low complexity (mainly O(1) or O(log(n)) you have to find workaround to avoid gas issues. These should be explained in comments.
- If possible (i.e, it does not lead to a significant increase in computation) public functions should follow a three sections pattern:
- Verify that the action is authorized (modifiers are included in it).
- Execute the internal changes provoked by the action.
- Interact with other accounts/contracts.
- Do not let unsecured functions without a TODO in the code.
- "Doing 0" is OK. A function sends 0 tokens, gives a penalty of 0%, can't be called again unless 0 seconds pass is fine. You should not make function throw or give error code when they "do 0".
- Smart contracts should not protect the user from himself (for example don't prevent the user from sending their funds to the address 0). The GUI should (because smart contract execution costs gas while GUI execution is almost free). The smart contracts should prevent malicious behaviors while the interface should prevent the stupid ones.