Skip to content

Commit

Permalink
refactor interface nft_position_manager
Browse files Browse the repository at this point in the history
  • Loading branch information
dpinones committed Oct 12, 2023
1 parent 0160770 commit e432f10
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 141 deletions.
74 changes: 33 additions & 41 deletions crates/yas_periphery/src/tests/test_yas_nft_position_manager.cairo
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
mod YASNFTPositionManagerTests {
use starknet::{ClassHash, SyscallResultTrait};
use starknet::testing::{set_contract_address, set_caller_address};
use starknet::{contract_address_const, ContractAddress};
use starknet::{ClassHash, ContractAddress, SyscallResultTrait};
use starknet::syscalls::deploy_syscall;
use starknet::testing::{set_contract_address};
use integer::BoundedInt;

use yas_core::contracts::yas_factory::{
YASFactory, IYASFactory, IYASFactoryDispatcher, IYASFactoryDispatcherTrait
};
use yas_core::contracts::yas_erc20::{
ERC20, ERC20::ERC20Impl, IERC20Dispatcher, IERC20DispatcherTrait
};
use yas_core::contracts::yas_factory::{
YASFactory, IYASFactory, IYASFactoryDispatcher, IYASFactoryDispatcherTrait
};
use yas_core::libraries::tick_math::{TickMath::MIN_TICK, TickMath::MAX_TICK};
use yas_core::numbers::fixed_point::implementations::impl_64x96::{
FP64x96Impl, FixedType, FixedTrait
};
use yas_core::tests::utils::constants::PoolConstants::{TOKEN_A, TOKEN_B, POOL_ADDRESS, WALLET};
use yas_core::numbers::signed_integer::{
i32::i32, i32::i32_div_no_round, integer_trait::IntegerTrait
};
use yas_core::tests::utils::constants::FactoryConstants::{
POOL_CLASS_HASH, FeeAmount, fee_amount, tick_spacing
POOL_CLASS_HASH, FeeAmount, fee_amount, tick_spacing, OWNER
};
use yas_core::tests::utils::constants::FactoryConstants::OWNER;
use yas_core::tests::utils::constants::PoolConstants::{TOKEN_A, TOKEN_B, POOL_ADDRESS, WALLET};

use yas_periphery::yas_nft_position_manager::{
YASNFTPositionManager, IYASNFTPositionManager, IYASNFTPositionManagerDispatcher,
IYASNFTPositionManagerDispatcherTrait, MintParams
};

use yas_core::numbers::signed_integer::{
i32::i32, i32::i32_div_no_round, integer_trait::IntegerTrait
};
use yas_core::libraries::tick_math::{TickMath::MIN_TICK, TickMath::MAX_TICK};

fn setup() -> (IYASNFTPositionManagerDispatcher, IERC20Dispatcher, IERC20Dispatcher) {
let yas_factory = deploy_factory(OWNER(), POOL_CLASS_HASH()); // 0x1
let nft_position_manager = deploy_nft_position_manager(yas_factory.contract_address); // 0x2
Expand Down Expand Up @@ -100,25 +97,22 @@ mod YASNFTPositionManagerTests {

mod mint {
use super::{setup, get_min_tick_and_max_tick};
use starknet::testing::{set_contract_address};

use yas_periphery::yas_nft_position_manager::{
YASNFTPositionManager, IYASNFTPositionManager, IYASNFTPositionManagerDispatcher,
IYASNFTPositionManagerDispatcherTrait, MintParams, Position, PoolKey
};
use yas_core::tests::utils::constants::PoolConstants::{TOKEN_A, TOKEN_B, WALLET, OTHER};

use yas_core::tests::utils::constants::FactoryConstants::{
POOL_CLASS_HASH, FeeAmount, fee_amount, tick_spacing
use yas_core::contracts::yas_erc20::{
ERC20, ERC20::ERC20Impl, IERC20Dispatcher, IERC20DispatcherTrait
};

use yas_core::numbers::fixed_point::implementations::impl_64x96::{
FP64x96Impl, FixedType, FixedTrait
};
use yas_core::tests::utils::constants::FactoryConstants::{
POOL_CLASS_HASH, FeeAmount, fee_amount, tick_spacing
};
use yas_core::tests::utils::constants::PoolConstants::{TOKEN_A, TOKEN_B, WALLET, OTHER};

use starknet::testing::{set_contract_address, set_caller_address};

use yas_core::contracts::yas_erc20::{
ERC20, ERC20::ERC20Impl, IERC20Dispatcher, IERC20DispatcherTrait
use yas_periphery::yas_nft_position_manager::{
YASNFTPositionManager, IYASNFTPositionManager, IYASNFTPositionManagerDispatcher,
IYASNFTPositionManagerDispatcherTrait, MintParams, Position, PoolKey
};

#[test]
Expand Down Expand Up @@ -149,7 +143,6 @@ mod YASNFTPositionManagerTests {

#[test]
#[available_gas(200000000)]
// TODO: error transfer ? u256_sub Overflow
#[should_panic(
expected: (
'u256_sub Overflow',
Expand Down Expand Up @@ -227,21 +220,20 @@ mod YASNFTPositionManagerTests {
}
);

// TODO: add methods interface nft manager
// assert(yas_nft_position_manager.balance_of(other.address) == 1, '');
// assert(yas_nft_position_manager.token_of_owner_by_index(other.address, 0) == 1, '');
assert(yas_nft_position_manager.balance_of(OTHER()) == 1, 'wrong balance_of OTHER');
// assert(yas_nft_position_manager.token_of_owner_by_index(other.address, 0) == 1, ''); // TODO: ERC721Enumerable

let (position, pool_key) = yas_nft_position_manager.positions(1);
assert(pool_key.token_0 == token_0.contract_address, '');
assert(pool_key.token_1 == token_1.contract_address, '');
assert(pool_key.fee == fee_amount(FeeAmount::MEDIUM), '');
assert(position.tick_lower == min_tick, '');
assert(position.tick_upper == max_tick, '');
assert(position.liquidity == 15, '');
assert(position.tokens_owed_0 == 0, '');
assert(position.tokens_owed_1 == 0, '');
assert(position.fee_growth_inside_0_last_X128 == 0, '');
assert(position.fee_growth_inside_1_last_X128 == 0, '');
assert(pool_key.token_0 == token_0.contract_address, 'wrong token_0');
assert(pool_key.token_1 == token_1.contract_address, 'wrong token_1');
assert(pool_key.fee == fee_amount(FeeAmount::MEDIUM), 'wrong fee');
assert(position.tick_lower == min_tick, 'wrong tick_lower');
assert(position.tick_upper == max_tick, 'wrong tick_upper');
assert(position.liquidity == 15, 'wrong liquidity');
assert(position.tokens_owed_0 == 0, 'wrong tokens_owed_0');
assert(position.tokens_owed_1 == 0, 'wrong tokens_owed_1');
assert(position.fee_growth_inside_0_last_X128 == 0, 'wrong fee_growth_inside_0');
assert(position.fee_growth_inside_1_last_X128 == 0, 'wrong fee_growth_inside_1');
}
}
}
212 changes: 112 additions & 100 deletions crates/yas_periphery/src/yas_nft_position_manager.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,29 @@ trait IYASNFTPositionManager<TContractState> {
fn yas_mint_callback(
ref self: TContractState, amount_0_owed: u256, amount_1_owed: u256, data: Array<felt252>
);
// ERC721
fn supports_interface(self: @TContractState, interface_id: felt252) -> bool;
fn name(self: @TContractState) -> felt252;
fn symbol(self: @TContractState) -> felt252;
fn token_uri(self: @TContractState, token_id: u256) -> felt252;
fn balance_of(self: @TContractState, account: ContractAddress) -> u256;
fn owner_of(self: @TContractState, token_id: u256) -> ContractAddress;
fn transfer_from(
ref self: TContractState, from: ContractAddress, to: ContractAddress, token_id: u256
);
fn safe_transfer_from(
ref self: TContractState,
from: ContractAddress,
to: ContractAddress,
token_id: u256,
data: Span<felt252>
);
fn approve(ref self: TContractState, to: ContractAddress, token_id: u256);
fn set_approval_for_all(ref self: TContractState, operator: ContractAddress, approved: bool);
fn get_approved(self: @TContractState, token_id: u256) -> ContractAddress;
fn is_approved_for_all(
self: @TContractState, owner: ContractAddress, operator: ContractAddress
) -> bool;
}

#[starknet::contract]
Expand All @@ -113,8 +136,6 @@ mod YASNFTPositionManager {
ContractAddress, get_contract_address, contract_address_const, get_caller_address
};
use openzeppelin::token::erc721::ERC721;
use openzeppelin::token::erc721::interface::{IERC721, IERC721Metadata};
use openzeppelin::introspection::interface::ISRC5;

use yas_core::contracts::yas_pool::{IYASPoolDispatcher, IYASPoolDispatcherTrait};
use yas_core::contracts::yas_factory::{IYASFactoryDispatcher, IYASFactoryDispatcherTrait};
Expand Down Expand Up @@ -458,6 +479,95 @@ mod YASNFTPositionManager {
.transferFrom(sender, msg_sender, amount_1_owed);
}
}

// ERC721
fn supports_interface(self: @ContractState, interface_id: felt252) -> bool {
let state = ERC721::unsafe_new_contract_state();
ERC721::SRC5Impl::supports_interface(@state, interface_id)
}

fn name(self: @ContractState) -> felt252 {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721MetadataImpl::name(@state)
}

fn symbol(self: @ContractState) -> felt252 {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721MetadataImpl::symbol(@state)
}

fn token_uri(self: @ContractState, token_id: u256) -> felt252 {
let state = ERC721::unsafe_new_contract_state();
assert(ERC721::InternalImpl::_exists(@state, token_id), 'ERC721: invalid token ID');
// TODO: url
1
}

fn balance_of(self: @ContractState, account: ContractAddress) -> u256 {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::balance_of(@state, account)
}

fn owner_of(self: @ContractState, token_id: u256) -> ContractAddress {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::owner_of(@state, token_id)
}

fn transfer_from(
ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256
) {
let mut state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::transfer_from(ref state, from, to, token_id);
}

fn safe_transfer_from(
ref self: ContractState,
from: ContractAddress,
to: ContractAddress,
token_id: u256,
data: Span<felt252>
) {
let mut state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::safe_transfer_from(ref state, from, to, token_id, data);
}

// TODO: replace _approve
fn approve(ref self: ContractState, to: ContractAddress, token_id: u256) {
let state = ERC721::unsafe_new_contract_state();
let owner = ERC721::InternalImpl::_owner_of(@state, token_id);

let caller = get_caller_address();
assert(
owner == caller || ERC721::ERC721Impl::is_approved_for_all(@state, owner, caller),
ERC721::Errors::UNAUTHORIZED
);

let mut position = self.positions.read(token_id);
position.operator = to;
self.positions.write(token_id, position);

self.emit(Approval { owner, to, token_id });
}

fn set_approval_for_all(
ref self: ContractState, operator: ContractAddress, approved: bool
) {
let mut state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::set_approval_for_all(ref state, operator, approved);
}

fn get_approved(self: @ContractState, token_id: u256) -> ContractAddress {
let state = ERC721::unsafe_new_contract_state();
assert(ERC721::InternalImpl::_exists(@state, token_id), 'ERC721: invalid token ID');
self.positions.read(token_id).operator
}

fn is_approved_for_all(
self: @ContractState, owner: ContractAddress, operator: ContractAddress
) -> bool {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::is_approved_for_all(@state, owner, operator)
}
}

#[generate_trait]
Expand Down Expand Up @@ -595,102 +705,4 @@ mod YASNFTPositionManager {
get_liquidity_for_amount_1(sqrt_ratio_AX96, sqrt_ratio_BX96, amount_1)
}
}

// ERC721
#[external(v0)]
impl SRC5Impl of ISRC5<ContractState> {
fn supports_interface(self: @ContractState, interface_id: felt252) -> bool {
let state = ERC721::unsafe_new_contract_state();
ERC721::SRC5Impl::supports_interface(@state, interface_id)
}
}

#[external(v0)]
impl ERC721MetadataImpl of IERC721Metadata<ContractState> {
fn name(self: @ContractState) -> felt252 {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721MetadataImpl::name(@state)
}

fn symbol(self: @ContractState) -> felt252 {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721MetadataImpl::symbol(@state)
}

fn token_uri(self: @ContractState, token_id: u256) -> felt252 {
let state = ERC721::unsafe_new_contract_state();
assert(ERC721::InternalImpl::_exists(@state, token_id), 'ERC721: invalid token ID');
// TODO: url
1
}
}

#[external(v0)]
impl IERC721Impl of IERC721<ContractState> {
fn balance_of(self: @ContractState, account: ContractAddress) -> u256 {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::balance_of(@state, account)
}

fn owner_of(self: @ContractState, token_id: u256) -> ContractAddress {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::owner_of(@state, token_id)
}

fn transfer_from(
ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256
) {
let mut state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::transfer_from(ref state, from, to, token_id);
}

fn safe_transfer_from(
ref self: ContractState,
from: ContractAddress,
to: ContractAddress,
token_id: u256,
data: Span<felt252>
) {
let mut state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::safe_transfer_from(ref state, from, to, token_id, data);
}

// TODO: replace _approve
fn approve(ref self: ContractState, to: ContractAddress, token_id: u256) {
let state = ERC721::unsafe_new_contract_state();
let owner = ERC721::InternalImpl::_owner_of(@state, token_id);

let caller = get_caller_address();
assert(
owner == caller || ERC721::ERC721Impl::is_approved_for_all(@state, owner, caller),
ERC721::Errors::UNAUTHORIZED
);

let mut position = self.positions.read(token_id);
position.operator = to;
self.positions.write(token_id, position);

self.emit(Approval { owner, to, token_id });
}

fn set_approval_for_all(
ref self: ContractState, operator: ContractAddress, approved: bool
) {
let mut state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::set_approval_for_all(ref state, operator, approved);
}

fn get_approved(self: @ContractState, token_id: u256) -> ContractAddress {
let state = ERC721::unsafe_new_contract_state();
assert(ERC721::InternalImpl::_exists(@state, token_id), 'ERC721: invalid token ID');
self.positions.read(token_id).operator
}

fn is_approved_for_all(
self: @ContractState, owner: ContractAddress, operator: ContractAddress
) -> bool {
let state = ERC721::unsafe_new_contract_state();
ERC721::ERC721Impl::is_approved_for_all(@state, owner, operator)
}
}
}

0 comments on commit e432f10

Please sign in to comment.