Features implement the core feature set of the 0x Protocol. They are trusted with user allowances and permissioned by the 0x Governor. Features are run in the context of the Proxy, via a delegatecall.

Below is a catalog of Features.

Implementing a Feature

The only requirement is that the Feature implements the interface in IFeature. Review the Proxy Section for details on how to write a smart contract that is compatible with our architecture (ex, how to properly manage state).

/// @dev Basic interface for a feature contract.
interface IFeature {

    /// @dev The name of this feature set.
    function FEATURE_NAME() external view returns (string memory name);

    /// @dev The version of this feature set.
    function FEATURE_VERSION() external view returns (uint256 version);

Best Practices

We use this checklist to review the safety of new Features.

- [ ] Feature has updated version information.
- [ ] implements IFeature interface.
- [ ] Feature contracts are stateless (including inherited contracts).
- [ ] onlySelf feature functions are prefixed with _.
- [ ] Feature functions are added to full_migration_tests.
- [ ] No delegatecalls from inside a feature. Call other features through the router.
- [ ] No self-destruct in features (except BootstrapFeature).
- [ ] No intentionally persistent (non-atomic) balances on the Exchange Proxy.
- [ ] No direct access to another feature’s storage bucket without strong justification.
- [ ] No executing arbitrary calldata from the context of the Exchange Proxy.
- [ ] No external calls to arbitrary contracts from within the Exchange Proxy.
- [ ] Features use unique StorageIds.
- [ ] Document functions with execution contexts outside of the Exchange Proxy.
- [ ] Document feature dependencies in checklist doc.
- [ ] Document reentrant functions in checklist doc.
- [ ] Document temporary balances.