Skip to content

Commit

Permalink
edit readme
Browse files Browse the repository at this point in the history
  • Loading branch information
SwayStar123 committed Jan 23, 2024
1 parent 9b49b8d commit 14fea77
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 133 deletions.
151 changes: 19 additions & 132 deletions standards/src11-security-information/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,168 +7,55 @@

# Abstract

The following standard allows for the implementation of a standard API for token vaults such as yield-bearing token vaults or asset wrappers. This standard is an optional add-on to the [SRC-20](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_20) standard.
The following standard allows for contract creators to make communication information readily available to everyone, with the primary purpose of allowing white hat hackers to coordinate a bug-fix or securing of funds.

# Motivation

Token vaults allow users to own shares of variable amounts of assets, such as lending protocols which may have growing assets due to profits from interest. This pattern is highly useful and would greatly benefit from standardization.
White hat hackers may find bugs or exploits in contracts which they want to report to the project for safeguarding of funds. It is not immedietely obvious from a ContractId, who the right person to contact is. This standarad aims to make the process of bug reporting as smooth as possible

# Prior Art

Token vaults have been thoroughly explored on Ethereum and with [EIP 4626](https://eips.ethereum.org/EIPS/eip-4626) they have their own standard for it. However as Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) are fundamentally different from Ethereum's ERC-20 tokens, the implementation will differ, but the interface may be used as a reference.
The [security.txt](https://github.com/neodyme-labs/solana-security-txt) library for solana has explored this idea. This standard takes inspiration from the library, with some changes.

# Specification

## Required public functions

The following functions MUST be implemented to follow the SRC-6 standard. Any contract that implements the SRC-6 standard MUST implement the SRC-20 standard.

### `fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64`
### `fn security_information() -> SecurityInformation;`

This function takes the `receiver` Identity and the SubId `vault_sub_id` of the sub-vault as an argument and returns the amount of shares minted to the `receiver`.
This function takes no input parameters and returns a struct containing contact information for the project owners, information regarding the bug bounty program, other information related to security, and any other information which the developers find relevant.

- This function MUST allow for depositing of the underlying asset in exchange for pro-rata shares of the vault.
- This function MAY reject arbitrary assets based on implementation and MUST revert if unaccepted assets are forwarded.
- This function MUST mint an asset representing the pro-rata share of the vault, with the SubId of the `sha256((underlying_asset, vault_sub_id))` digest, where `underlying_asset` is the AssetId of the deposited asset and the `vault_sub_id` is the id of the vault.
- This function MUST emit a `Deposit` log.
- This function MUST return the amount of minted shares.
- This function MUST return accurate and up to date information.
- This function MAY not return the optional parameters.
- This function MUST return atleast one item in the `contact_information` field's `Vec`. Furthurmore, the string should follow the following format `<contact_type>:<contact_information>`.
- This function MUST NOT return any empty strings. Optional parameters must return `None` if it is unnecessary.
- This function MUST return atleast one item in the `preferred_languages`, if it is not `None`. Furthurmore, the string should only contain the `ISO 639-1` language code and nothing else.
- This function MAY return a link or the information directly for the following fields: `project_url`, `policy`, `encryption`, `source_code`, `auditors`, `acknowledgements`, `additional_information`.
- This function MUST return the information directly for the following fields: `name`, `contact_information`, `preferred_languages`, `source_release`, `source_revision`.

### `fn withdraw(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> u64`

This function takes the `receiver` Identity, the `underlying_asset` AssetId, and the `vault_sub_id` of the sub vault, as arguments and returns the amount of assets transferred to the `receiver`.

- This function MUST allow for redeeming of the vault shares in exchange for a pro-rata amount of the underlying assets.
- This function MUST revert if any AssetId other than the AssetId representing the underlying asset's shares for the given sub vault at `vault_sub_id` is forwarded. (i.e. transferred share's AssetId must be equal to `AssetId::new(ContractId::this(), sha256((underlying_asset, vault_sub_id))`)
- This function MUST burn the received shares.
- This function MUST emit a `Withdraw` log.
- This function MUST return amount of assets transferred to the receiver.

### `fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64`

This function returns the total assets under management by vault. Includes assets controlled by the vault but not directly possessed by vault. It takes the `underlying_asset` AssetId and the `vault_sub_id` of the sub vault as arguments and returns the total amount of assets of AssetId under management by vault.

- This function MUST return total amount of assets of `underlying_asset` AssetId under management by vault.
- This function MUST return 0 if there are no assets of `underlying_asset` AssetId under management by vault.
- This function MUST NOT revert under any circumstances.

### `fn max_depositable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>`

This is a helper function for getting the maximum amount of assets that can be deposited. It takes the hypothetical `receiver` Identity, the `underlying_asset` AssetId, and the `vault_sub_id` SubId of the sub vault as an arguments and returns the maximum amount of assets that can be deposited into the contract, for the given asset.

- This function MUST return the maximum amount of assets that can be deposited into the contract, for the given `underlying_asset`, if the given `vault_sub_id` vault exists.
- This function MUST return an `Some(amount)` if the given `vault_sub_id` vault exists.
- This function MUST return an `None` if the given `vault_sub_id` vault does not exist.
- This function MUST account for both global and user specific limits. For example: if deposits are disabled, even temporarily, MUST return 0.

### `fn max_withdrawable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>`

This is a helper function for getting maximum withdrawable. It takes the hypothetical `receiver` Identity, the `underlying_asset` AssetId, and the `vault_sub_id` SubId of the sub vault as an argument and returns the maximum amount of assets that can be withdrawn from the contract, for the given asset.

- This function MUST return the maximum amount of assets that can be withdrawn from the contract, for the given `underlying_asset`, if the given `vault_sub_id` vault exists.
- This function MUST return an `Some(amount)` if the given `vault_sub_id` vault exists.
- This function MUST return an `None` if the given `vault_sub_id` vault does not exist.
- This function MUST account for global limits. For example: if withdrawals are disabled, even temporarily, MUST return 0.

## Required logs

The following logs MUST be emitted at the specified occasions.

### `Deposit`

`caller` has called the `deposit()` method sending `deposited_amount` assets of the `underlying_asset` Asset to the subvault of `vault_sub_id`, in exchange for `minted_shares` shares sent to the receiver `receiver`.

The `Deposit` struct MUST be logged whenever new shares are minted via the `deposit()` method.

The `Deposit` log SHALL have the following fields.

#### - `caller`: Identity

The `caller` field MUST represent the Identity which called the deposit function.

#### - `receiver`: Identity

The `receiver` field MUST represent the Identity which received the vault shares.

#### - `underlying_asset`: AssetId

The `underlying_asset` field MUST represent the AssetId of the asset which was deposited into the vault.

#### - `vault_sub_id`: SubId

The `vault_sub_id` field MUST represent the SubId of the vault which was deposited into.

#### - `deposited_amount`: u64

The `deposited_amount` field MUST represent the u64 amount of assets deposited into the vault.

#### - `minted_shares`: u64

The `minted_shares` field MUST represent the u64 amount of shares minted.

### `Withdraw`

`caller` has called the `withdraw()` method sending `burned_shares` shares in exchange for `withdrawn_amount` assets of the `underlying_asset` Asset from the subvault of `vault_sub_id` to the receiver `receiver`.

The `Withdraw` struct MUST be logged whenever shares are redeemed for assets via the `withdraw()` method.

The `Withdraw` log SHALL have the following fields.

#### - `caller`: Identity

The `caller` field MUST represent the Identity which called the withdraw function.

#### - `receiver`: Identity

The `receiver` field MUST represent the Identity which received the withdrawn assets.

#### - `underlying_asset`: AssetId

The `underlying_asset` field MUST represent the AssetId of the asset that was withdrawn.

#### - `vault_sub_id`: SubId

The `vault_sub_id` field MUST represent the SubId of the vault from which was withdrawn.

#### - `withdrawn_amount`: u64

The `withdrawn_amount` field MUST represent the u64 amount of tokens withdrawn.

#### - `burned_shares`: u64

The `burned_shares` field MUST represent the u64 amount of shares burned.

# Rationale

The ABI discussed covers the known use cases of token vaults while allowing safe implementations.
The return structure discussed covers most information that may want to be conveyed regarding the security of the contract, with an additional field to convey any additional information. This should allow easy communication between the project owners and any white hat hackers if necessary.

# Backwards Compatibility

This standard is fully compatible with the [SRC-20 standard](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_20).
This standard does not face any issues with backward compatibility.

// Is this section necessary?

# Security Considerations

Incorrect implementation of token vaults could allow attackers to steal underlying assets. It is recommended to properly audit any code using this standard to ensure exploits are not possible.
The information is entirely self reported and as such might not be accurate. Accuracy of information cannot be enforced and as such, anyone using this information should be aware of that.

# Example ABI

```sway
abi SRC6 {
#[payable]
#[storage(read, write)]
fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64;
#[payable]
#[storage(read, write)]
fn withdraw(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> u64;
#[storage(read)]
fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64;
#[storage(read)]
fn max_depositable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>;
abi SRC11 {
#[storage(read)]
fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>;
fn security_information() -> SecurityInformation;
}
```

Expand Down
3 changes: 2 additions & 1 deletion standards/src11-security-information/src/src11.sw
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct SecurityInformation {
/// The revision identifier of this build, usually a git sha that can be rebuilt to reproduce the same binary.
/// 3rd party build verification tools will use this tag to identify a matching github releases.
source_revision: Option<String>,
/// A comma-separated list of people or entities that audited this smart contract, or a link to a page where audit reports are hosted.
/// A list of people or entities that audited this smart contract, or links to pages where audit reports are hosted.
/// Note that this field is self-reported by the author of the program and might not be accurate.
auditors: Option<Vec<String>>,
/// Either a link or a text document containing acknowledgements to security researchers who have previously found vulnerabilities in the project.
Expand All @@ -43,5 +43,6 @@ abi SRC11 {
/// # Returns
///
/// * [SecurityInformation] - Security information about the contract.
#[storage(read)]
fn security_information() -> SecurityInformation;
}

0 comments on commit 14fea77

Please sign in to comment.