Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vault standard; SRC-6 #24

Merged
merged 79 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
fb9e76f
initial commit
SwayStar123 Sep 17, 2023
bdbc811
Update readme
SwayStar123 Sep 25, 2023
d99d57b
forc fmt
SwayStar123 Sep 25, 2023
90fef86
Improve wording
SwayStar123 Oct 3, 2023
eaae21d
req changes
SwayStar123 Oct 3, 2023
614a197
add space between fn docs
SwayStar123 Oct 3, 2023
2967abc
remove tab
SwayStar123 Oct 3, 2023
0a25bf9
remove preview functions
SwayStar123 Oct 10, 2023
ac2f913
init
SwayStar123 Oct 17, 2023
8d9f65e
specs
SwayStar123 Oct 17, 2023
ad9d835
specs
SwayStar123 Oct 17, 2023
f7a804c
add example
SwayStar123 Oct 26, 2023
5b07a7c
move file out of folder
SwayStar123 Oct 30, 2023
2b7ebf3
fix imports
SwayStar123 Oct 31, 2023
610bfca
fmt
SwayStar123 Oct 31, 2023
0573079
move impl block up
SwayStar123 Oct 31, 2023
56f2a44
Merge pull request #28 from FuelLabs/vault-standard-with-subvaults
SwayStar123 Oct 31, 2023
5458c9b
Merge branch 'master' into vault_standard
SwayStar123 Oct 31, 2023
e3ae07e
fmted moved ex
SwayStar123 Nov 2, 2023
9fb0e64
Merge branch 'vault_standard' of https://github.com/FuelLabs/sway-sta…
SwayStar123 Nov 2, 2023
a49f725
update banners
SwayStar123 Nov 30, 2023
e82ed1a
resolve some req changes
SwayStar123 Nov 30, 2023
c2821d6
address some of the req changes
SwayStar123 Dec 1, 2023
9a248c8
remove unnecessary funcs
SwayStar123 Dec 4, 2023
7d202c7
fmt
SwayStar123 Dec 4, 2023
789b449
add second example
SwayStar123 Dec 4, 2023
c015568
fmt
SwayStar123 Dec 4, 2023
505f119
use if instead of match
SwayStar123 Dec 4, 2023
0aa72b7
add third example
SwayStar123 Dec 4, 2023
80a651d
finishing touches
SwayStar123 Dec 5, 2023
b9733f1
Update examples/src_6/multi_token_vault/Forc.toml
SwayStar123 Dec 6, 2023
c3bcd22
Update examples/src_6/multi_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
e069a72
Update examples/src_6/multi_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
96780da
Update examples/src_6/single_token_single_sub_vault/Forc.toml
SwayStar123 Dec 6, 2023
e071263
Update examples/src_6/single_token_single_sub_vault/src/main.sw
SwayStar123 Dec 6, 2023
4d4e87b
Update examples/src_6/single_token_single_sub_vault/src/main.sw
SwayStar123 Dec 6, 2023
2ab2c86
Update examples/src_6/single_token_vault/Forc.toml
SwayStar123 Dec 6, 2023
4efbc42
Update examples/src_6/single_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
f84708b
Update examples/src_6/single_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
8a92553
Update standards/src_6/README.md
SwayStar123 Dec 6, 2023
6fc1d91
Update standards/src_6/README.md
SwayStar123 Dec 6, 2023
c03c459
Update examples/src_6/multi_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
c49c545
Update examples/src_6/multi_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
cbb1ad4
Update examples/src_6/multi_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
ab37a33
Update examples/src_6/multi_token_vault/src/main.sw
SwayStar123 Dec 6, 2023
35310ca
Update examples/src_6/single_token_single_sub_vault/src/main.sw
SwayStar123 Dec 6, 2023
8289539
Add documentation and fix bug
SwayStar123 Dec 7, 2023
6cb7bd0
remove unnecessary into
SwayStar123 Dec 7, 2023
18361e5
unsafe reads fixed
SwayStar123 Dec 7, 2023
00062e2
remove doubling
SwayStar123 Dec 7, 2023
a012f66
forc fmt
SwayStar123 Dec 7, 2023
1602385
remove unncessary braces
SwayStar123 Dec 8, 2023
c71f8ba
fmt
SwayStar123 Dec 8, 2023
3c02c47
change logo
SwayStar123 Dec 12, 2023
88c4a78
modify a line to remove ambiguity
SwayStar123 Dec 12, 2023
3f85686
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
60d7860
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
f7ee8ba
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
e09d6ce
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
3256873
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
b1af20e
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
3e7535f
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
9d87ba9
Update standards/src_6/README.md
SwayStar123 Dec 12, 2023
82c4e13
remove unnecessary line
SwayStar123 Dec 12, 2023
8b5d969
rem,ove unnecessary line
SwayStar123 Dec 12, 2023
c16209f
abstract elaboration
SwayStar123 Dec 12, 2023
db03515
This function
SwayStar123 Dec 12, 2023
ecb4ec3
Update standards/src_6/README.md
SwayStar123 Dec 13, 2023
9e447b6
Update standards/src_6/README.md
SwayStar123 Dec 13, 2023
2713412
Update standards/src_6/README.md
SwayStar123 Dec 13, 2023
e34bf56
change par names
SwayStar123 Dec 15, 2023
3242e5d
Merge branch 'vault_standard' of https://github.com/FuelLabs/sway-sta…
SwayStar123 Dec 15, 2023
1b8d424
fix position of params
SwayStar123 Dec 15, 2023
8c019fb
fix some descriptions
SwayStar123 Dec 15, 2023
fa3b660
changed log var names
SwayStar123 Dec 15, 2023
b0a5928
standardize readme
SwayStar123 Dec 15, 2023
d498552
fmt
SwayStar123 Dec 15, 2023
0f321c5
add periods
SwayStar123 Dec 15, 2023
e4f843a
period.
SwayStar123 Dec 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/src_6/multi_token_vault/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out
target
9 changes: 9 additions & 0 deletions examples/src_6/multi_token_vault/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "multi_token_vault"

