FuelLabs/sway-standards

SRC-5; Ownership Standard

bitzoic opened this issue · 2 comments

Abstract

The following standard intends to enable the use of administrators or owners in Sway contracts.

Motivation

The standard seeks to provide a method for restricting access to particular users within a Sway contract.

Prior Art

The sway-libs repository contains a pre-existing Ownership library.

Ownership libraries exist for other ecosystems such as OpenZeppelin's Ownership library.

Specification

State

There shall be 3 states for any library implementing an ownership module, these are:

- Uninitialized

The Uninitialized state SHALL be set as the initial state if no owner or admin is set. The Uninitialized state may be used when an owner or admin MAY be set in the future.

- Initialized

The Initialized state SHALL be set as the state if an owner or admin is set.

- Revoked

The Revoked state SHALL be set when there is no owner or admin and there SHALL not be one set in the future.

Functions

The following functions MUST be implemented to follow the SRC-5 standard:

fn only_owner()

This function SHALL be used as a check to ensure the current function caller is an owner or admin.
This function MUST revert if the caller is not defined as an owner or admin.

fn owner() -> State

This function SHALL return the current state of ownership for the contract where State is either Uninitialized, Initialized, or Revoked.

Errors

There shall be error handling.

- NotOwner

This error MUST be emitted when only_owner() reverts.

Rationale

In order to provide a universal method of administrative capabilities, SRC-5 will further enable interoperability between applications and provide safeguards for smart contract security.

Backwards Compatability

The SRC-5 standard is compatible with the sway-libs repository pre-existing Ownership library. Considerations should be made to best handle multiple owners or admins.

There are no standards that SRC-5 requires to be compatible with.

Security Considerations

The SRC-5 standard should help improve the security of Sway contracts and their interoperability.

Examples

pub enum State {
    Uninitialized: (),
    Initialized: Identity,
    Revoked: (),
}

pub struct Ownership {
    owner: State,
}

impl StorageKey<Ownership> {
    #[storage(read)]
    pub fn owner(self) -> State {
        self.read().owner
    }
}

impl StorageKey<Ownership> {
    pub fn only_owner(self) {
        require(self.owner() == State::Initialized(msg_sender().unwrap()), AccessError::NotOwner);
    }
}

Updated to include error handling.

Typo: Revkoed