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

Add erc4626 #1170

Open
wants to merge 86 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 80 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
82b3173
start erc4626
andrew-fleming Sep 26, 2024
f08dd48
add fns from interface
andrew-fleming Sep 27, 2024
c558c59
start business logic
andrew-fleming Oct 1, 2024
0b572e5
add mul_div and tests
andrew-fleming Oct 1, 2024
3cadd55
simplify math
andrew-fleming Oct 1, 2024
f66bce4
add fix me comments
andrew-fleming Oct 1, 2024
5d7b1d9
fix fmt
andrew-fleming Oct 1, 2024
33bd0d4
fix fmt
andrew-fleming Oct 1, 2024
ce22c2f
add convert_to logic, add metadata impl
andrew-fleming Oct 2, 2024
4fefde2
reexports
andrew-fleming Oct 2, 2024
80c4013
add erc4626 mock
andrew-fleming Oct 2, 2024
7e4177f
add erc4626 mock
andrew-fleming Oct 2, 2024
3def693
start erc4626 tests
andrew-fleming Oct 2, 2024
77fdfa6
comment out mods and tests to improve performance
andrew-fleming Oct 2, 2024
dc66804
add offset config in mock
andrew-fleming Oct 3, 2024
b05f57e
add overflow assertion and test
andrew-fleming Oct 3, 2024
ea3bf06
add power fn
andrew-fleming Oct 6, 2024
f5ce03b
add erc20reentrant mock
andrew-fleming Oct 6, 2024
e70061d
fix interface fns
andrew-fleming Oct 6, 2024
ca52772
fix logic, add power
andrew-fleming Oct 6, 2024
8072770
add starting tests-no assets, no shares
andrew-fleming Oct 6, 2024
7d2a3c1
fix fmt
andrew-fleming Oct 6, 2024
a45c8dc
clean up power fn
andrew-fleming Oct 6, 2024
bb1cdc2
simplify operation
andrew-fleming Oct 6, 2024
f2681e5
add comments, fix visibility
andrew-fleming Oct 6, 2024
f401df1
move fn, remove tests
andrew-fleming Oct 6, 2024
4bdde8d
add test_math mod
andrew-fleming Oct 6, 2024
ccc8784
add mint to mock vault construction
andrew-fleming Oct 8, 2024
87a84ab
add full vault tests
andrew-fleming Oct 8, 2024
501d7b9
fix fmt
andrew-fleming Oct 8, 2024
ee222f5
fix assertions
andrew-fleming Oct 8, 2024
970cb75
add full vault redeem tests
andrew-fleming Oct 8, 2024
39b205c
fix fmt
andrew-fleming Oct 8, 2024
5af5b8b
fix fmt
andrew-fleming Oct 8, 2024
69c4831
fix conflicts
andrew-fleming Oct 8, 2024
b735b5d
fix fmt
andrew-fleming Oct 8, 2024
43440d0
move erc4626 tests to erc4626 dir
andrew-fleming Oct 8, 2024
56cea65
add transfer assertion
andrew-fleming Oct 9, 2024
0870930
add reentrancy tests
andrew-fleming Oct 11, 2024
65dddfc
expose burn in mock
andrew-fleming Oct 11, 2024
bded58f
tidy up tests
andrew-fleming Oct 11, 2024
fd4d146
add default decimals mock
andrew-fleming Oct 11, 2024
2bf3aac
fix deploy fn names
andrew-fleming Oct 11, 2024
9c7243f
improve helper fn name
andrew-fleming Oct 11, 2024
bb3a6b0
fix fmt
andrew-fleming Oct 11, 2024
c8a9dfa
add comments, remove unused dep
andrew-fleming Oct 19, 2024
385118e
update branch
andrew-fleming Oct 19, 2024
bc88cf8
fix conflicts
andrew-fleming Oct 19, 2024
1d14afc
fix conflicts
andrew-fleming Oct 19, 2024
acc2047
fix fmt
andrew-fleming Oct 19, 2024
2e368fd
update spdx
andrew-fleming Oct 19, 2024
c4f565e
fix conflicts
andrew-fleming Nov 20, 2024
c343716
add reqs to mul_div, fix spdx
andrew-fleming Nov 21, 2024
0e10817
remove duplicate erc4626 in votes
andrew-fleming Nov 21, 2024
cbdd70a
add/fix in-code docs
andrew-fleming Nov 21, 2024
970d621
fix param name
andrew-fleming Nov 22, 2024
1418543
fix comments
andrew-fleming Nov 25, 2024
a10b28c
add multiple tx tests
andrew-fleming Nov 25, 2024
e67d312
fix err msgs
andrew-fleming Nov 25, 2024
ed727df
fix comments, fix test
andrew-fleming Nov 25, 2024
b7fb9de
add note to power
andrew-fleming Nov 26, 2024
44055bd
use math:: prefix in tests
andrew-fleming Nov 26, 2024
8d8e066
improve u256_mul_div
andrew-fleming Nov 26, 2024
450efa4
remove unused var
andrew-fleming Nov 27, 2024
d912c6d
remove line
andrew-fleming Nov 27, 2024
0cd10da
improve var name
andrew-fleming Nov 27, 2024
3ef163f
add changelog entries
andrew-fleming Nov 29, 2024
4fcdd0c
Merge branch 'main' into add-erc4626
andrew-fleming Nov 29, 2024
c8b7161
fix version in spdx
andrew-fleming Nov 29, 2024
1c221a5
Apply suggestions from code review
andrew-fleming Dec 5, 2024
ed01a88
fix conflicts
andrew-fleming Dec 9, 2024
58d26be
use corelib pow, remove power fn
andrew-fleming Dec 9, 2024
c699dc4
add zero addr test
andrew-fleming Dec 9, 2024
0ec51cf
fix max and preview comments
andrew-fleming Dec 10, 2024
f84d7d1
Apply suggestions from code review
andrew-fleming Dec 10, 2024
dd81898
fix conflicts, fmt
andrew-fleming Dec 10, 2024
960f338
improve interface fmt
andrew-fleming Dec 10, 2024
b147fb4
re-enable cairo-coverage in CI
andrew-fleming Dec 11, 2024
978ac98
tmp lower codecov coverage
andrew-fleming Dec 11, 2024
533f7ba
tmp increase threshold
andrew-fleming Dec 11, 2024
84e3681
Apply suggestions from code review
andrew-fleming Dec 18, 2024
9a6a14a
fix comment
andrew-fleming Dec 18, 2024
9c69ca2
add LimitConfig comments
andrew-fleming Dec 18, 2024
0c3f8e0
Apply suggestions from code review
andrew-fleming Dec 18, 2024
8852efe
add HasComponent to traits
andrew-fleming Dec 18, 2024
8729faa
fix fmt
andrew-fleming Dec 18, 2024
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
24 changes: 10 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ jobs:
with:
starknet-foundry-version: ${{ env.FOUNDRY_VERSION }}

