Security Concepts

Minimize attack surface

Smart contracts are not your typical application, either. Sometimes when writing an interface to a system, I will include fallbacks or alternatives that perform a “best effort” action, or try to “guess” what the user input means. When writing a smart contract, however, try for the opposite: minimize the domain of valid input to the minimum viable set. The smart contract is the only barrier between an attacker and the integrity of your dapp, so the fewer inputs you have to account for, the better. Contracts should reject at the first sign of something not being quite right.

Systematic function design

Due to its asynchronous cross-contract calls, reentrancy attacks are not quite possible on NEAR the same way they are on EVM chains. However, I would still recommend you follow the checks-effects-interactions order of operations, because:

  • It establishes function invariants chronologically before they are exercised.

  • Cross-contract interactions take the form of a Promise, which must be returned at the end of a function.

  • It is systematic and predictable. Other smart contract authors will be familiar with it.

Make invalid states unrepresentable

As much as is possible, design the data structures your smart contract manipulates in such a way that it is impossible to assemble them into an invalid configuration, or fill them with invalid data. Rust’s type system is quite powerful and flexible, making this concept more applicable than in other programming languages.

Last updated