[dependencies]
src_20 = { path = "../../../standards/src_20" }
src_6 = { path = "../../../standards/src_6" }
SwayStar123 marked this conversation as resolved.
Show resolved Hide resolved
233 changes: 233 additions & 0 deletions examples/src_6/multi_token_vault/src/main.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
contract;

use std::{
call_frames::msg_asset_id,
context::msg_amount,
hash::{
Hash,
sha256,
},
storage::storage_string::*,
string::String,
token::transfer,
};

use src_6::{Deposit, SRC6, Withdraw};
use src_20::SRC20;

pub struct VaultInfo {
/// Amount of assets currently managed by this vault
managed_assets: u64,
Braqzen marked this conversation as resolved.
Show resolved Hide resolved
/// The sub_id of this vault.
sub_id: SubId,
/// The asset being managed by this vault
asset: AssetId,
}

storage {
/// Vault share AssetId -> VaultInfo.
vault_info: StorageMap<AssetId, VaultInfo> = StorageMap {},
SwayStar123 marked this conversation as resolved.
Show resolved Hide resolved
/// Number of different assets managed by this contract.
total_assets: u64 = 0,
/// Total supply of shares for each asset.
total_supply: StorageMap<AssetId, u64> = StorageMap {},
/// Asset name.
name: StorageMap<AssetId, StorageString> = StorageMap {},
/// Asset symbol.
symbol: StorageMap<AssetId, StorageString> = StorageMap {},
/// Asset decimals.
decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC6 for Contract {
#[storage(read, write)]
fn deposit(receiver: Identity, sub_id: SubId) -> u64 {
let asset_amount = msg_amount();
require(asset_amount != 0, "ZERO_ASSETS");

let asset = msg_asset_id();
let (shares, share_asset, share_asset_sub_id) = preview_deposit(asset, sub_id, asset_amount);

_mint(receiver, share_asset, share_asset_sub_id, shares);
storage
.total_supply
.insert(
share_asset,
storage
.total_supply
.get(share_asset)
.read() + shares,
);

let mut vault_info = storage.vault_info.get(share_asset).read();
vault_info.managed_assets = vault_info
.managed_assets + asset_amount;
storage.vault_info.insert(share_asset, vault_info);

log(Deposit {
caller: msg_sender().unwrap(),
receiver,
asset,
sub_id,
assets: asset_amount,
shares,
});

shares
}

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

let (share_asset_id, share_asset_sub_id) = vault_asset_id(asset, sub_id);

require(msg_asset_id() == share_asset_id, "INVALID_ASSET_ID");
let assets = preview_withdraw(share_asset_id, shares);

_burn(share_asset_id, share_asset_sub_id, shares);
storage
.total_supply
.insert(
share_asset_id,
storage
.total_supply
.get(share_asset_id)
.read() - shares,
);

transfer(receiver, asset, assets);

log(Withdraw {
caller: msg_sender().unwrap(),
receiver,
asset,
sub_id,
assets,
shares,
});

assets
}
#[storage(read)]
fn managed_assets(asset: AssetId, sub_id: SubId) -> u64 {
let vault_share_asset = vault_asset_id(asset, sub_id).0;
// In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
managed_assets(vault_share_asset)
}

#[storage(read)]
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))
}