# Issue with cairo-coverage. Re-add to CI once issues are fixed.
#
# - name: Install cairo-coverage
# run: curl -L https://raw.githubusercontent.com/software-mansion/cairo-coverage/main/scripts/install.sh | sh
- name: Install cairo-coverage
run: curl -L https://raw.githubusercontent.com/software-mansion/cairo-coverage/main/scripts/install.sh | sh

- name: Markdown lint
uses: DavidAnson/markdownlint-cli2-action@eb5ca3ab411449c66620fe7f1b3c9e10547144b0 # v16
Expand All @@ -52,13 +50,11 @@ jobs:
- name: Run tests
run: snforge test --workspace

# Issue with cairo-coverage. Re-add to CI once issues are fixed.
#
# - name: Run tests and generate coverage report
# run: snforge test --workspace --coverage
#
# - name: Upload coverage to Codecov
# uses: codecov/codecov-action@v4
# with:
# file: ./coverage.lcov
# token: ${{ secrets.CODECOV_TOKEN }}
- name: Run tests and generate coverage report
run: snforge test --workspace --coverage

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage.lcov
token: ${{ secrets.CODECOV_TOKEN }}
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- ERC4626Component (#1170)
- `Math::u256_mul_div` (#1170)
- SRC9 (Outside Execution) integration to account presets (#1201)
- `SNIP12HashSpanImpl` to `openzeppelin_utils::cryptography::snip12` (#1180)
- GovernorComponent with the following extensions: (#1180)
Expand Down
12 changes: 7 additions & 5 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ comment:
coverage:
# The value range where you want the value to be green
# Hold ourselves to a high bar.
range: 90..100
# TMP 80 floor until cairo-coverage becomes more stable
range: 80..100
status:
project:
coverage:
# Use the coverage from the base commit (pull request base) coverage to compare against.
# Once we have a baseline we can be more strict.
# TMP threshold until cairo-coverage becomes more stable
target: auto
threshold: 2%
threshold: 4%
patch:
default:
# Require new code to have 90%+ coverage.
target: 90%
threshold: 2%
# TMP target and threshold until cairo-coverage becomes more stable
target: 80%
threshold: 4%

ignore:
- "**/tests/**"
Expand All @@ -27,4 +30,3 @@ ignore:

github_checks:
annotations: false

1 change: 1 addition & 0 deletions packages/test_common/src/mocks.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod checkpoint;
pub mod erc1155;
pub mod erc20;
pub mod erc2981;
pub mod erc4626;
pub mod erc721;
pub mod governor;
pub mod multisig;
Expand Down
161 changes: 161 additions & 0 deletions packages/test_common/src/mocks/erc20.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use starknet::ContractAddress;

#[starknet::contract]
pub mod DualCaseERC20Mock {
use openzeppelin_token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
Expand Down Expand Up @@ -224,3 +226,162 @@ pub mod DualCaseERC20PermitMock {
self.erc20.mint(recipient, initial_supply);
}
}

#[derive(Drop, Serde, PartialEq, Debug, starknet::Store)]
pub enum Type {
No,
Before,
After,
}

#[starknet::interface]
pub trait IERC20ReentrantHelpers<TState> {
fn schedule_reenter(
ref self: TState,
when: Type,
target: ContractAddress,
selector: felt252,
calldata: Span<felt252>,
);
fn function_call(ref self: TState);
fn unsafe_mint(ref self: TState, recipient: ContractAddress, amount: u256);
fn unsafe_burn(ref self: TState, account: ContractAddress, amount: u256);
}

#[starknet::interface]
pub trait IERC20Reentrant<TState> {
fn schedule_reenter(
ref self: TState,
when: Type,
target: ContractAddress,
selector: felt252,
calldata: Span<felt252>,
);
fn function_call(ref self: TState);
fn unsafe_mint(ref self: TState, recipient: ContractAddress, amount: u256);
fn unsafe_burn(ref self: TState, account: ContractAddress, amount: u256);

// IERC20
fn total_supply(self: @TState) -> u256;
fn balance_of(self: @TState, account: ContractAddress) -> u256;
fn allowance(self: @TState, owner: ContractAddress, spender: ContractAddress) -> u256;
fn transfer(ref self: TState, recipient: ContractAddress, amount: u256) -> bool;
fn transfer_from(
ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256,
) -> bool;
fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool;
}

#[starknet::contract]
pub mod ERC20ReentrantMock {
use openzeppelin_token::erc20::ERC20Component;
use starknet::ContractAddress;
use starknet::SyscallResultTrait;
use starknet::storage::{MutableVecTrait, Vec};
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
use starknet::syscalls::call_contract_syscall;
use super::Type;

component!(path: ERC20Component, storage: erc20, event: ERC20Event);

#[abi(embed_v0)]
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;
#[abi(embed_v0)]
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;
#[abi(embed_v0)]
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;
impl InternalImpl = ERC20Component::InternalImpl<ContractState>;

#[storage]
pub struct Storage {
#[substorage(v0)]
pub erc20: ERC20Component::Storage,
reenter_type: Type,
reenter_target: ContractAddress,
reenter_selector: felt252,
reenter_calldata: Vec<felt252>,
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
ERC20Event: ERC20Component::Event,
}

//
// Hooks
//

impl ERC20ReentrantImpl of ERC20Component::ERC20HooksTrait<ContractState> {
fn before_update(
ref self: ERC20Component::ComponentState<ContractState>,
from: ContractAddress,
recipient: ContractAddress,
amount: u256,
) {
let mut contract_state = self.get_contract_mut();

if (contract_state.reenter_type.read() == Type::Before) {
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved
contract_state.reenter_type.write(Type::No);
contract_state.function_call();
}
}

fn after_update(
ref self: ERC20Component::ComponentState<ContractState>,
from: ContractAddress,
recipient: ContractAddress,
amount: u256,
) {
let mut contract_state = self.get_contract_mut();

if (contract_state.reenter_type.read() == Type::After) {
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved
contract_state.reenter_type.write(Type::No);
contract_state.function_call();
}
}
}

#[abi(embed_v0)]
pub impl ERC20ReentrantHelpers of super::IERC20ReentrantHelpers<ContractState> {
fn schedule_reenter(
ref self: ContractState,
when: Type,
target: ContractAddress,
selector: felt252,
calldata: Span<felt252>,
) {
self.reenter_type.write(when);
self.reenter_target.write(target);
self.reenter_selector.write(selector);
for elem in calldata {
self.reenter_calldata.append().write(*elem);
Copy link
Collaborator

@immrsd immrsd Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we clear the calldata that already exists to allow for a repeated call?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have to. There's only one reentrant call since we're setting the reentrant Type to No in the hooks after the initial call

}
}

fn function_call(ref self: ContractState) {
let target = self.reenter_target.read();
let selector = self.reenter_selector.read();
let mut calldata = array![];
for i in 0..self.reenter_calldata.len() {
calldata.append(self.reenter_calldata.at(i).read());
};
call_contract_syscall(target, selector, calldata.span()).unwrap_syscall();
}

fn unsafe_mint(ref self: ContractState, recipient: ContractAddress, amount: u256) {
self.erc20.mint(recipient, amount);
}

fn unsafe_burn(ref self: ContractState, account: ContractAddress, amount: u256) {
self.erc20.burn(account, amount);
}
}

#[constructor]
fn constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray) {
self.erc20.initializer(name, symbol);
self.reenter_type.write(Type::No);
}
}
Loading
Loading