Skip to content

Commit

Permalink
finishing touches
Browse files Browse the repository at this point in the history
  • Loading branch information
SwayStar123 committed Dec 5, 2023
1 parent 0aa72b7 commit 80a651d
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 131 deletions.
17 changes: 3 additions & 14 deletions examples/src_6/multi_token_vault/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use std::{
Hash,
sha256,
},
string::String,
storage::{
storage_map::*,
storage_string::*,
},
string::String,
token::{
transfer,
},
Expand Down Expand Up @@ -75,7 +75,7 @@ impl SRC6 for Contract {
}

#[storage(read, write)]
fn withdraw(asset: AssetId, sub_id: SubId, receiver: Identity) -> u64 {
fn withdraw(receiver: Identity, asset: AssetId, sub_id: SubId) -> u64 {
let shares = msg_amount();
require(shares != 0, "ZERO_SHARES");

Expand All @@ -102,7 +102,7 @@ impl SRC6 for Contract {
}

#[storage(read)]
fn max_depositable(asset: AssetId, sub_id: SubId) -> Option<u64> {
fn max_depositable(receiver: Identity, asset: AssetId, sub_id: SubId) -> Option<u64> {
// This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
Some(u64::max() - managed_assets(asset))
}
Expand All @@ -112,17 +112,6 @@ impl SRC6 for Contract {
// In this implementation total_assets and max_withdrawable are the same. However in case of lending out of assets, total_assets should be greater than max_withdrawable.
Some(managed_assets(asset))
}

#[storage(read)]
fn vault_asset_id(asset: AssetId, sub_id: SubId) -> Option<(AssetId, SubId)> {
Some(vault_asset_id(asset, sub_id))
}

#[storage(read)]
fn asset_of_vault(vault_asset_id: AssetId) -> Option<(AssetId, SubId)> {
let vault_info = storage.vault_info.get(vault_asset_id).read();
Some((vault_info.asset, vault_info.sub_id))
}
}

impl SRC20 for Contract {
Expand Down
29 changes: 3 additions & 26 deletions examples/src_6/single_token_single_sub_vault/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use src_20::SRC20;
configurable {
ACCEPTED_TOKEN: AssetId = std::constants::BASE_ASSET_ID,
ACCEPTED_SUB_VAULT: SubId = std::constants::ZERO_B256,
// Calculated as sha256((ACCEPTED_TOKEN, ACCEPTED_SUB_VAULT))
PRE_CALCULATED_SHARE_SUB_ID: SubId = 0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b,
}

Expand Down Expand Up @@ -75,7 +74,7 @@ impl SRC6 for Contract {
}

#[storage(read, write)]
fn withdraw(asset: AssetId, sub_id: SubId, receiver: Identity) -> u64 {
fn withdraw(receiver: Identity, asset: AssetId, sub_id: SubId) -> u64 {
require(asset == ACCEPTED_TOKEN, "INVALID_ASSET_ID");
require(sub_id == ACCEPTED_SUB_VAULT, "INVALID_SUB_ID");

Expand Down Expand Up @@ -105,7 +104,7 @@ impl SRC6 for Contract {
}

#[storage(read)]
fn max_depositable(asset: AssetId, sub_id: SubId) -> Option<u64> {
fn max_depositable(receiver: Identity, asset: AssetId, sub_id: SubId) -> Option<u64> {
if asset == ACCEPTED_TOKEN {
// This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
Some(u64::max() - storage.managed_assets.read())
Expand All @@ -123,24 +122,6 @@ impl SRC6 for Contract {
None
}
}

#[storage(read)]
fn vault_asset_id(asset: AssetId, sub_id: SubId) -> Option<(AssetId, SubId)> {
if asset == ACCEPTED_TOKEN && sub_id == ACCEPTED_SUB_VAULT {
Some((vault_assetid(), PRE_CALCULATED_SHARE_SUB_ID))
} else {
None
}
}

#[storage(read)]
fn asset_of_vault(vault_asset_id: AssetId) -> Option<(AssetId, SubId)> {
if vault_assetid() == vault_asset_id {
Some((ACCEPTED_TOKEN, ACCEPTED_SUB_VAULT))
} else {
None
}
}
}

impl SRC20 for Contract {
Expand Down Expand Up @@ -202,11 +183,7 @@ fn preview_withdraw(shares: u64) -> u64 {
}

#[storage(read, write)]
pub fn _mint(
recipient: Identity,
asset_id: AssetId,
amount: u64,
) {
pub fn _mint(recipient: Identity, asset_id: AssetId, amount: u64) {
use std::token::mint_to;

let supply = storage.total_supply.read();
Expand Down
25 changes: 2 additions & 23 deletions examples/src_6/single_token_vault/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl SRC6 for Contract {
}

#[storage(read, write)]
fn withdraw(asset: AssetId, sub_id: SubId, receiver: Identity) -> u64 {
fn withdraw(receiver: Identity, asset: AssetId, sub_id: SubId) -> u64 {
let shares = msg_amount();
require(shares != 0, "ZERO_SHARES");

Expand All @@ -112,7 +112,7 @@ impl SRC6 for Contract {
}

#[storage(read)]
fn max_depositable(asset: AssetId, sub_id: SubId) -> Option<u64> {
fn max_depositable(receiver: Identity, asset: AssetId, sub_id: SubId) -> Option<u64> {
if asset == ACCEPTED_TOKEN {
// This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
Some(u64::max() - managed_assets(asset))
Expand All @@ -130,27 +130,6 @@ impl SRC6 for Contract {
None
}
}

#[storage(read)]
fn vault_asset_id(asset: AssetId, sub_id: SubId) -> Option<(AssetId, SubId)> {
if asset == ACCEPTED_TOKEN {
Some(vault_asset_id(asset, sub_id))
} else {
None
}
}

#[storage(read)]
fn asset_of_vault(vault_asset_id: AssetId) -> Option<(AssetId, SubId)> {
let asset = storage.vault_info.get(vault_asset_id).read().asset;

if asset == ACCEPTED_TOKEN {
let vault_info = storage.vault_info.get(vault_asset_id).read();
Some((vault_info.asset, vault_info.sub_id))
} else {
None
}
}
}

impl SRC20 for Contract {
Expand Down
62 changes: 26 additions & 36 deletions standards/src_6/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,25 @@ The following functions MUST be implemented to follow the SRC-6 standard. Any co
Method that allows depositing of the underlying asset in exchange for shares of the vault.
This function takes the receiver's identity and the sub_id of the sub vault as an argument and returns the amount of shares minted to the receiver.

MUST revert if any AssetId other than the underlying is forwarded.
MUST increase `managed_assets` by `deposited_assets` (through any means including `std::context::this_balance(ASSET_ID)` if applicable).
MUST revert if any unaccepted AssetId is forwarded.
MUST increase `managed_assets` by amount of deposited assets (through any means including `std::context::this_balance(ASSET_ID)` if applicable).
MUST mint a token representing the pro-rata share of the vault, with the AssetId of `sha256((asset, sub_id))`, a hash of the AssetId of the deposited asset, and the `sub_id` of the vault.
MUST increase `total_supply` of the share's AssetId by newly minted shares.
MUST increase `total_assets` by one if the the AssetId is minted for the first time.
MUST emit a `Deposit` log.
MUST return amount of minted shares.

### `fn withdraw(asset: AssetId, sub_id: SubId, receiver: Identity) -> u64`
### `fn withdraw(receiver: Identity, asset: AssetId, sub_id: SubId) -> u64`

Method that allows the redeeming of the vault shares in exchange for a pro-rata amount of the underlying asset
This function takes the asset's AssetId, the sub_id of the sub vault, and the receiver's identity as arguments and returns the amount of assets transferred to the receiver.
The AssetId of the asset, and the AssetId of the shares MUST be one-to-one, meaning every deposited AssetId shall have a unique corresponding shares AssetId.

MUST revert if any AssetId other than the AssetId corresponding to the deposited asset is forwarded.
MUST revert if any AssetId other than the AssetId representing the deposited asset's shares for the given sub vault at `sub_id` is forwarded.
MUST burn the received shares.
MUST reduce `total_supply` of the shares's AssetId by amount of burnt shares.
MUST emit a `Withdraw` log.
MUST return amount of assets transferred to the receiver.

### `fn managed_assets(asset: AssetId, sub_id: SubId) -> u64`

Expand All @@ -54,37 +57,26 @@ MUST return total amount of assets of underlying AssetId under management by vau
MUST return 0 if there are no assets of underlying AssetId under management by vault.
MUST NOT revert under any circumstances.

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

Helper method for getting maximum depositable
This function takes the asset's AssetId and the sub_id of the sub vault as an argument and returns the maximum amount of assets that can be deposited into the contract, for the given asset.
This function takes the hypothetical receivers `Identity`, the asset's `AssetId`, and the `sub_id` of the sub vault as an argument and returns the maximum amount of assets that can be deposited into the contract, for the given asset.

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

### `fn max_withdrawable(asset: AssetId, sub_id: SubId) -> Option<u64>`

Helper method for getting maximum withdrawable
This function takes the asset's AssetId and the sub_id 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.

MUST return the maximum amount of assets that can be withdrawn from the contract, for the given asset.

### `fn vault_asset_id(asset: AssetId, sub_id: SubId) -> Option<AssetId>`

Method that returns the AssetId of the vault shares for the given asset and sub vault.
This function takes the asset's AssetId and the SubId of the vault as arguments and returns the AssetId of the vault shares for the given asset and sub vault.
### `fn max_withdrawable(receiver: Identity, asset: AssetId, sub_id: SubId) -> Option<u64>`

MUST return an `Option::Some(AssetId)` of the vault shares for the given asset and sub vault, if the given asset is supported.
MUST return an `Option::None` if the given asset is not supported.
MUST NOT revert under any circumstances.

### `fn asset_of_vault(vault_asset_id: AssetId) -> Option<AssetId>`
Helper method for getting maximum withdrawable
This function takes the hypothetical receive's `Identity`, the asset's `AssetId`, and the `sub_id`` 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.

Method that returns the AssetId of the asset of the vault for the given AssetId of the vault shares.
This function takes the AssetId of the vault shares as an argument and returns the AssetId of the asset of the vault for the given AssetId of the vault shares.

MUST return an `Option::Some(AssetId)` of the asset of the vault for the given AssetId of the vault shares, if the given asset is supported and the vault has been initialised.
MUST return an `Option::None` if the given asset is not supported or the vault has not been initialised.
MUST NOT revert under any circumstances.
MUST return the maximum amount of assets that can be withdrawn from the contract, for the given asset, if the given vault exists.
MUST return an `Option::Some(amount)` if the given vault exists.
MUST return an `Option::None` if the given vault does not exist.
MUST account for global limits. For example: if withdrawals are disabled, even temporarily, MUST return 0.

## Required logs

Expand Down Expand Up @@ -152,22 +144,16 @@ abi SRC6 {
fn deposit(receiver: Identity, sub_id: SubId) -> u64;
#[storage(read, write)]
fn withdraw(asset: AssetId, sub_id: SubId, receiver: Identity) -> u64;
fn withdraw(receiver: Identity, asset: AssetId, sub_id: SubId) -> u64;
#[storage(read)]
fn managed_assets(asset: AssetId, sub_id: SubId) -> u64;
#[storage(read)]
fn max_depositable(asset: AssetId, sub_id: SubId) -> Option<u64>;
fn max_depositable(receiver: Identity, asset: AssetId, sub_id: SubId) -> Option<u64>;
#[storage(read)]
fn max_withdrawable(asset: AssetId, sub_id: SubId) -> Option<u64>;
#[storage(read)]
fn vault_asset_id(asset: AssetId, sub_id: SubId) -> Option<(AssetId, SubId)>;
#[storage(read)]
fn asset_of_vault(vault_asset_id: AssetId) -> Option<(AssetId, SubId)>;
}
```

Expand All @@ -180,3 +166,7 @@ A barebones implementation of the vault standard that supports any number of sub
## [Single Token Vault](../../examples/src_6/single_token_vault/)

A barebones implemenation of the vault standard demonstrating how to constrict deposits and withdrawals to a single AssetId.

## [Single Token Single Sub Vault](../../examples/src_6/single_token_single_sub_vault/)

A barebones implementation of the vault standard demonstrating how to constrict deposits and withdrawals to a single AssetId, and to a single Sub vault.
38 changes: 6 additions & 32 deletions standards/src_6/src/src_6.sw
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ abi SRC6 {
///
/// # Arguments
///
/// * `receiver`: [Identity] - The receiver of the assets.
/// * `asset`: [AssetId] - The asset for which the shares should be burned.
/// * `sub_id`: [SubId] - The SubId of the vault.
/// * `receiver`: [Identity] - The receiver of the assets.
///
/// # Returns
///
Expand All @@ -79,7 +79,7 @@ abi SRC6 {
/// * If the transferred shares do not corresspond to the given asset.
/// * The user crosses any global or user specific withdrawal limits.
#[storage(read, write)]
fn withdraw(asset: AssetId, sub_id: SubId, receiver: Identity) -> u64;
fn withdraw(receiver: Identity, asset: AssetId, sub_id: SubId) -> u64;

/// Returns the amount of managed assets of the given asset.
///
Expand All @@ -98,10 +98,11 @@ abi SRC6 {
///
/// # Additional Information
///
/// Does not account for any user or global limits.
/// Must account for any user or global limits.
///
/// # Arguments
///
/// * `receiver`: [Identity] - The hypothetical receiver of the shares.
/// * `asset`: [AssetId] - The asset for which the maximum amount of depositable assets should be returned.
/// * `sub_id`: [SubId] - The SubId of the vault.
///
Expand All @@ -110,13 +111,13 @@ abi SRC6 {
/// * [Some(u64)] - The maximum amount of assets that can be deposited into the contract, for the given asset.
/// * [None] - If the asset is not supported by the contract.
#[storage(read)]
fn max_depositable(asset: AssetId, sub_id: SubId) -> Option<u64>;
fn max_depositable(receiver: Identity, asset: AssetId, sub_id: SubId) -> Option<u64>;

/// Returns the maximum amount of assets that can be withdrawn from the contract, for the given asset.
///
/// # Additional Information
///
/// Does not account for any user or global limits.
/// Must account for any global limits.
///
/// # Arguments
///
Expand All @@ -129,31 +130,4 @@ abi SRC6 {
/// * [None] - If the asset is not supported by the contract.
#[storage(read)]
fn max_withdrawable(asset: AssetId, sub_id: SubId) -> Option<u64>;

/// Returns the AssetId and SubId of the vault shares for the given asset and sub vault.
///
/// # Arguments
///
/// * `asset`: [AssetId] - The asset for which the vault shares should be returned.
/// * `sub_id`: [SubId] - The SubId of the vault.
///
/// # Returns
///
/// * [Some((AssetId, SubId))] - The AssetId and SubId of the vault shares for the given asset and sub vault.
/// * [None] - If the asset is not supported by the contract.
#[storage(read)]
fn vault_asset_id(asset: AssetId, sub_id: SubId) -> Option<(AssetId, SubId)>;

/// Returns the AssetId of the asset of the vault for the given AssetId of the vault shares, and the sub_id of the vault.
///
/// # Arguments
///
/// * `vault_asset_id`: [AssetId] - The AssetId of the vault shares for which the asset of the vault should be returned.
///
/// # Returns
///
/// * [Some((AssetId, SubId))] - The AssetId of the asset of the vault for the given AssetId of the vault shares, and the sub_id of the vault.
/// * [None] - If the asset is not supported by the contract or the vault has not been initialised.
#[storage(read)]
fn asset_of_vault(vault_asset_id: AssetId) -> Option<(AssetId, SubId)>;
}

0 comments on commit 80a651d

Please sign in to comment.