#[storage(read)]
fn max_withdrawable(asset: AssetId, sub_id: SubId) -> Option<u64> {
// 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))
}
}

impl SRC20 for Contract {
#[storage(read)]
fn total_assets() -> u64 {
storage.total_assets.try_read().unwrap_or(0)
}

#[storage(read)]
fn total_supply(asset: AssetId) -> Option<u64> {
storage.total_supply.get(asset).try_read()
}

#[storage(read)]
fn name(asset: AssetId) -> Option<String> {
storage.name.get(asset).read_slice()
}

#[storage(read)]
fn symbol(asset: AssetId) -> Option<String> {
storage.symbol.get(asset).read_slice()
}

#[storage(read)]
fn decimals(asset: AssetId) -> Option<u8> {
storage.decimals.get(asset).try_read()
}
}

/// Returns the vault shares assetid and subid for the given assets assetid and the vaults sub id
fn vault_asset_id(asset: AssetId, sub_id: SubId) -> (AssetId, SubId) {
let share_asset_sub_id = sha256((asset, sub_id));
let share_asset_id = AssetId::new(ContractId::this(), share_asset_sub_id);
(share_asset_id, share_asset_sub_id)
}

#[storage(read)]
fn managed_assets(share_asset: AssetId) -> u64 {
match storage.vault_info.get(share_asset).try_read() {
Some(vault_info) => vault_info.managed_assets,
None => 0,
}
}

#[storage(read)]
fn preview_deposit(asset: AssetId, sub_id: SubId, assets: u64) -> (u64, AssetId, SubId) {
let (share_asset_id, share_asset_sub_id) = vault_asset_id(asset, sub_id);

let shares_supply = storage.total_supply.get(share_asset_id).try_read().unwrap_or(0);
if shares_supply == 0 {
(assets, share_asset_id, share_asset_sub_id)
} else {
(
assets * shares_supply / managed_assets(share_asset_id),
share_asset_id,
share_asset_sub_id,
)
}
}

#[storage(read)]
fn preview_withdraw(share_asset_id: AssetId, shares: u64) -> u64 {
let supply = storage.total_supply.get(share_asset_id).read();
if supply == shares {
managed_assets(share_asset_id)
} else {
shares * (managed_assets(share_asset_id) / supply)
}
}

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

let supply = storage.total_supply.get(asset_id).try_read();
// Only increment the number of assets minted by this contract if it hasn't been minted before.
if supply.is_none() {
storage.total_assets.write(storage.total_assets.read() + 1);
}
storage
.total_supply
.insert(asset_id, supply.unwrap_or(0) + amount);
mint_to(recipient, sub_id, amount);
}

#[storage(read, write)]
pub fn _burn(asset_id: AssetId, sub_id: SubId, amount: u64) {
use std::{context::this_balance, token::burn};

require(
this_balance(asset_id) >= amount,
"BurnError::NotEnoughTokens",
);
// If we pass the check above, we can assume it is safe to unwrap.
let supply = storage.total_supply.get(asset_id).try_read().unwrap();
storage.total_supply.insert(asset_id, supply - amount);
burn(sub_id, amount);
}
2 changes: 2 additions & 0 deletions examples/src_6/single_token_single_sub_vault/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out
target
9 changes: 9 additions & 0 deletions examples/src_6/single_token_single_sub_vault/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "single_token_single_sub_vault"

[dependencies]
src_20 = { path = "../../../standards/src_20" }
src_6 = { path = "../../../standards/src_6" }
SwayStar123 marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading