-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: simple defi vault * feat: add Simple defi vault description * fix: typo * fix: simple vault wrapped IERC20Dispatcher
- Loading branch information
Showing
6 changed files
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "simple_vault" | ||
version = "0.1.0" | ||
|
||
# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest | ||
|
||
[dependencies] | ||
starknet = "1.1.0" | ||
|
||
[[target.starknet-contract]] | ||
allowed-libfuncs-list.name = "experimental_v0.1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
mod simple_vault; |
109 changes: 109 additions & 0 deletions
109
listings/ch01-applications/simple_vault/src/simple_vault.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use starknet::{ContractAddress}; | ||
|
||
// In order to make contract calls within our Vault, | ||
// we need to have the ABI of the remote contract defined to import the Dispatcher | ||
#[abi] | ||
trait IERC20 { | ||
#[view] | ||
fn name() -> felt252; | ||
|
||
#[view] | ||
fn symbol() -> felt252; | ||
|
||
#[view] | ||
fn decimals() -> u8; | ||
|
||
#[view] | ||
fn total_supply() -> u256; | ||
|
||
#[view] | ||
fn balance_of(account: ContractAddress) -> u256; | ||
|
||
#[view] | ||
fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256; | ||
|
||
#[external] | ||
fn transfer(recipient: ContractAddress, amount: u256) -> bool; | ||
|
||
#[external] | ||
fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool; | ||
|
||
#[external] | ||
fn approve(spender: ContractAddress, amount: u256) -> bool; | ||
} | ||
|
||
#[contract] | ||
mod SimpleVault { | ||
use super::{IERC20Dispatcher, IERC20DispatcherTrait}; | ||
use starknet::{ | ||
ContractAddress, | ||
get_caller_address, | ||
get_contract_address | ||
}; | ||
|
||
struct Storage { | ||
_token: IERC20Dispatcher, | ||
_total_supply: u256, | ||
_balance_of: LegacyMap<ContractAddress, u256> | ||
} | ||
|
||
#[constructor] | ||
fn constructor(token: ContractAddress) { | ||
_token::write(IERC20Dispatcher { contract_address: token }); | ||
} | ||
|
||
fn _mint(to: ContractAddress, shares: u256) { | ||
_total_supply::write(_total_supply::read() + shares); | ||
_balance_of::write(to, _balance_of::read(to) + shares); | ||
} | ||
|
||
fn _burn(from: ContractAddress, shares: u256) { | ||
_total_supply::write(_total_supply::read() - shares); | ||
_balance_of::write(from, _balance_of::read(from) - shares); | ||
} | ||
|
||
#[external] | ||
fn deposit(amount: u256) { | ||
// a = amount | ||
// B = balance of token before deposit | ||
// T = total supply | ||
// s = shares to mint | ||
// | ||
// (T + s) / T = (a + B) / B | ||
// | ||
// s = aT / B | ||
let caller = get_caller_address(); | ||
let this = get_contract_address(); | ||
|
||
let mut shares = 0; | ||
if _total_supply::read() == 0 { | ||
shares = amount; | ||
} else { | ||
let balance = _token::read().balance_of(this); | ||
shares = (amount * _total_supply::read()) / balance; | ||
} | ||
|
||
_mint(caller, shares); | ||
_token::read().transfer_from(caller, this, amount); | ||
} | ||
|
||
#[external] | ||
fn withdraw(shares: u256) { | ||
// a = amount | ||
// B = balance of token before withdraw | ||
// T = total supply | ||
// s = shares to burn | ||
// | ||
// (T - s) / T = (B - a) / B | ||
// | ||
// a = sB / T | ||
let caller = get_caller_address(); | ||
let this = get_contract_address(); | ||
|
||
let balance = _token::read().balance_of(this); | ||
let amount = (shares * balance) / _total_supply::read(); | ||
_burn(caller, shares); | ||
_token::read().transfer(caller, amount); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Simple Defi Vault | ||
|
||
This is the Cairo adaptation of the [Solidity by example Vault](https://solidity-by-example.org/defi/vault/). | ||
Here's how it works: | ||
|
||
- When a user deposits a token, the contract calculates the amount of shares to mint. | ||
|
||
- When a user withdraws, the contract burns their shares, calculates the yield, and withdraw both the yield and the initial amount of token deposited. | ||
|
||
```rust | ||
{{#include ../listings/ch01-applications/simple_vault/src/simple_vault.cairo}} | ||
``` | ||
|
||
> **Note** | ||
> As of version v1.1.0, we need to enable `experimental_v0.1.0` libfuncs to use `u256_divmod_safe` as it hasn't been audited yet. | ||
> It'll be included in v2.0.0. |