// SPDX-License-Identifier: XXX
- Pragmas
- Imports - grouped by category, separated by a new line, and sorted alphabetically within categories. Categories:
- External dependencies (e.g.
import "@openzeppelin/contracts/access/Ownable.sol";
) - In-repo dependencies (e.g.
import "./libraries/AddressLinkedList.sol";
)
- External dependencies (e.g.
- Contract contents - ordered logically within categories. Categories:
- Using X for Y;
- Constants / immutables
- Enums
- Structs
- State variables
- Events
- Errors
- Modifiers
- Constructor
- Receive function (if exists)
- Fallback function (if exists)
- External functions - ordered state modifying -> view -> pure
- Public functions - ordered state modifying -> view -> pure
- Internal functions - ordered state modifying -> view -> pure
- Private functions - ordered state modifying -> view -> pure
- Well named and without abbreviations (e.g.
voteForGroup
instead ofvoteForGrp
, etc). - Function names are generally not prefixed with an underscore.
- Parameters are generally ordered with "identifying" information first. E.g.
function voteFor(address group, uint256 amount)
instead offunction voteFor(uint256 amount, address group)
. - Constructor or setter parameters that must be disambiguated, e.g.
setFoo(uint _foo) { foo = _foo; }
may be prefixed with an underscore. All other function parameters should not be prefixed with underscores.
- Well named and without abbreviations (e.g.
votesForGroup
instead ofvotesForGrp
, etc). - No underscore prefixing, even for private variables.
- Natspec used for all structs, state variables, errors, events, modifiers, constructors, and functions.
///
syntax may be used for single-line natspec comments-- e.g. if there is only an@notice
, but multi-line natspec comments should use/**
syntax. - Comments are grammatically and syntactically close to normal sentences-- e.g. first words are capitalized and always end with periods.
- Generally of the form:
SomethingHappened
, rather thanSomething
(e.g.CeloDeposited
instead ofCeloDeposit
). - When a primitive state variable has been updated via a setter (most often as a result of an owner changing the value), an event of the form
VariableNameUpdated
should be emitted with the new value-- e.g.event GroupVoterUpdated(address groupVoter)
. - Should contain enough information such that if all events were streamed from the beginning of time, the current state could theoretically be reconstructed.
- Parameters are not prefixed with an underscore.
- Parameters are indexed if they are likely to be searched for — e.g.
event CeloDeposited(address indexed group, uint256 amount)
, where it's likely that deposits for a group will be searched for but not likely that the exact amount of a deposit will ever be searched for.
- Should have descriptive names.
- Should contain relevant parameters, e.g.
error GroupAlreadyDeprecated(address group);
includes the group that is already deprecated. - When something has failed, the event should be of the form:
SomethingFailed
.