From e6dc8b89532da495a08dc0fd6885b3b9a8bb7e75 Mon Sep 17 00:00:00 2001 From: zkDice <156126180+zkdice-xyz@users.noreply.github.com> Date: Sat, 23 Mar 2024 01:16:40 +0530 Subject: [PATCH 01/37] Update Scarb.toml --- Scarb.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Scarb.toml b/Scarb.toml index 2d94f75..4f4d5f3 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -7,6 +7,8 @@ openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.14.0" } starknet = "2.4.3" +[lib] + [[target.starknet-contract]] sierra = true casm = true From d3b8b5bae4def0204f203d330355da5211500622 Mon Sep 17 00:00:00 2001 From: zkDice <156126180+zkdice-xyz@users.noreply.github.com> Date: Sat, 23 Mar 2024 01:22:46 +0530 Subject: [PATCH 02/37] Update lib.cairo --- src/lib.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.cairo b/src/lib.cairo index ce442a1..345467e 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,4 +1,4 @@ -mod erc4626; +mod ERC4626; #[cfg(test)] mod tests; mod utils; From 1046740e761965fe0d420e060b4fc406022403b3 Mon Sep 17 00:00:00 2001 From: zkDice <156126180+zkdice-xyz@users.noreply.github.com> Date: Sat, 23 Mar 2024 01:24:40 +0530 Subject: [PATCH 03/37] Update ERC4626.cairo --- src/ERC4626.cairo | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ERC4626.cairo b/src/ERC4626.cairo index 864240f..0d0acf7 100644 --- a/src/ERC4626.cairo +++ b/src/ERC4626.cairo @@ -1,5 +1,8 @@ -mod erc4626; -mod interface; +mod erc4626 { + mod erc4626; + mod interface; +} + use erc4626::ERC4626; use interface::{IERC4626, IERC4626Dispatcher, IERC4626DispatcherTrait}; From f61e419463e8f7c595ed1618f1464d42da37b306 Mon Sep 17 00:00:00 2001 From: zkDice <156126180+zkdice-xyz@users.noreply.github.com> Date: Sat, 23 Mar 2024 01:26:15 +0530 Subject: [PATCH 04/37] Update ERC4626.cairo --- src/ERC4626.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ERC4626.cairo b/src/ERC4626.cairo index 0d0acf7..82b66f6 100644 --- a/src/ERC4626.cairo +++ b/src/ERC4626.cairo @@ -3,6 +3,6 @@ mod erc4626 { mod interface; } -use erc4626::ERC4626; +use erc4626::erc4626::ERC4626; use interface::{IERC4626, IERC4626Dispatcher, IERC4626DispatcherTrait}; From 6913ec4eaaa45b9c3578b2df4b49481c61be1857 Mon Sep 17 00:00:00 2001 From: zkDice <156126180+zkdice-xyz@users.noreply.github.com> Date: Sat, 23 Mar 2024 01:27:09 +0530 Subject: [PATCH 05/37] Update ERC4626.cairo --- src/ERC4626.cairo | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ERC4626.cairo b/src/ERC4626.cairo index 82b66f6..906cb7b 100644 --- a/src/ERC4626.cairo +++ b/src/ERC4626.cairo @@ -4,5 +4,4 @@ mod erc4626 { } use erc4626::erc4626::ERC4626; - -use interface::{IERC4626, IERC4626Dispatcher, IERC4626DispatcherTrait}; +use erc4626::interface::{IERC4626, IERC4626Dispatcher, IERC4626DispatcherTrait}; From ebea1f1b5963e37eae320b5be1781dfeab5b054a Mon Sep 17 00:00:00 2001 From: akira Date: Sat, 23 Mar 2024 02:27:11 +0530 Subject: [PATCH 06/37] upgrade to scarb 2.6.3 --- src/ERC4626.cairo | 9 ++------- src/erc4626/erc4626.cairo | 8 ++++---- src/erc4626/interface.cairo | 4 ++-- src/mocks/ERC20.cairo | 5 +++-- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/ERC4626.cairo b/src/ERC4626.cairo index 906cb7b..151f5cd 100644 --- a/src/ERC4626.cairo +++ b/src/ERC4626.cairo @@ -1,7 +1,2 @@ -mod erc4626 { - mod erc4626; - mod interface; -} - -use erc4626::erc4626::ERC4626; -use erc4626::interface::{IERC4626, IERC4626Dispatcher, IERC4626DispatcherTrait}; +mod erc4626; +mod interface; diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 91bf1cc..e2c9163 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,6 +1,6 @@ #[starknet::contract] mod ERC4626 { - use erc4626::erc4626::interface::{ +use erc4626::ERC4626::interface::{ IERC4626, IERC4626Additional, IERC4626Snake, IERC4626Camel, IERC4626Metadata }; use erc4626::utils::{pow_256}; @@ -65,7 +65,7 @@ mod ERC4626 { #[constructor] fn constructor( - ref self: ContractState, asset: ContractAddress, name: felt252, symbol: felt252, offset: u8 + ref self: ContractState, asset: ContractAddress, name: ByteArray, symbol: ByteArray, offset: u8 ) { let dispatcher = ERC20ABIDispatcher { contract_address: asset }; self.offset.write(offset); @@ -179,10 +179,10 @@ mod ERC4626 { #[abi(embed_v0)] impl MetadataEntrypoints of IERC4626Metadata { - fn name(self: @ContractState) -> felt252 { + fn name(self: @ContractState) -> ByteArray { self.erc20.name() } - fn symbol(self: @ContractState) -> felt252 { + fn symbol(self: @ContractState) -> ByteArray { self.erc20.symbol() } fn decimals(self: @ContractState) -> u8 { diff --git a/src/erc4626/interface.cairo b/src/erc4626/interface.cairo index ae77e8a..708c289 100644 --- a/src/erc4626/interface.cairo +++ b/src/erc4626/interface.cairo @@ -64,8 +64,8 @@ trait IERC4626 { #[starknet::interface] trait IERC4626Metadata { - fn name(self: @TState) -> felt252; - fn symbol(self: @TState) -> felt252; + fn name(self: @TState) -> ByteArray; + fn symbol(self: @TState) -> ByteArray; fn decimals(self: @TState) -> u8; } diff --git a/src/mocks/ERC20.cairo b/src/mocks/ERC20.cairo index 4c8dd7c..7e664be 100644 --- a/src/mocks/ERC20.cairo +++ b/src/mocks/ERC20.cairo @@ -44,18 +44,19 @@ mod ERC20Token { #[constructor] fn constructor(ref self: ContractState, recipient: ContractAddress, initial_supply: u256) { - self.erc20.initializer('Mock', 'MCK'); + self.erc20.initializer("Mock", "MCK"); self.erc20._mint(recipient, initial_supply); } #[generate_trait] - #[external(v0)] impl ExternalImpl of ExternalTrait { + #[abi(per_item)] fn burn(ref self: ContractState, value: u256) { let caller = get_caller_address(); self.erc20._burn(caller, value); } + #[abi(per_item)] fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) { self.ownable.assert_only_owner(); self.erc20._mint(recipient, amount); From ff89e21a8bca38bf40e1ae39e6606b79059b200a Mon Sep 17 00:00:00 2001 From: zkDice <156126180+zkdice-xyz@users.noreply.github.com> Date: Sat, 23 Mar 2024 02:29:42 +0530 Subject: [PATCH 07/37] Rename ERC4626.cairo to erc4626.cairo --- src/{ERC4626.cairo => erc4626.cairo} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ERC4626.cairo => erc4626.cairo} (100%) diff --git a/src/ERC4626.cairo b/src/erc4626.cairo similarity index 100% rename from src/ERC4626.cairo rename to src/erc4626.cairo From 8f63aa99e58b28fdef6e05196afb117e614e78da Mon Sep 17 00:00:00 2001 From: akira Date: Sat, 23 Mar 2024 02:31:03 +0530 Subject: [PATCH 08/37] rename --- src/erc4626/erc4626.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index e2c9163..609e434 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,6 +1,6 @@ #[starknet::contract] mod ERC4626 { -use erc4626::ERC4626::interface::{ +use erc4626::erc4626::interface::{ IERC4626, IERC4626Additional, IERC4626Snake, IERC4626Camel, IERC4626Metadata }; use erc4626::utils::{pow_256}; From 380e19f2bd361fd745b6123522e3293c3529d6b9 Mon Sep 17 00:00:00 2001 From: zkDice <156126180+zkdice-xyz@users.noreply.github.com> Date: Sat, 23 Mar 2024 02:31:56 +0530 Subject: [PATCH 09/37] Update lib.cairo --- src/lib.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.cairo b/src/lib.cairo index 345467e..ce442a1 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,4 +1,4 @@ -mod ERC4626; +mod erc4626; #[cfg(test)] mod tests; mod utils; From b715f659f819f86032bedddfa2a47141717bf743 Mon Sep 17 00:00:00 2001 From: akira Date: Sat, 23 Mar 2024 02:53:49 +0530 Subject: [PATCH 10/37] add embeddable --- src/erc4626/erc4626.cairo | 40 ++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 609e434..6e9f261 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,6 +1,6 @@ #[starknet::contract] mod ERC4626 { -use erc4626::erc4626::interface::{ + use erc4626::erc4626::interface::{ IERC4626, IERC4626Additional, IERC4626Snake, IERC4626Camel, IERC4626Metadata }; use erc4626::utils::{pow_256}; @@ -76,21 +76,23 @@ use erc4626::erc4626::interface::{ } - #[abi(embed_v0)] - impl ERC4626Additional of IERC4626Additional { - fn asset(self: @ContractState) -> ContractAddress { + #[embeddable_as(ERC4626AdditionalImpl)] + impl ERC4626Additional< + TContractState, +HasComponent + > of IERC4626Additional> { + fn asset(self: @ComponentState) -> ContractAddress { self.asset.read() } - fn convert_to_assets(self: @ContractState, shares: u256) -> u256 { + fn convert_to_assets(self: @ComponentState, shares: u256) -> u256 { self._convert_to_assets(shares, false) } - fn convert_to_shares(self: @ContractState, assets: u256) -> u256 { + fn convert_to_shares(self: @ComponentState, assets: u256) -> u256 { self._convert_to_shares(assets, false) } - fn deposit(ref self: ContractState, assets: u256, receiver: ContractAddress) -> u256 { + fn deposit(ref self: ComponentState, assets: u256, receiver: ContractAddress) -> u256 { let max_assets = self.max_deposit(receiver); assert(max_assets >= assets, Errors::EXCEEDED_MAX_DEPOSIT); @@ -101,24 +103,24 @@ use erc4626::erc4626::interface::{ shares } - fn max_deposit(self: @ContractState, address: ContractAddress) -> u256 { + fn max_deposit(self: @ComponentState, address: ContractAddress) -> u256 { BoundedU256::max() } - fn max_mint(self: @ContractState, receiver: ContractAddress) -> u256 { + fn max_mint(self: @ComponentState, receiver: ContractAddress) -> u256 { BoundedU256::max() } - fn max_redeem(self: @ContractState, owner: ContractAddress) -> u256 { + fn max_redeem(self: @ComponentState, owner: ContractAddress) -> u256 { self.balance_of(owner) } - fn max_withdraw(self: @ContractState, owner: ContractAddress) -> u256 { + fn max_withdraw(self: @ComponentState, owner: ContractAddress) -> u256 { let balance = self.balance_of(owner); self._convert_to_assets(balance, false) } - fn mint(ref self: ContractState, shares: u256, receiver: ContractAddress) -> u256 { + fn mint(ref self: ComponentState, shares: u256, receiver: ContractAddress) -> u256 { let max_shares = self.max_mint(receiver); assert(max_shares >= shares, Errors::EXCEEDED_MAX_MINT); @@ -129,24 +131,24 @@ use erc4626::erc4626::interface::{ assets } - fn preview_deposit(self: @ContractState, assets: u256) -> u256 { + fn preview_deposit(self: @ComponentState, assets: u256) -> u256 { self._convert_to_shares(assets, false) } - fn preview_mint(self: @ContractState, shares: u256) -> u256 { + fn preview_mint(self: @ComponentState, shares: u256) -> u256 { self._convert_to_assets(shares, true) } - fn preview_redeem(self: @ContractState, shares: u256) -> u256 { + fn preview_redeem(self: @ComponentState, shares: u256) -> u256 { self._convert_to_assets(shares, false) } - fn preview_withdraw(self: @ContractState, assets: u256) -> u256 { + fn preview_withdraw(self: @ComponentState, assets: u256) -> u256 { self._convert_to_shares(assets, true) } fn redeem( - ref self: ContractState, shares: u256, receiver: ContractAddress, owner: ContractAddress + ref self: ComponentState, shares: u256, receiver: ContractAddress, owner: ContractAddress ) -> u256 { let max_shares = self.max_redeem(owner); assert(shares <= max_shares, Errors::EXCEEDED_MAX_REDEEM); @@ -157,13 +159,13 @@ use erc4626::erc4626::interface::{ assets } - fn total_assets(self: @ContractState) -> u256 { + fn total_assets(self: @ComponentState) -> u256 { let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.balance_of(get_contract_address()) } fn withdraw( - ref self: ContractState, assets: u256, receiver: ContractAddress, owner: ContractAddress + ref self: ComponentState, assets: u256, receiver: ContractAddress, owner: ContractAddress ) -> u256 { let max_assets = self.max_withdraw(owner); assert(assets <= max_assets, Errors::EXCEEDED_MAX_WITHDRAW); From d563402e760d107b86a4bab65bf73c177a306110 Mon Sep 17 00:00:00 2001 From: akira Date: Sat, 23 Mar 2024 02:56:46 +0530 Subject: [PATCH 11/37] add embeddable --- src/erc4626/erc4626.cairo | 42 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 6e9f261..6016969 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -179,41 +179,45 @@ mod ERC4626 { } - #[abi(embed_v0)] - impl MetadataEntrypoints of IERC4626Metadata { - fn name(self: @ContractState) -> ByteArray { + #[embeddable_as(MetadataEntrypointsImpl)] + impl MetadataEntrypoints< + TContractState, +HasComponent + > of IERC4626Metadata> { + fn name(self: @ComponentState) -> ByteArray { self.erc20.name() } - fn symbol(self: @ContractState) -> ByteArray { + fn symbol(self: @ComponentState) -> ByteArray { self.erc20.symbol() } - fn decimals(self: @ContractState) -> u8 { + fn decimals(self: @ComponentState) -> u8 { self.underlying_decimals.read() + self._decimals_offset() } } - #[abi(embed_v0)] - impl SnakeEntrypoints of IERC4626Snake { - fn total_supply(self: @ContractState) -> u256 { + #[embeddable_as(SnakeEntrypointsImpl)] + impl SnakeEntrypoints< + TContractState, +HasComponent + > of IERC4626Snake> { + fn total_supply(self: @ComponentState) -> u256 { self.erc20.total_supply() } - fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { + fn balance_of(self: @ComponentState, account: ContractAddress) -> u256 { self.erc20.balance_of(account) } fn allowance( - self: @ContractState, owner: ContractAddress, spender: ContractAddress + self: @ComponentState, owner: ContractAddress, spender: ContractAddress ) -> u256 { self.erc20.allowance(owner, spender) } - fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { + fn transfer(ref self: ComponentState, recipient: ContractAddress, amount: u256) -> bool { self.erc20.transfer(recipient, amount) } fn transfer_from( - ref self: ContractState, + ref self: ComponentState, sender: ContractAddress, recipient: ContractAddress, amount: u256 @@ -221,22 +225,24 @@ mod ERC4626 { self.erc20.transfer_from(sender, recipient, amount) } - fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) -> bool { + fn approve(ref self: ComponentState, spender: ContractAddress, amount: u256) -> bool { self.erc20.approve(spender, amount) } } - #[abi(embed_v0)] - impl CamelEntrypoints of IERC4626Camel { - fn totalSupply(self: @ContractState) -> u256 { + #[embeddable_as(CamelEntrypointsImpl)] + impl CamelEntrypoints< + TContractState, +HasComponent + > of IERC4626Camel> { + fn totalSupply(self: @ComponentState) -> u256 { self.total_supply() } - fn balanceOf(self: @ContractState, account: ContractAddress) -> u256 { + fn balanceOf(self: @ComponentState, account: ContractAddress) -> u256 { self.balance_of(account) } fn transferFrom( - ref self: ContractState, + ref self: ComponentState, sender: ContractAddress, recipient: ContractAddress, amount: u256 From c1551107e0cd3675777d01e17943adf5442cb8cd Mon Sep 17 00:00:00 2001 From: akira Date: Sat, 23 Mar 2024 15:42:15 +0530 Subject: [PATCH 12/37] convert to component --- src/erc4626/erc4626.cairo | 102 ++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 43 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 6016969..01fb9b4 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,8 +1,10 @@ -#[starknet::contract] +#[starknet::component] mod ERC4626 { use erc4626::erc4626::interface::{ - IERC4626, IERC4626Additional, IERC4626Snake, IERC4626Camel, IERC4626Metadata + IERC4626Additional, IERC4626Snake, IERC4626Camel, IERC4626Metadata }; + use openzeppelin::token::erc20::ERC20Component::InternalTrait as ERC20InternalTrait; + use erc4626::utils::{pow_256}; use integer::BoundedU256; use openzeppelin::token::erc20::interface::{ @@ -12,17 +14,11 @@ mod ERC4626 { use starknet::{ContractAddress, get_caller_address, get_contract_address}; - component!(path: ERC20Component, storage: erc20, event: ERC20Event); - impl ERC20InternalImpl = ERC20Component::InternalImpl; - impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl; - #[storage] struct Storage { asset: ContractAddress, underlying_decimals: u8, offset: u8, - #[substorage(v0)] - erc20: ERC20Component::Storage, } #[event] @@ -30,8 +26,6 @@ mod ERC4626 { enum Event { Deposit: Deposit, Withdraw: Withdraw, - #[flat] - ERC20Event: ERC20Component::Event, } #[derive(Drop, starknet::Event)] @@ -63,22 +57,12 @@ mod ERC4626 { const EXCEEDED_MAX_WITHDRAW: felt252 = 'ERC4626: exceeded max withdraw'; } - #[constructor] - fn constructor( - ref self: ContractState, asset: ContractAddress, name: ByteArray, symbol: ByteArray, offset: u8 - ) { - let dispatcher = ERC20ABIDispatcher { contract_address: asset }; - self.offset.write(offset); - let decimals = dispatcher.decimals(); - self.erc20.initializer(name, symbol); - self.asset.write(asset); - self.underlying_decimals.write(decimals); - } - #[embeddable_as(ERC4626AdditionalImpl)] impl ERC4626Additional< - TContractState, +HasComponent + TContractState, +HasComponent, + +ERC20Component::HasComponent, + +Drop > of IERC4626Additional> { fn asset(self: @ComponentState) -> ContractAddress { self.asset.read() @@ -181,13 +165,17 @@ mod ERC4626 { #[embeddable_as(MetadataEntrypointsImpl)] impl MetadataEntrypoints< - TContractState, +HasComponent + TContractState, +HasComponent, + impl erc20: ERC20Component::HasComponent, + +Drop > of IERC4626Metadata> { fn name(self: @ComponentState) -> ByteArray { - self.erc20.name() + let erc20_comp = get_dep_component!(ref self, erc20); + erc20_comp.name() } fn symbol(self: @ComponentState) -> ByteArray { - self.erc20.symbol() + let erc20_comp = get_dep_component!(ref self, erc20); + erc20_comp.symbol() } fn decimals(self: @ComponentState) -> u8 { self.underlying_decimals.read() + self._decimals_offset() @@ -196,24 +184,30 @@ mod ERC4626 { #[embeddable_as(SnakeEntrypointsImpl)] impl SnakeEntrypoints< - TContractState, +HasComponent + TContractState, +HasComponent, + impl erc20: ERC20Component::HasComponent, + +Drop > of IERC4626Snake> { fn total_supply(self: @ComponentState) -> u256 { - self.erc20.total_supply() + let erc20_comp = get_dep_component!(ref self, erc20); + erc20_comp.total_supply() } fn balance_of(self: @ComponentState, account: ContractAddress) -> u256 { - self.erc20.balance_of(account) + let erc20_comp = get_dep_component!(ref self, erc20); + erc20_comp.balance_of(account) } fn allowance( self: @ComponentState, owner: ContractAddress, spender: ContractAddress ) -> u256 { - self.erc20.allowance(owner, spender) + let erc20_comp = get_dep_component!(ref self, erc20); + erc20_comp.allowance(owner, spender) } fn transfer(ref self: ComponentState, recipient: ContractAddress, amount: u256) -> bool { - self.erc20.transfer(recipient, amount) + let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); + erc20_comp_mut.transfer(recipient, amount) } fn transfer_from( @@ -222,17 +216,21 @@ mod ERC4626 { recipient: ContractAddress, amount: u256 ) -> bool { - self.erc20.transfer_from(sender, recipient, amount) + let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); + erc20_comp_mut.transfer_from(sender, recipient, amount) } fn approve(ref self: ComponentState, spender: ContractAddress, amount: u256) -> bool { - self.erc20.approve(spender, amount) + let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); + erc20_comp_mut.approve(spender, amount) } } #[embeddable_as(CamelEntrypointsImpl)] impl CamelEntrypoints< - TContractState, +HasComponent + TContractState, +HasComponent, + +ERC20Component::HasComponent, + +Drop > of IERC4626Camel> { fn totalSupply(self: @ComponentState) -> u256 { self.total_supply() @@ -252,8 +250,24 @@ mod ERC4626 { } #[generate_trait] - impl InternalImpl of InternalImplTrait { - fn _convert_to_assets(self: @ContractState, shares: u256, round: bool) -> u256 { + impl InternalImpl< + TContractState, +HasComponent, + impl erc20: ERC20Component::HasComponent, + +Drop + > of InternalImplTrait { + fn initializer( + ref self: ComponentState, asset: ContractAddress, name: ByteArray, symbol: ByteArray, offset: u8 + ) { + let dispatcher = ERC20ABIDispatcher { contract_address: asset }; + self.offset.write(offset); + let decimals = dispatcher.decimals(); + let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); + erc20_comp_mut.initializer(name, symbol); + self.asset.write(asset); + self.underlying_decimals.write(decimals); + } + + fn _convert_to_assets(self: @ComponentState, shares: u256, round: bool) -> u256 { let total_assets = self.total_assets() + 1; let total_shares = self.total_supply() + pow_256(10, self._decimals_offset()); let assets = shares * total_assets / total_shares; @@ -264,7 +278,7 @@ mod ERC4626 { } } - fn _convert_to_shares(self: @ContractState, assets: u256, round: bool) -> u256 { + fn _convert_to_shares(self: @ComponentState, assets: u256, round: bool) -> u256 { let total_assets = self.total_assets() + 1; let total_shares = self.total_supply() + pow_256(10, self._decimals_offset()); let share = assets * total_shares / total_assets; @@ -276,7 +290,7 @@ mod ERC4626 { } fn _deposit( - ref self: ContractState, + ref self: ComponentState, caller: ContractAddress, receiver: ContractAddress, assets: u256, @@ -284,27 +298,29 @@ mod ERC4626 { ) { let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.transfer_from(caller, get_contract_address(), assets); - self.erc20._mint(receiver, shares); + let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); + erc20_comp_mut._mint(receiver, shares); self.emit(Deposit { sender: caller, owner: receiver, assets, shares }); } fn _withdraw( - ref self: ContractState, + ref self: ComponentState, caller: ContractAddress, receiver: ContractAddress, owner: ContractAddress, assets: u256, shares: u256 ) { + let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); if (caller != owner) { let allowance = self.allowance(owner, caller); if (allowance != BoundedU256::max()) { assert(allowance >= shares, ERC20Errors::APPROVE_FROM_ZERO); - self.erc20.ERC20_allowances.write((owner, caller), allowance - shares); + erc20_comp_mut.ERC20_allowances.write((owner, caller), allowance - shares); } } - self.erc20._burn(owner, shares); + erc20_comp_mut._burn(owner, shares); let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.transfer(receiver, assets); @@ -312,7 +328,7 @@ mod ERC4626 { self.emit(Withdraw { sender: caller, receiver, owner, assets, shares }); } - fn _decimals_offset(self: @ContractState) -> u8 { + fn _decimals_offset(self: @ComponentState) -> u8 { self.offset.read() } } From 4047325d938baa0918b17b3ca3060358f24930c4 Mon Sep 17 00:00:00 2001 From: akira Date: Sat, 23 Mar 2024 15:46:02 +0530 Subject: [PATCH 13/37] add erc20 as impl --- src/erc4626/erc4626.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 01fb9b4..f6e0d85 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -61,7 +61,7 @@ mod ERC4626 { #[embeddable_as(ERC4626AdditionalImpl)] impl ERC4626Additional< TContractState, +HasComponent, - +ERC20Component::HasComponent, + impl erc20: ERC20Component::HasComponent, +Drop > of IERC4626Additional> { fn asset(self: @ComponentState) -> ContractAddress { From 916a8051958da60a97745f95c00b4516c042b978 Mon Sep 17 00:00:00 2001 From: akira Date: Sat, 23 Mar 2024 16:02:52 +0530 Subject: [PATCH 14/37] add eip165 [partially] --- src/erc4626/erc4626.cairo | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index f6e0d85..fd5e051 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,16 +1,20 @@ #[starknet::component] mod ERC4626 { + use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait}; + use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; + use openzeppelin::introspection::src5::SRC5Component::SRC5; + use openzeppelin::introspection::src5::SRC5Component; + use erc4626::erc4626::interface::{ IERC4626Additional, IERC4626Snake, IERC4626Camel, IERC4626Metadata }; - use openzeppelin::token::erc20::ERC20Component::InternalTrait as ERC20InternalTrait; - use erc4626::utils::{pow_256}; use integer::BoundedU256; use openzeppelin::token::erc20::interface::{ IERC20, IERC20Metadata, ERC20ABIDispatcher, ERC20ABIDispatcherTrait }; use openzeppelin::token::erc20::{ERC20Component, ERC20Component::Errors as ERC20Errors}; + use openzeppelin::token::erc20::ERC20Component::InternalTrait as ERC20InternalTrait; use starknet::{ContractAddress, get_caller_address, get_contract_address}; @@ -61,7 +65,8 @@ mod ERC4626 { #[embeddable_as(ERC4626AdditionalImpl)] impl ERC4626Additional< TContractState, +HasComponent, - impl erc20: ERC20Component::HasComponent, + +ERC20Component::HasComponent, + +SRC5Component::HasComponent, +Drop > of IERC4626Additional> { fn asset(self: @ComponentState) -> ContractAddress { @@ -167,6 +172,7 @@ mod ERC4626 { impl MetadataEntrypoints< TContractState, +HasComponent, impl erc20: ERC20Component::HasComponent, + +SRC5Component::HasComponent, +Drop > of IERC4626Metadata> { fn name(self: @ComponentState) -> ByteArray { @@ -186,6 +192,7 @@ mod ERC4626 { impl SnakeEntrypoints< TContractState, +HasComponent, impl erc20: ERC20Component::HasComponent, + +SRC5Component::HasComponent, +Drop > of IERC4626Snake> { fn total_supply(self: @ComponentState) -> u256 { @@ -230,6 +237,7 @@ mod ERC4626 { impl CamelEntrypoints< TContractState, +HasComponent, +ERC20Component::HasComponent, + +SRC5Component::HasComponent, +Drop > of IERC4626Camel> { fn totalSupply(self: @ComponentState) -> u256 { @@ -253,6 +261,7 @@ mod ERC4626 { impl InternalImpl< TContractState, +HasComponent, impl erc20: ERC20Component::HasComponent, + impl src5: SRC5Component::HasComponent, +Drop > of InternalImplTrait { fn initializer( @@ -265,6 +274,11 @@ mod ERC4626 { erc20_comp_mut.initializer(name, symbol); self.asset.write(asset); self.underlying_decimals.write(decimals); + + // ! To register interface + // let mut src5_component = get_dep_component_mut!(ref self, src5); + // src5_component.register_interface(interface::IERC721_ID); + // src5_component.register_interface(interface::IERC721_METADATA_ID); } fn _convert_to_assets(self: @ComponentState, shares: u256, round: bool) -> u256 { From 4e621c6d74a1908ba2557442b020ca03ee1bfa7d Mon Sep 17 00:00:00 2001 From: akira Date: Thu, 28 Mar 2024 00:09:49 +0530 Subject: [PATCH 15/37] upgrade snforge --- Scarb.toml | 2 +- src/tests/erc4626/test_erc4626.cairo | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 4f4d5f3..a7ac6f3 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -4,7 +4,7 @@ version = "0.1.0" [dependencies] openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git"} -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.14.0" } +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } starknet = "2.4.3" [lib] diff --git a/src/tests/erc4626/test_erc4626.cairo b/src/tests/erc4626/test_erc4626.cairo index 8aa5a6f..52b6e90 100644 --- a/src/tests/erc4626/test_erc4626.cairo +++ b/src/tests/erc4626/test_erc4626.cairo @@ -1,6 +1,6 @@ use core::traits::TryInto; use debug::PrintTrait; -use erc4626::erc4626::{IERC4626Dispatcher, IERC4626DispatcherTrait}; +use erc4626::erc4626::interface::{IERC4626Dispatcher, IERC4626DispatcherTrait}; use erc4626::utils::{pow_256}; use integer::BoundedU256; use openzeppelin::token::erc20::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; @@ -34,7 +34,7 @@ fn VAULT_ADDRESS() -> ContractAddress { } fn deploy_token() -> (ERC20ABIDispatcher, ContractAddress) { - let token = declare('ERC20Token'); + let token = declare("ERC20Token"); let mut calldata = Default::default(); Serde::serialize(@OWNER(), ref calldata); Serde::serialize(@INITIAL_SUPPLY(), ref calldata); @@ -51,7 +51,7 @@ fn deploy_contract() -> (ERC20ABIDispatcher, IERC4626Dispatcher) { params.append('Vault Mock Token'); params.append('vltMCK'); params.append(8); - let vault = declare('ERC4626'); + let vault = declare("ERC4626"); let contract_address = vault.deploy_at(@params, VAULT_ADDRESS()).unwrap(); (token, IERC4626Dispatcher { contract_address }) } From d85b3dd726d96b178117fa9d4e5d9882ccaa7260 Mon Sep 17 00:00:00 2001 From: akira Date: Fri, 29 Mar 2024 13:51:21 +0530 Subject: [PATCH 16/37] add preset and fix tests --- Scarb.toml | 2 +- src/erc4626/erc4626.cairo | 2 +- src/erc4626/interface.cairo | 4 +- src/lib.cairo | 4 ++ src/preset/ERC4626.cairo | 57 +++++++++++++++++++++++ src/tests/erc4626/test_erc4626.cairo | 69 +++++++++++++++------------- 6 files changed, 101 insertions(+), 37 deletions(-) create mode 100644 src/preset/ERC4626.cairo diff --git a/Scarb.toml b/Scarb.toml index a7ac6f3..4ffbf73 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git"} +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.10.0"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } starknet = "2.4.3" diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index fd5e051..26ad47d 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,5 +1,5 @@ #[starknet::component] -mod ERC4626 { +mod ERC4626Component { use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait}; use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; use openzeppelin::introspection::src5::SRC5Component::SRC5; diff --git a/src/erc4626/interface.cairo b/src/erc4626/interface.cairo index 708c289..e7481de 100644 --- a/src/erc4626/interface.cairo +++ b/src/erc4626/interface.cairo @@ -5,8 +5,8 @@ trait IERC4626 { // ************************************ // * Metadata // ************************************ - fn name(self: @TState) -> felt252; - fn symbol(self: @TState) -> felt252; + fn name(self: @TState) -> ByteArray; + fn symbol(self: @TState) -> ByteArray; fn decimals(self: @TState) -> u8; // ************************************ diff --git a/src/lib.cairo b/src/lib.cairo index ce442a1..2ea5fb3 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,4 +1,8 @@ mod erc4626; +mod preset { + mod ERC4626; +} + #[cfg(test)] mod tests; mod utils; diff --git a/src/preset/ERC4626.cairo b/src/preset/ERC4626.cairo new file mode 100644 index 0000000..b80ba69 --- /dev/null +++ b/src/preset/ERC4626.cairo @@ -0,0 +1,57 @@ +#[starknet::contract] +mod ERC4626 { + use erc4626::erc4626::erc4626::{ERC4626Component}; + use openzeppelin::introspection::src5::SRC5Component; + use openzeppelin::token::erc20::ERC20Component; + + component!(path: ERC4626Component, storage: erc4626, event: ERC4626Event); + component!(path: ERC20Component, storage: erc20, event: ERC20Event); + component!(path: SRC5Component, storage: src5, event: SRC5Event); + + use starknet::{ContractAddress}; + use openzeppelin::token::erc20::interface::{IERC20, IERC20Dispatcher, IERC20DispatcherTrait}; + use starknet::{get_contract_address}; + + #[abi(embed_v0)] + impl ERC4626AdditionalImpl = ERC4626Component::ERC4626AdditionalImpl; + #[abi(embed_v0)] + impl MetadataEntrypointsImpl = ERC4626Component::MetadataEntrypointsImpl; + #[abi(embed_v0)] + impl SnakeEntrypointsImpl = ERC4626Component::SnakeEntrypointsImpl; + #[abi(embed_v0)] + impl CamelEntrypointsImpl = ERC4626Component::CamelEntrypointsImpl; + + impl ERC4626InternalImpl = ERC4626Component::InternalImpl; + + #[storage] + struct Storage { + #[substorage(v0)] + erc4626: ERC4626Component::Storage, + #[substorage(v0)] + erc20: ERC20Component::Storage, + #[substorage(v0)] + src5: SRC5Component::Storage, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + ERC4626Event: ERC4626Component::Event, + #[flat] + ERC20Event: ERC20Component::Event, + #[flat] + SRC5Event: SRC5Component::Event, + } + + #[constructor] + fn constructor( + ref self: ContractState, + asset: ContractAddress, + name: ByteArray, + symbol: ByteArray, + offset: u8, + ) { + self.erc4626.initializer(asset, name, symbol, offset); + } +} \ No newline at end of file diff --git a/src/tests/erc4626/test_erc4626.cairo b/src/tests/erc4626/test_erc4626.cairo index 52b6e90..69b049e 100644 --- a/src/tests/erc4626/test_erc4626.cairo +++ b/src/tests/erc4626/test_erc4626.cairo @@ -7,6 +7,7 @@ use openzeppelin::token::erc20::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; use snforge_std::{ declare, ContractClassTrait, start_prank, stop_prank, CheatTarget, start_warp, stop_warp }; +use openzeppelin::utils::serde::SerializedAppend; use starknet::{ContractAddress, contract_address_const, get_contract_address}; fn OWNER() -> ContractAddress { @@ -46,13 +47,15 @@ fn deploy_token() -> (ERC20ABIDispatcher, ContractAddress) { fn deploy_contract() -> (ERC20ABIDispatcher, IERC4626Dispatcher) { let (token, token_address) = deploy_token(); - let mut params = ArrayTrait::::new(); - token_address.serialize(ref params); - params.append('Vault Mock Token'); - params.append('vltMCK'); - params.append(8); + let mut calldata = array![]; + let name: ByteArray = "Vault Mock Token"; + let symbol: ByteArray = "vltMCK"; + calldata.append_serde(token_address); + calldata.append_serde(name); + calldata.append_serde(symbol); + calldata.append(0); let vault = declare("ERC4626"); - let contract_address = vault.deploy_at(@params, VAULT_ADDRESS()).unwrap(); + let contract_address = vault.deploy_at(@calldata, VAULT_ADDRESS()).unwrap(); (token, IERC4626Dispatcher { contract_address }) } @@ -61,60 +64,60 @@ fn deploy_contract() -> (ERC20ABIDispatcher, IERC4626Dispatcher) { fn test_constructor() { let (asset, vault) = deploy_contract(); assert(vault.asset() == asset.contract_address, 'invalid asset'); - assert(vault.decimals() == (18 + 8), 'invalid decimals'); - assert(vault.name() == 'Vault Mock Token', 'invalid name'); - assert(vault.symbol() == 'vltMCK', 'invalid symbol'); + assert(vault.decimals() == (18 + 0), 'invalid decimals'); + assert(vault.name() == "Vault Mock Token", 'invalid name'); + assert(vault.symbol() == "vltMCK", 'invalid symbol'); } #[test] fn convert_to_assets() { - let (asset, vault) = deploy_contract(); - let shares = pow_256(10, 10); + let (_asset, vault) = deploy_contract(); + let shares = pow_256(10, 2); // 10e10 * (0 + 1) / (0 + 10e8) assert(vault.convert_to_assets(shares) == 100, 'invalid assets'); } #[test] fn convert_to_shares() { - let (asset, vault) = deploy_contract(); + let (_asset, vault) = deploy_contract(); let assets = 10; // asset * shares / total assets // 10 * (0 + 10e8) / (0 + 1) - assert(vault.convert_to_shares(assets) == pow_256(10, 9), 'invalid shares'); + assert(vault.convert_to_shares(assets) == pow_256(10, 1), 'invalid shares'); } #[test] fn max_deposit() { - let (asset, vault) = deploy_contract(); + let (_asset, vault) = deploy_contract(); assert(vault.max_deposit(get_contract_address()) == BoundedU256::max(), 'invalid max deposit'); } #[test] fn max_mint() { - let (asset, vault) = deploy_contract(); + let (_asset, vault) = deploy_contract(); assert(vault.max_mint(get_contract_address()) == BoundedU256::max(), 'invalid max mint'); } #[test] fn preview_deposit() { - let (asset, vault) = deploy_contract(); - assert(vault.preview_deposit(10) == pow_256(10, 9), 'invalid preview_deposit'); + let (_asset, vault) = deploy_contract(); + assert(vault.preview_deposit(10) == pow_256(10, 1), 'invalid preview_deposit'); } #[test] fn preview_mint() { - let (asset, vault) = deploy_contract(); - assert(vault.preview_mint(pow_256(10, 10)) == 100, 'invalid preview_mint'); + let (_asset, vault) = deploy_contract(); + assert(vault.preview_mint(pow_256(10, 2)) == 100, 'invalid preview_mint'); } #[test] fn preview_redeem() { - let (asset, vault) = deploy_contract(); - assert(vault.preview_redeem(pow_256(10, 10)) == 100, 'invalid preview_redeem'); + let (_asset, vault) = deploy_contract(); + assert(vault.preview_redeem(pow_256(10, 2)) == 100, 'invalid preview_redeem'); } #[test] fn preview_withdraw() { - let (asset, vault) = deploy_contract(); - assert(vault.preview_redeem(pow_256(10, 10)) == 100, 'invalid preview_withdraw'); + let (_asset, vault) = deploy_contract(); + assert(vault.preview_redeem(pow_256(10, 2)) == 100, 'invalid preview_withdraw'); } #[test] fn test_deposit() { @@ -136,7 +139,7 @@ fn test_max_redeem() { start_prank(CheatTarget::One(asset.contract_address), OWNER()); asset.approve(vault.contract_address, amount); stop_prank(CheatTarget::One(asset.contract_address)); - let result = vault.preview_deposit(amount); + let _result = vault.preview_deposit(amount); start_prank(CheatTarget::One(vault.contract_address), OWNER()); let shares = vault.deposit(amount, OWNER()); assert(vault.max_redeem(OWNER()) == shares, 'invalid max redeem'); @@ -148,9 +151,9 @@ fn max_withdraw() { start_prank(CheatTarget::One(asset.contract_address), OWNER()); asset.approve(vault.contract_address, amount); stop_prank(CheatTarget::One(asset.contract_address)); - let result = vault.preview_deposit(amount); + let _result = vault.preview_deposit(amount); start_prank(CheatTarget::One(vault.contract_address), OWNER()); - let shares = vault.deposit(amount, OWNER()); + let _shares = vault.deposit(amount, OWNER()); let value = vault.convert_to_assets(vault.balanceOf(OWNER())); assert(vault.max_withdraw(OWNER()) == value, 'invalid max withdraw'); } @@ -161,10 +164,10 @@ fn mint() { start_prank(CheatTarget::One(asset.contract_address), OWNER()); asset.approve(vault.contract_address, amount); stop_prank(CheatTarget::One(asset.contract_address)); - let result = vault.preview_deposit(amount); + let _result = vault.preview_deposit(amount); let minted = vault.preview_mint(1); start_prank(CheatTarget::One(vault.contract_address), OWNER()); - let shares = vault.mint(1, OWNER()); + let _shares = vault.mint(1, OWNER()); assert(vault.balanceOf(OWNER()) == minted, 'invalid mint shares'); } #[test] @@ -174,13 +177,13 @@ fn test_redeem() { start_prank(CheatTarget::One(asset.contract_address), OWNER()); asset.approve(vault.contract_address, amount); stop_prank(CheatTarget::One(asset.contract_address)); - let result = vault.preview_deposit(amount); + let _result = vault.preview_deposit(amount); start_prank(CheatTarget::One(vault.contract_address), OWNER()); let shares = vault.deposit(amount, OWNER()); assert(vault.balanceOf(OWNER()) == shares, 'invalid balance before'); - let preview = vault.preview_redeem(shares); + let _preview = vault.preview_redeem(shares); start_prank(CheatTarget::One(vault.contract_address), OWNER()); - let redeemed = vault.redeem(shares, OWNER(), OWNER()); + let _redeemed = vault.redeem(shares, OWNER(), OWNER()); assert(vault.balanceOf(OWNER()) == 0, 'invalid balance after'); } @@ -191,13 +194,13 @@ fn test_withdraw() { start_prank(CheatTarget::One(asset.contract_address), OWNER()); asset.approve(vault.contract_address, amount); stop_prank(CheatTarget::One(asset.contract_address)); - let result = vault.preview_deposit(amount); + let _result = vault.preview_deposit(amount); start_prank(CheatTarget::One(vault.contract_address), OWNER()); let shares = vault.deposit(amount, OWNER()); assert(vault.balanceOf(OWNER()) == shares, 'invalid balance before'); start_prank(CheatTarget::One(vault.contract_address), OWNER()); - let shares = vault.withdraw(amount, OWNER(), OWNER()); + let _shares = vault.withdraw(amount, OWNER(), OWNER()); assert(vault.balanceOf(OWNER()) == 0, 'invalid balance after'); } From a077a1c7cf6f3bc352400ad9c996f0b288709cef Mon Sep 17 00:00:00 2001 From: akira Date: Fri, 29 Mar 2024 19:30:45 +0530 Subject: [PATCH 17/37] use camel case --- src/erc4626/erc4626.cairo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 26ad47d..dd3dde8 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -150,7 +150,7 @@ mod ERC4626Component { fn total_assets(self: @ComponentState) -> u256 { let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; - dispatcher.balance_of(get_contract_address()) + dispatcher.balanceOf(get_contract_address()) } fn withdraw( @@ -311,7 +311,7 @@ mod ERC4626Component { shares: u256 ) { let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; - dispatcher.transfer_from(caller, get_contract_address(), assets); + dispatcher.transferFrom(caller, get_contract_address(), assets); let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); erc20_comp_mut._mint(receiver, shares); self.emit(Deposit { sender: caller, owner: receiver, assets, shares }); From 658e66a25bfd3395f1c452ea623c2a12ac464321 Mon Sep 17 00:00:00 2001 From: Akira <156126180+akiraonstarknet@users.noreply.github.com> Date: Thu, 4 Apr 2024 20:37:17 +0530 Subject: [PATCH 18/37] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 00e0f90..9dd63f5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -# ERC4626 inflation attack free +# Cairo ERC4626 Component [inflation attack free] -An implementation of ERC4626 in Cairo. +An implementation of ERC4626 Component in Cairo. Forked from https://github.com/0xEniotna/ERC4626. Below is the original readme. +-------- I used the [OZ solidity](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol#L239) implementation. It is itself inspired from YieldBox codebase that has an inflation attack protection. Shares are virtually minted which reduces the issue. From bfcc34486ad7b0cd718f4a6edd69a6e799a7f39d Mon Sep 17 00:00:00 2001 From: akira Date: Sun, 19 May 2024 20:17:01 +0530 Subject: [PATCH 19/37] upgrade to cairo contracts 0.12 --- Scarb.toml | 4 ++-- src/erc4626/erc4626.cairo | 8 ++++++-- src/mocks/ERC20.cairo | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 4ffbf73..1976773 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,9 +3,9 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.10.0"} +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.12.0"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } -starknet = "2.4.3" +starknet = "2.6.3" [lib] diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index dd3dde8..c1b64a8 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -11,9 +11,13 @@ mod ERC4626Component { use erc4626::utils::{pow_256}; use integer::BoundedU256; use openzeppelin::token::erc20::interface::{ - IERC20, IERC20Metadata, ERC20ABIDispatcher, ERC20ABIDispatcherTrait + IERC20, IERC20Metadata, ERC20ABIDispatcher, ERC20ABIDispatcherTrait, + }; + use openzeppelin::token::erc20::{ + ERC20Component, + ERC20HooksEmptyImpl, + ERC20Component::Errors as ERC20Errors }; - use openzeppelin::token::erc20::{ERC20Component, ERC20Component::Errors as ERC20Errors}; use openzeppelin::token::erc20::ERC20Component::InternalTrait as ERC20InternalTrait; use starknet::{ContractAddress, get_caller_address, get_contract_address}; diff --git a/src/mocks/ERC20.cairo b/src/mocks/ERC20.cairo index 7e664be..2a44b80 100644 --- a/src/mocks/ERC20.cairo +++ b/src/mocks/ERC20.cairo @@ -3,7 +3,7 @@ #[starknet::contract] mod ERC20Token { use openzeppelin::access::ownable::OwnableComponent; - use openzeppelin::token::erc20::ERC20Component; + use openzeppelin::token::erc20::{ERC20Component, ERC20HooksEmptyImpl}; use starknet::ContractAddress; use starknet::get_caller_address; From 898b47fab48b4329e8713ec3991edfef2ade25e8 Mon Sep 17 00:00:00 2001 From: akira Date: Sun, 19 May 2024 20:21:52 +0530 Subject: [PATCH 20/37] upgrade to cairo contracts main --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index 1976773..a493264 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.12.0"} +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", branch = "main"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } starknet = "2.6.3" From f5c0094699d993731e16a6776755f4a0e1a9d8b9 Mon Sep 17 00:00:00 2001 From: Akira <156126180+akiraonstarknet@users.noreply.github.com> Date: Thu, 4 Jul 2024 12:42:04 +0200 Subject: [PATCH 21/37] update to starknet 2.6.4 --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index a493264..8e20a16 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -5,7 +5,7 @@ version = "0.1.0" [dependencies] openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", branch = "main"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } -starknet = "2.6.3" +starknet = "2.6.4" [lib] From 3efdd7da97a7c6d423f59f368c1e1d687af74a7c Mon Sep 17 00:00:00 2001 From: Akira <156126180+akiraonstarknet@users.noreply.github.com> Date: Thu, 4 Jul 2024 12:46:01 +0200 Subject: [PATCH 22/37] Update Scarb.toml --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index 8e20a16..a493264 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -5,7 +5,7 @@ version = "0.1.0" [dependencies] openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", branch = "main"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } -starknet = "2.6.4" +starknet = "2.6.3" [lib] From 1469f8507723e186cb3ed912b8ce0c3aabc83058 Mon Sep 17 00:00:00 2001 From: Akira <156126180+akiraonstarknet@users.noreply.github.com> Date: Thu, 4 Jul 2024 12:47:35 +0200 Subject: [PATCH 23/37] Update Scarb.toml --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index a493264..030a0d1 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", branch = "main"} +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", ref = "v0.13.0"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } starknet = "2.6.3" From 781a52b1fcf0d5e2d2364d2c9dbbb008f854a2dc Mon Sep 17 00:00:00 2001 From: Akira <156126180+akiraonstarknet@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:30:43 +0200 Subject: [PATCH 24/37] Update Scarb.toml --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index 030a0d1..cb365a6 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -5,7 +5,7 @@ version = "0.1.0" [dependencies] openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", ref = "v0.13.0"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } -starknet = "2.6.3" +starknet = ">=2.5.4" [lib] From b8d54162382c39c839c90cad507e7d45308fef76 Mon Sep 17 00:00:00 2001 From: Akira <156126180+akiraonstarknet@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:48:20 +0200 Subject: [PATCH 25/37] Update Scarb.toml --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index cb365a6..bd9d1f7 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", ref = "v0.13.0"} +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", rev = "v0.13.0"} snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } starknet = ">=2.5.4" From b032201546487497c2aea5db5a7c49e7323f03ce Mon Sep 17 00:00:00 2001 From: ariyan-hashstack Date: Thu, 29 Aug 2024 17:40:50 +0530 Subject: [PATCH 26/37] added before_deposit Hook --- src/erc4626/erc4626.cairo | 35 +++++++++++++++++++++++++++++++---- src/erc4626/interface.cairo | 6 +++--- src/preset/ERC4626.cairo | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index c1b64a8..9080948 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -65,12 +65,24 @@ mod ERC4626Component { const EXCEEDED_MAX_WITHDRAW: felt252 = 'ERC4626: exceeded max withdraw'; } + pub trait ERC4626HooksTrait { + fn before_deposit( + ref self: ComponentState, + liquidity: u256, + min_liquidity: u256, + ); + + // fn before_withdraw( + // ref self: ComponentState, + // ) {} + } #[embeddable_as(ERC4626AdditionalImpl)] impl ERC4626Additional< TContractState, +HasComponent, +ERC20Component::HasComponent, +SRC5Component::HasComponent, + +ERC4626HooksTrait, +Drop > of IERC4626Additional> { fn asset(self: @ComponentState) -> ContractAddress { @@ -85,13 +97,13 @@ mod ERC4626Component { self._convert_to_shares(assets, false) } - fn deposit(ref self: ComponentState, assets: u256, receiver: ContractAddress) -> u256 { + fn deposit(ref self: ComponentState, assets: u256, min_liquidity: u256, receiver: ContractAddress) -> u256 { let max_assets = self.max_deposit(receiver); assert(max_assets >= assets, Errors::EXCEEDED_MAX_DEPOSIT); let caller = get_caller_address(); let shares = self.preview_deposit(assets); - self._deposit(caller, receiver, assets, shares); + self._deposit(caller, receiver, assets, min_liquidity, shares); shares } @@ -113,13 +125,13 @@ mod ERC4626Component { self._convert_to_assets(balance, false) } - fn mint(ref self: ComponentState, shares: u256, receiver: ContractAddress) -> u256 { + fn mint(ref self: ComponentState, shares: u256, min_liquidity: u256, receiver: ContractAddress) -> u256 { let max_shares = self.max_mint(receiver); assert(max_shares >= shares, Errors::EXCEEDED_MAX_MINT); let caller = get_caller_address(); let assets = self.preview_mint(shares); - self._deposit(caller, receiver, assets, shares); + self._deposit(caller, receiver, assets, min_liquidity, shares); assets } @@ -177,6 +189,7 @@ mod ERC4626Component { TContractState, +HasComponent, impl erc20: ERC20Component::HasComponent, +SRC5Component::HasComponent, + +ERC4626HooksTrait, +Drop > of IERC4626Metadata> { fn name(self: @ComponentState) -> ByteArray { @@ -197,6 +210,7 @@ mod ERC4626Component { TContractState, +HasComponent, impl erc20: ERC20Component::HasComponent, +SRC5Component::HasComponent, + +ERC4626HooksTrait, +Drop > of IERC4626Snake> { fn total_supply(self: @ComponentState) -> u256 { @@ -242,6 +256,7 @@ mod ERC4626Component { TContractState, +HasComponent, +ERC20Component::HasComponent, +SRC5Component::HasComponent, + +ERC4626HooksTrait, +Drop > of IERC4626Camel> { fn totalSupply(self: @ComponentState) -> u256 { @@ -266,6 +281,7 @@ mod ERC4626Component { TContractState, +HasComponent, impl erc20: ERC20Component::HasComponent, impl src5: SRC5Component::HasComponent, + impl Hooks: ERC4626HooksTrait, +Drop > of InternalImplTrait { fn initializer( @@ -312,8 +328,11 @@ mod ERC4626Component { caller: ContractAddress, receiver: ContractAddress, assets: u256, + min_liquidity: u256, shares: u256 ) { + Hooks::before_deposit(ref self, assets, min_liquidity); + let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.transferFrom(caller, get_contract_address(), assets); let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); @@ -351,3 +370,11 @@ mod ERC4626Component { } } } + +impl ERC4626HooksEmptyImpl of ERC4626Component::ERC4626HooksTrait { + fn before_deposit( + ref self: ERC4626Component::ComponentState, + liquidity: u256, + min_liquidity: u256, + ) {} +} \ No newline at end of file diff --git a/src/erc4626/interface.cairo b/src/erc4626/interface.cairo index e7481de..41c5a38 100644 --- a/src/erc4626/interface.cairo +++ b/src/erc4626/interface.cairo @@ -36,7 +36,7 @@ trait IERC4626 { fn asset(self: @TState) -> starknet::ContractAddress; fn convert_to_assets(self: @TState, shares: u256) -> u256; fn convert_to_shares(self: @TState, assets: u256) -> u256; - fn deposit(ref self: TState, assets: u256, receiver: starknet::ContractAddress) -> u256; + fn deposit(ref self: TState, assets: u256, min_liquidity: u256, receiver: starknet::ContractAddress) -> u256; fn max_deposit(self: @TState, address: starknet::ContractAddress) -> u256; fn max_mint(self: @TState, receiver: starknet::ContractAddress) -> u256; fn max_redeem(self: @TState, owner: starknet::ContractAddress) -> u256; @@ -95,12 +95,12 @@ trait IERC4626Additional { fn asset(self: @TState) -> ContractAddress; fn convert_to_assets(self: @TState, shares: u256) -> u256; fn convert_to_shares(self: @TState, assets: u256) -> u256; - fn deposit(ref self: TState, assets: u256, receiver: ContractAddress) -> u256; + fn deposit(ref self: TState, assets: u256, min_liquidity: u256, receiver: ContractAddress) -> u256; fn max_deposit(self: @TState, address: ContractAddress) -> u256; fn max_mint(self: @TState, receiver: ContractAddress) -> u256; fn max_redeem(self: @TState, owner: ContractAddress) -> u256; fn max_withdraw(self: @TState, owner: ContractAddress) -> u256; - fn mint(ref self: TState, shares: u256, receiver: ContractAddress) -> u256; + fn mint(ref self: TState, shares: u256, min_liquidity: u256, receiver: ContractAddress) -> u256; fn preview_deposit(self: @TState, assets: u256) -> u256; fn preview_mint(self: @TState, shares: u256) -> u256; fn preview_redeem(self: @TState, shares: u256) -> u256; diff --git a/src/preset/ERC4626.cairo b/src/preset/ERC4626.cairo index b80ba69..eebfb82 100644 --- a/src/preset/ERC4626.cairo +++ b/src/preset/ERC4626.cairo @@ -1,6 +1,6 @@ #[starknet::contract] mod ERC4626 { - use erc4626::erc4626::erc4626::{ERC4626Component}; + use erc4626::erc4626::erc4626::{ERC4626Component, ERC4626HooksEmptyImpl}; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::token::erc20::ERC20Component; From ef7656c29ad548496813fb44cc93b38de8ddf357 Mon Sep 17 00:00:00 2001 From: ariyan-hashstack Date: Fri, 30 Aug 2024 21:21:34 +0530 Subject: [PATCH 27/37] [erc4626] refactored deposit flow --- src/erc4626/erc4626.cairo | 13 +++++-------- src/erc4626/interface.cairo | 4 ++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 9080948..40d19b6 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -69,7 +69,6 @@ mod ERC4626Component { fn before_deposit( ref self: ComponentState, liquidity: u256, - min_liquidity: u256, ); // fn before_withdraw( @@ -97,13 +96,13 @@ mod ERC4626Component { self._convert_to_shares(assets, false) } - fn deposit(ref self: ComponentState, assets: u256, min_liquidity: u256, receiver: ContractAddress) -> u256 { + fn deposit(ref self: ComponentState, assets: u256, receiver: ContractAddress) -> u256 { let max_assets = self.max_deposit(receiver); assert(max_assets >= assets, Errors::EXCEEDED_MAX_DEPOSIT); let caller = get_caller_address(); let shares = self.preview_deposit(assets); - self._deposit(caller, receiver, assets, min_liquidity, shares); + self._deposit(caller, receiver, assets, shares); shares } @@ -125,13 +124,13 @@ mod ERC4626Component { self._convert_to_assets(balance, false) } - fn mint(ref self: ComponentState, shares: u256, min_liquidity: u256, receiver: ContractAddress) -> u256 { + fn mint(ref self: ComponentState, shares: u256, receiver: ContractAddress) -> u256 { let max_shares = self.max_mint(receiver); assert(max_shares >= shares, Errors::EXCEEDED_MAX_MINT); let caller = get_caller_address(); let assets = self.preview_mint(shares); - self._deposit(caller, receiver, assets, min_liquidity, shares); + self._deposit(caller, receiver, assets, shares); assets } @@ -328,10 +327,9 @@ mod ERC4626Component { caller: ContractAddress, receiver: ContractAddress, assets: u256, - min_liquidity: u256, shares: u256 ) { - Hooks::before_deposit(ref self, assets, min_liquidity); + Hooks::before_deposit(ref self, assets); let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.transferFrom(caller, get_contract_address(), assets); @@ -375,6 +373,5 @@ impl ERC4626HooksEmptyImpl of ERC4626Component::ERC4626HooksTrai fn before_deposit( ref self: ERC4626Component::ComponentState, liquidity: u256, - min_liquidity: u256, ) {} } \ No newline at end of file diff --git a/src/erc4626/interface.cairo b/src/erc4626/interface.cairo index 41c5a38..f2afe43 100644 --- a/src/erc4626/interface.cairo +++ b/src/erc4626/interface.cairo @@ -95,12 +95,12 @@ trait IERC4626Additional { fn asset(self: @TState) -> ContractAddress; fn convert_to_assets(self: @TState, shares: u256) -> u256; fn convert_to_shares(self: @TState, assets: u256) -> u256; - fn deposit(ref self: TState, assets: u256, min_liquidity: u256, receiver: ContractAddress) -> u256; + fn deposit(ref self: TState, assets: u256, receiver: ContractAddress) -> u256; fn max_deposit(self: @TState, address: ContractAddress) -> u256; fn max_mint(self: @TState, receiver: ContractAddress) -> u256; fn max_redeem(self: @TState, owner: ContractAddress) -> u256; fn max_withdraw(self: @TState, owner: ContractAddress) -> u256; - fn mint(ref self: TState, shares: u256, min_liquidity: u256, receiver: ContractAddress) -> u256; + fn mint(ref self: TState, shares: u256, receiver: ContractAddress) -> u256; fn preview_deposit(self: @TState, assets: u256) -> u256; fn preview_mint(self: @TState, shares: u256) -> u256; fn preview_redeem(self: @TState, shares: u256) -> u256; From b49ee9081cb63c80627832ba3b6dbacf47ddbc7e Mon Sep 17 00:00:00 2001 From: ariyan-hashstack Date: Mon, 2 Sep 2024 14:18:29 +0530 Subject: [PATCH 28/37] [erc4626] added withdraw Hooks, refac --- src/erc4626/erc4626.cairo | 71 +++++++++++++++++++++++++++++++++---- src/erc4626/interface.cairo | 2 +- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 40d19b6..dfef397 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,3 +1,5 @@ +use starknet::ContractAddress; + #[starknet::component] mod ERC4626Component { use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait}; @@ -68,12 +70,34 @@ mod ERC4626Component { pub trait ERC4626HooksTrait { fn before_deposit( ref self: ComponentState, - liquidity: u256, + caller: ContractAddress, + receiver: ContractAddress, + assets: u256, + shares: u256, + ); + fn after_deposit( + ref self: ComponentState, + caller: ContractAddress, + receiver: ContractAddress, + assets: u256, + shares: u256, + ); + fn before_withdraw( + ref self: ComponentState, + caller: ContractAddress, + receiver: ContractAddress, + owner: ContractAddress, + assets: u256, + shares: u256 + ); + fn after_withdraw( + ref self: ComponentState, + caller: ContractAddress, + receiver: ContractAddress, + owner: ContractAddress, + assets: u256, + shares: u256 ); - - // fn before_withdraw( - // ref self: ComponentState, - // ) {} } #[embeddable_as(ERC4626AdditionalImpl)] @@ -329,13 +353,15 @@ mod ERC4626Component { assets: u256, shares: u256 ) { - Hooks::before_deposit(ref self, assets); + Hooks::before_deposit(ref self, caller, receiver, assets, shares); let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.transferFrom(caller, get_contract_address(), assets); let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); erc20_comp_mut._mint(receiver, shares); self.emit(Deposit { sender: caller, owner: receiver, assets, shares }); + + Hooks::after_deposit(ref self, caller, receiver, assets, shares); } fn _withdraw( @@ -346,6 +372,8 @@ mod ERC4626Component { assets: u256, shares: u256 ) { + Hooks::before_withdraw(ref self, caller, receiver, owner, assets, shares); + let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); if (caller != owner) { let allowance = self.allowance(owner, caller); @@ -361,6 +389,8 @@ mod ERC4626Component { dispatcher.transfer(receiver, assets); self.emit(Withdraw { sender: caller, receiver, owner, assets, shares }); + + Hooks::after_withdraw(ref self, caller, receiver, owner, assets, shares); } fn _decimals_offset(self: @ComponentState) -> u8 { @@ -372,6 +402,33 @@ mod ERC4626Component { impl ERC4626HooksEmptyImpl of ERC4626Component::ERC4626HooksTrait { fn before_deposit( ref self: ERC4626Component::ComponentState, - liquidity: u256, + caller: ContractAddress, + receiver: ContractAddress, + assets: u256, + shares: u256 + ) {} + fn after_deposit( + ref self: ERC4626Component::ComponentState, + caller: ContractAddress, + receiver: ContractAddress, + assets: u256, + shares: u256 + ) {} + + fn before_withdraw( + ref self: ERC4626Component::ComponentState, + caller: ContractAddress, + receiver: ContractAddress, + owner: ContractAddress, + assets: u256, + shares: u256 + ) {} + fn after_withdraw( + ref self: ERC4626Component::ComponentState, + caller: ContractAddress, + receiver: ContractAddress, + owner: ContractAddress, + assets: u256, + shares: u256 ) {} } \ No newline at end of file diff --git a/src/erc4626/interface.cairo b/src/erc4626/interface.cairo index f2afe43..e7481de 100644 --- a/src/erc4626/interface.cairo +++ b/src/erc4626/interface.cairo @@ -36,7 +36,7 @@ trait IERC4626 { fn asset(self: @TState) -> starknet::ContractAddress; fn convert_to_assets(self: @TState, shares: u256) -> u256; fn convert_to_shares(self: @TState, assets: u256) -> u256; - fn deposit(ref self: TState, assets: u256, min_liquidity: u256, receiver: starknet::ContractAddress) -> u256; + fn deposit(ref self: TState, assets: u256, receiver: starknet::ContractAddress) -> u256; fn max_deposit(self: @TState, address: starknet::ContractAddress) -> u256; fn max_mint(self: @TState, receiver: starknet::ContractAddress) -> u256; fn max_redeem(self: @TState, owner: starknet::ContractAddress) -> u256; From 8625a34e9d7d64aaaf50332750a54354bb03807c Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Thu, 24 Oct 2024 10:48:11 +0530 Subject: [PATCH 29/37] bump to oz 0.18.0, snforge 0.32.0 --- Scarb.toml | 8 +++-- src/erc4626/erc4626.cairo | 5 ++- src/mocks/ERC20.cairo | 6 ++-- src/tests/erc4626/test_erc4626.cairo | 51 ++++++++++++++-------------- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index bd9d1f7..4ca95fd 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,9 +3,11 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", rev = "v0.13.0"} -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } -starknet = ">=2.5.4" +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", rev = "v0.18.0"} +starknet = ">=2.6.0" + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.32.0" } [lib] diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index dfef397..3d65d69 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -4,7 +4,6 @@ use starknet::ContractAddress; mod ERC4626Component { use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait}; use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; - use openzeppelin::introspection::src5::SRC5Component::SRC5; use openzeppelin::introspection::src5::SRC5Component; use erc4626::erc4626::interface::{ @@ -358,7 +357,7 @@ mod ERC4626Component { let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.transferFrom(caller, get_contract_address(), assets); let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); - erc20_comp_mut._mint(receiver, shares); + erc20_comp_mut.mint(receiver, shares); self.emit(Deposit { sender: caller, owner: receiver, assets, shares }); Hooks::after_deposit(ref self, caller, receiver, assets, shares); @@ -383,7 +382,7 @@ mod ERC4626Component { } } - erc20_comp_mut._burn(owner, shares); + erc20_comp_mut.burn(owner, shares); let dispatcher = ERC20ABIDispatcher { contract_address: self.asset.read() }; dispatcher.transfer(receiver, assets); diff --git a/src/mocks/ERC20.cairo b/src/mocks/ERC20.cairo index 2a44b80..85effc3 100644 --- a/src/mocks/ERC20.cairo +++ b/src/mocks/ERC20.cairo @@ -45,7 +45,7 @@ mod ERC20Token { #[constructor] fn constructor(ref self: ContractState, recipient: ContractAddress, initial_supply: u256) { self.erc20.initializer("Mock", "MCK"); - self.erc20._mint(recipient, initial_supply); + self.erc20.mint(recipient, initial_supply); } #[generate_trait] @@ -53,13 +53,13 @@ mod ERC20Token { #[abi(per_item)] fn burn(ref self: ContractState, value: u256) { let caller = get_caller_address(); - self.erc20._burn(caller, value); + self.erc20.burn(caller, value); } #[abi(per_item)] fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) { self.ownable.assert_only_owner(); - self.erc20._mint(recipient, amount); + self.erc20.mint(recipient, amount); } } } diff --git a/src/tests/erc4626/test_erc4626.cairo b/src/tests/erc4626/test_erc4626.cairo index 69b049e..5883943 100644 --- a/src/tests/erc4626/test_erc4626.cairo +++ b/src/tests/erc4626/test_erc4626.cairo @@ -5,7 +5,8 @@ use erc4626::utils::{pow_256}; use integer::BoundedU256; use openzeppelin::token::erc20::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; use snforge_std::{ - declare, ContractClassTrait, start_prank, stop_prank, CheatTarget, start_warp, stop_warp + declare, ContractClassTrait, start_cheat_caller_address, stop_cheat_caller_address, + DeclareResultTrait }; use openzeppelin::utils::serde::SerializedAppend; use starknet::{ContractAddress, contract_address_const, get_contract_address}; @@ -35,12 +36,12 @@ fn VAULT_ADDRESS() -> ContractAddress { } fn deploy_token() -> (ERC20ABIDispatcher, ContractAddress) { - let token = declare("ERC20Token"); + let token = declare("ERC20Token").unwrap().contract_class(); let mut calldata = Default::default(); Serde::serialize(@OWNER(), ref calldata); Serde::serialize(@INITIAL_SUPPLY(), ref calldata); - let address = token.deploy_at(@calldata, TOKEN_ADDRESS()).unwrap(); + let (address, _) = token.deploy_at(@calldata, TOKEN_ADDRESS()).unwrap(); let dispatcher = ERC20ABIDispatcher { contract_address: address, }; (dispatcher, address) } @@ -54,8 +55,8 @@ fn deploy_contract() -> (ERC20ABIDispatcher, IERC4626Dispatcher) { calldata.append_serde(name); calldata.append_serde(symbol); calldata.append(0); - let vault = declare("ERC4626"); - let contract_address = vault.deploy_at(@calldata, VAULT_ADDRESS()).unwrap(); + let vault = declare("ERC4626").unwrap().contract_class(); + let (contract_address, _) = vault.deploy_at(@calldata, VAULT_ADDRESS()).unwrap(); (token, IERC4626Dispatcher { contract_address }) } @@ -123,11 +124,11 @@ fn preview_withdraw() { fn test_deposit() { let (asset, vault) = deploy_contract(); let amount = asset.balanceOf(OWNER()); - start_prank(CheatTarget::One(asset.contract_address), OWNER()); + start_cheat_caller_address(asset.contract_address, OWNER()); asset.approve(vault.contract_address, amount); - stop_prank(CheatTarget::One(asset.contract_address)); + stop_cheat_caller_address(asset.contract_address); let result = vault.preview_deposit(amount); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); assert(vault.deposit(amount, OWNER()) == result, 'invalid shares'); assert(vault.balanceOf(OWNER()) == result, 'invalid balance'); } @@ -136,11 +137,11 @@ fn test_deposit() { fn test_max_redeem() { let (asset, vault) = deploy_contract(); let amount = asset.balanceOf(OWNER()); - start_prank(CheatTarget::One(asset.contract_address), OWNER()); + start_cheat_caller_address(asset.contract_address, OWNER()); asset.approve(vault.contract_address, amount); - stop_prank(CheatTarget::One(asset.contract_address)); + stop_cheat_caller_address(asset.contract_address); let _result = vault.preview_deposit(amount); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); let shares = vault.deposit(amount, OWNER()); assert(vault.max_redeem(OWNER()) == shares, 'invalid max redeem'); } @@ -148,11 +149,11 @@ fn test_max_redeem() { fn max_withdraw() { let (asset, vault) = deploy_contract(); let amount = asset.balanceOf(OWNER()); - start_prank(CheatTarget::One(asset.contract_address), OWNER()); + start_cheat_caller_address(asset.contract_address, OWNER()); asset.approve(vault.contract_address, amount); - stop_prank(CheatTarget::One(asset.contract_address)); + stop_cheat_caller_address(asset.contract_address); let _result = vault.preview_deposit(amount); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); let _shares = vault.deposit(amount, OWNER()); let value = vault.convert_to_assets(vault.balanceOf(OWNER())); assert(vault.max_withdraw(OWNER()) == value, 'invalid max withdraw'); @@ -161,12 +162,12 @@ fn max_withdraw() { fn mint() { let (asset, vault) = deploy_contract(); let amount = asset.balanceOf(OWNER()); - start_prank(CheatTarget::One(asset.contract_address), OWNER()); + start_cheat_caller_address(asset.contract_address, OWNER()); asset.approve(vault.contract_address, amount); - stop_prank(CheatTarget::One(asset.contract_address)); + stop_cheat_caller_address(asset.contract_address); let _result = vault.preview_deposit(amount); let minted = vault.preview_mint(1); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); let _shares = vault.mint(1, OWNER()); assert(vault.balanceOf(OWNER()) == minted, 'invalid mint shares'); } @@ -174,15 +175,15 @@ fn mint() { fn test_redeem() { let (asset, vault) = deploy_contract(); let amount = asset.balanceOf(OWNER()); - start_prank(CheatTarget::One(asset.contract_address), OWNER()); + start_cheat_caller_address(asset.contract_address, OWNER()); asset.approve(vault.contract_address, amount); - stop_prank(CheatTarget::One(asset.contract_address)); + stop_cheat_caller_address(asset.contract_address); let _result = vault.preview_deposit(amount); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); let shares = vault.deposit(amount, OWNER()); assert(vault.balanceOf(OWNER()) == shares, 'invalid balance before'); let _preview = vault.preview_redeem(shares); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); let _redeemed = vault.redeem(shares, OWNER(), OWNER()); assert(vault.balanceOf(OWNER()) == 0, 'invalid balance after'); } @@ -191,15 +192,15 @@ fn test_redeem() { fn test_withdraw() { let (asset, vault) = deploy_contract(); let amount = asset.balanceOf(OWNER()); - start_prank(CheatTarget::One(asset.contract_address), OWNER()); + start_cheat_caller_address(asset.contract_address, OWNER()); asset.approve(vault.contract_address, amount); - stop_prank(CheatTarget::One(asset.contract_address)); + stop_cheat_caller_address(asset.contract_address); let _result = vault.preview_deposit(amount); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); let shares = vault.deposit(amount, OWNER()); assert(vault.balanceOf(OWNER()) == shares, 'invalid balance before'); - start_prank(CheatTarget::One(vault.contract_address), OWNER()); + start_cheat_caller_address(vault.contract_address, OWNER()); let _shares = vault.withdraw(amount, OWNER(), OWNER()); assert(vault.balanceOf(OWNER()) == 0, 'invalid balance after'); } From d879d025575f43bbf57afd5878455359fa0de484 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Sat, 23 Nov 2024 18:15:18 +0530 Subject: [PATCH 30/37] update oz to scarb reg --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index 4ca95fd..aaeefa3 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", rev = "v0.18.0"} +openzeppelin = "0.18.0" starknet = ">=2.6.0" [dev-dependencies] From fe7004b1ef9fd95ce71521b67f0104367873f61e Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Sat, 7 Dec 2024 10:43:08 +0530 Subject: [PATCH 31/37] bump OZ 0.19.0 --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index aaeefa3..23e26b5 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = "0.18.0" +openzeppelin = "0.19.0" starknet = ">=2.6.0" [dev-dependencies] From c2c6288ffdcf1e8d70927b17096214fc40a6a5be Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Thu, 19 Dec 2024 15:27:11 +0530 Subject: [PATCH 32/37] add edition, bump oz >=0.19.0 --- Scarb.toml | 3 ++- src/erc4626/erc4626.cairo | 24 ++++++++++++------------ src/erc4626/interface.cairo | 10 +++++----- src/lib.cairo | 7 +++++-- src/utils.cairo | 4 +++- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 23e26b5..cd83b74 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,9 +1,10 @@ [package] name = "erc4626" version = "0.1.0" +edition = "2023_11" [dependencies] -openzeppelin = "0.19.0" +openzeppelin = ">=0.19.0" starknet = ">=2.6.0" [dev-dependencies] diff --git a/src/erc4626/erc4626.cairo b/src/erc4626/erc4626.cairo index 3d65d69..ab0d04d 100644 --- a/src/erc4626/erc4626.cairo +++ b/src/erc4626/erc4626.cairo @@ -1,7 +1,7 @@ use starknet::ContractAddress; #[starknet::component] -mod ERC4626Component { +pub mod ERC4626Component { use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait}; use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; use openzeppelin::introspection::src5::SRC5Component; @@ -9,8 +9,8 @@ mod ERC4626Component { use erc4626::erc4626::interface::{ IERC4626Additional, IERC4626Snake, IERC4626Camel, IERC4626Metadata }; + use core::num::traits::Bounded; use erc4626::utils::{pow_256}; - use integer::BoundedU256; use openzeppelin::token::erc20::interface::{ IERC20, IERC20Metadata, ERC20ABIDispatcher, ERC20ABIDispatcherTrait, }; @@ -32,7 +32,7 @@ mod ERC4626Component { #[event] #[derive(Drop, starknet::Event)] - enum Event { + pub enum Event { Deposit: Deposit, Withdraw: Withdraw, } @@ -60,10 +60,10 @@ mod ERC4626Component { } mod Errors { - const EXCEEDED_MAX_DEPOSIT: felt252 = 'ERC4626: exceeded max deposit'; - const EXCEEDED_MAX_MINT: felt252 = 'ERC4626: exceeded max mint'; - const EXCEEDED_MAX_REDEEM: felt252 = 'ERC4626: exceeded max redeem'; - const EXCEEDED_MAX_WITHDRAW: felt252 = 'ERC4626: exceeded max withdraw'; + pub const EXCEEDED_MAX_DEPOSIT: felt252 = 'ERC4626: exceeded max deposit'; + pub const EXCEEDED_MAX_MINT: felt252 = 'ERC4626: exceeded max mint'; + pub const EXCEEDED_MAX_REDEEM: felt252 = 'ERC4626: exceeded max redeem'; + pub const EXCEEDED_MAX_WITHDRAW: felt252 = 'ERC4626: exceeded max withdraw'; } pub trait ERC4626HooksTrait { @@ -131,11 +131,11 @@ mod ERC4626Component { } fn max_deposit(self: @ComponentState, address: ContractAddress) -> u256 { - BoundedU256::max() + Bounded::::MAX } fn max_mint(self: @ComponentState, receiver: ContractAddress) -> u256 { - BoundedU256::max() + Bounded::::MAX } fn max_redeem(self: @ComponentState, owner: ContractAddress) -> u256 { @@ -299,7 +299,7 @@ mod ERC4626Component { } #[generate_trait] - impl InternalImpl< + pub impl InternalImpl< TContractState, +HasComponent, impl erc20: ERC20Component::HasComponent, impl src5: SRC5Component::HasComponent, @@ -376,7 +376,7 @@ mod ERC4626Component { let mut erc20_comp_mut = get_dep_component_mut!(ref self, erc20); if (caller != owner) { let allowance = self.allowance(owner, caller); - if (allowance != BoundedU256::max()) { + if (allowance != Bounded::::MAX) { assert(allowance >= shares, ERC20Errors::APPROVE_FROM_ZERO); erc20_comp_mut.ERC20_allowances.write((owner, caller), allowance - shares); } @@ -398,7 +398,7 @@ mod ERC4626Component { } } -impl ERC4626HooksEmptyImpl of ERC4626Component::ERC4626HooksTrait { +pub impl ERC4626HooksEmptyImpl of ERC4626Component::ERC4626HooksTrait { fn before_deposit( ref self: ERC4626Component::ComponentState, caller: ContractAddress, diff --git a/src/erc4626/interface.cairo b/src/erc4626/interface.cairo index e7481de..47748ca 100644 --- a/src/erc4626/interface.cairo +++ b/src/erc4626/interface.cairo @@ -1,7 +1,7 @@ use starknet::ContractAddress; #[starknet::interface] -trait IERC4626 { +pub trait IERC4626 { // ************************************ // * Metadata // ************************************ @@ -63,14 +63,14 @@ trait IERC4626 { #[starknet::interface] -trait IERC4626Metadata { +pub trait IERC4626Metadata { fn name(self: @TState) -> ByteArray; fn symbol(self: @TState) -> ByteArray; fn decimals(self: @TState) -> u8; } #[starknet::interface] -trait IERC4626Camel { +pub trait IERC4626Camel { fn totalSupply(self: @TState) -> u256; fn balanceOf(self: @TState, account: ContractAddress) -> u256; fn transferFrom( @@ -79,7 +79,7 @@ trait IERC4626Camel { } #[starknet::interface] -trait IERC4626Snake { +pub trait IERC4626Snake { fn total_supply(self: @TState) -> u256; fn balance_of(self: @TState, account: ContractAddress) -> u256; fn allowance(self: @TState, owner: ContractAddress, spender: ContractAddress) -> u256; @@ -91,7 +91,7 @@ trait IERC4626Snake { } #[starknet::interface] -trait IERC4626Additional { +pub trait IERC4626Additional { fn asset(self: @TState) -> ContractAddress; fn convert_to_assets(self: @TState, shares: u256) -> u256; fn convert_to_shares(self: @TState, assets: u256) -> u256; diff --git a/src/lib.cairo b/src/lib.cairo index 2ea5fb3..7506ffb 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,6 +1,9 @@ -mod erc4626; +pub mod erc4626 { + pub mod erc4626; + pub mod interface; +} mod preset { - mod ERC4626; + pub mod ERC4626; } #[cfg(test)] diff --git a/src/utils.cairo b/src/utils.cairo index 0d0edca..ae776fb 100644 --- a/src/utils.cairo +++ b/src/utils.cairo @@ -1,4 +1,6 @@ -fn pow_256(self: u256, mut exponent: u8) -> u256 { +use core::num::traits::Zero; + +pub fn pow_256(self: u256, mut exponent: u8) -> u256 { if self.is_zero() { return 0; } From e5c4138fde1d2c10c46c369e2cb31fd27088a558 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Thu, 19 Dec 2024 15:33:10 +0530 Subject: [PATCH 33/37] bump oz 0.20.0 --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index cd83b74..97a7380 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2023_11" [dependencies] -openzeppelin = ">=0.19.0" +openzeppelin = "0.20.0" starknet = ">=2.6.0" [dev-dependencies] From c727fbb0875517bca298aac23f88dd5aab1bbea0 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Sun, 22 Dec 2024 00:24:11 +0530 Subject: [PATCH 34/37] switch OZ 0.18.0 to scarb reg --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index 4ca95fd..aaeefa3 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", rev = "v0.18.0"} +openzeppelin = "0.18.0" starknet = ">=2.6.0" [dev-dependencies] From d89dcc907b7741ab7048956683b22d61e6cc5af5 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Sun, 22 Dec 2024 00:26:13 +0530 Subject: [PATCH 35/37] bump back to OZ 0.20.0 --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index aaeefa3..f06f0f5 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -3,7 +3,7 @@ name = "erc4626" version = "0.1.0" [dependencies] -openzeppelin = "0.18.0" +openzeppelin = "0.20.0" starknet = ">=2.6.0" [dev-dependencies] From 3c953f6c6661865a923aa06ba1b0e9da1bf0c863 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Sun, 22 Dec 2024 00:35:22 +0530 Subject: [PATCH 36/37] add edition --- Scarb.toml | 2 +- src/tests/erc4626/test_erc4626.cairo | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 97a7380..71b67d6 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2023_11" [dependencies] -openzeppelin = "0.20.0" +openzeppelin = "0.18.0" starknet = ">=2.6.0" [dev-dependencies] diff --git a/src/tests/erc4626/test_erc4626.cairo b/src/tests/erc4626/test_erc4626.cairo index 5883943..53e8f02 100644 --- a/src/tests/erc4626/test_erc4626.cairo +++ b/src/tests/erc4626/test_erc4626.cairo @@ -1,13 +1,12 @@ use core::traits::TryInto; -use debug::PrintTrait; use erc4626::erc4626::interface::{IERC4626Dispatcher, IERC4626DispatcherTrait}; use erc4626::utils::{pow_256}; -use integer::BoundedU256; use openzeppelin::token::erc20::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; use snforge_std::{ declare, ContractClassTrait, start_cheat_caller_address, stop_cheat_caller_address, DeclareResultTrait }; +use core::num::traits::Bounded; use openzeppelin::utils::serde::SerializedAppend; use starknet::{ContractAddress, contract_address_const, get_contract_address}; @@ -88,13 +87,13 @@ fn convert_to_shares() { #[test] fn max_deposit() { let (_asset, vault) = deploy_contract(); - assert(vault.max_deposit(get_contract_address()) == BoundedU256::max(), 'invalid max deposit'); + assert(vault.max_deposit(get_contract_address()) == Bounded::::MAX, 'invalid max deposit'); } #[test] fn max_mint() { let (_asset, vault) = deploy_contract(); - assert(vault.max_mint(get_contract_address()) == BoundedU256::max(), 'invalid max mint'); + assert(vault.max_mint(get_contract_address()) == Bounded::::MAX, 'invalid max mint'); } #[test] From 980883bd8766d36afd865d6f03ce045379920d1b Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Sun, 22 Dec 2024 00:36:24 +0530 Subject: [PATCH 37/37] edition with OZ 0.20 --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index 71b67d6..97a7380 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2023_11" [dependencies] -openzeppelin = "0.18.0" +openzeppelin = "0.20.0" starknet = ">=2.6.0" [dev-dependencies]