diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 98b53f8..cc32f3d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v3 - uses: software-mansion/setup-scarb@v1 with: - scarb-version: "0.7.0" + scarb-version: "2.4.1" - run: scarb fmt --check - run: scarb build - run: scarb test \ No newline at end of file diff --git a/.gitignore b/.gitignore index ab9c17a..a9b7a7e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ target .env -accounts \ No newline at end of file +accounts/*.json \ No newline at end of file diff --git a/Scarb.lock b/Scarb.lock new file mode 100644 index 0000000..0f1fed1 --- /dev/null +++ b/Scarb.lock @@ -0,0 +1,14 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "openzeppelin" +version = "0.8.0" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.8.0#c23e8e96de60e6e3159b1ff8591a1187269c0eb7" + +[[package]] +name = "swappy" +version = "0.0.1" +dependencies = [ + "openzeppelin", +] diff --git a/Scarb.toml b/Scarb.toml index 9b30446..fcd65cf 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -6,7 +6,7 @@ version = "0.0.1" [dependencies] starknet = ">=2.2.0" -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.7.0-rc.0" } +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.8.0" } [[target.starknet-contract]] diff --git a/accounts/README.md b/accounts/README.md new file mode 100644 index 0000000..ec6794e --- /dev/null +++ b/accounts/README.md @@ -0,0 +1,55 @@ +# Create a new signer +``` +starkli signer keystore new accounts/keystore.json +export STARKNET_KEYSTORE=accounts/keystore.json +``` + +# Create the deployer account +``` +starkli account oz init accounts/deployer.json +starkli account deploy accounts/deployer.json +``` + +# Declare Swappy Account Contract +``` +starkli declare target/dev/swappy_Account.contract_class.json --account accounts/deployer.json +# 0x03dd8bbd25d0807d830cc78f3aef5e759c186c8f91efe1fcf3531132fdcade4b +``` + +# Create a swappy account +``` +starkli account oz init accounts/swappy.json +``` +> update class_hash +``` +starkli account deploy accounts/swappy.json +``` + +# Deploy Position Manager Contract +``` +starkli declare target/dev/swappy_PositionManager.contract_class.json --account accounts/deployer.json +# 0x0303b3c6adfb5015a09bce62b23428bb3e3b4bca3726a27919ae78763b5e993a + +starkli deploy 0x0303b3c6adfb5015a09bce62b23428bb3e3b4bca3726a27919ae78763b5e993a 0x0 --account accounts/deployer.json +# 0x0097ab8a6dc7760a687caaffa7101611b20babda533ce40b3cac94fb1926355e +``` + +# Get last position ID +``` +starkli call 0x0097ab8a6dc7760a687caaffa7101611b20babda533ce40b3cac94fb1926355e get_last_id +``` + +# create position +``` +starkli invoke 0x0097ab8a6dc7760a687caaffa7101611b20babda533ce40b3cac94fb1926355e create_position 0x1 0x2 u256:1 u256:1 --account accounts/swappy.json +``` + +# Pause position +``` +starkli invoke 0x0097ab8a6dc7760a687caaffa7101611b20babda533ce40b3cac94fb1926355e pause_position [POSITION_ID] --account accounts/swappy.json +``` + +# Resume position +``` +starkli invoke 0x0097ab8a6dc7760a687caaffa7101611b20babda533ce40b3cac94fb1926355e resume_position [POSITION_ID] --account accounts/swappy.json +``` \ No newline at end of file diff --git a/src/account/account.cairo b/src/account/account.cairo index 98032c4..9196e22 100755 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -1,244 +1,50 @@ -use array::ArrayTrait; -use array::SpanTrait; -use option::OptionTrait; -use serde::Serde; -use starknet::ContractAddress; -use starknet::account::Call; - -const TRANSACTION_VERSION: felt252 = 1; - -// 2**128 + TRANSACTION_VERSION -const QUERY_VERSION: felt252 = 340282366920938463463374607431768211457; - -trait PublicKeyTrait { - fn set_public_key(ref self: TState, new_public_key: felt252); - fn get_public_key(self: @TState) -> felt252; -} - -trait PublicKeyCamelTrait { - fn setPublicKey(ref self: TState, newPublicKey: felt252); - fn getPublicKey(self: @TState) -> felt252; -} - #[starknet::contract] mod Account { - use array::ArrayTrait; - use array::SpanTrait; - use box::BoxTrait; - use ecdsa::check_ecdsa_signature; - - use openzeppelin::account::interface; - use openzeppelin::introspection::interface::ISRC5; - use openzeppelin::introspection::interface::ISRC5Camel; - use openzeppelin::introspection::src5::SRC5; - use option::OptionTrait; - use starknet::get_caller_address; - use starknet::get_contract_address; - use starknet::get_tx_info; - - use super::Call; - use super::QUERY_VERSION; - use super::TRANSACTION_VERSION; - use zeroable::Zeroable; - - use swappy::account::error::AccountError; + use openzeppelin::account::AccountComponent; + use openzeppelin::introspection::src5::SRC5Component; + + component!(path: AccountComponent, storage: account, event: AccountEvent); + component!(path: SRC5Component, storage: src5, event: SRC5Event); + + // Account + #[abi(embed_v0)] + impl SRC6Impl = AccountComponent::SRC6Impl; + #[abi(embed_v0)] + impl SRC6CamelOnlyImpl = AccountComponent::SRC6CamelOnlyImpl; + #[abi(embed_v0)] + impl PublicKeyImpl = AccountComponent::PublicKeyImpl; + #[abi(embed_v0)] + impl PublicKeyCamelImpl = AccountComponent::PublicKeyCamelImpl; + #[abi(embed_v0)] + impl DeclarerImpl = AccountComponent::DeclarerImpl; + #[abi(embed_v0)] + impl DeployableImpl = AccountComponent::DeployableImpl; + + impl AccountInternalImpl = AccountComponent::InternalImpl; + + // SRC5 + #[abi(embed_v0)] + impl SRC5Impl = SRC5Component::SRC5Impl; #[storage] struct Storage { - public_key: felt252 + #[substorage(v0)] + account: AccountComponent::Storage, + #[substorage(v0)] + src5: SRC5Component::Storage } #[event] #[derive(Drop, starknet::Event)] enum Event { - OwnerAdded: OwnerAdded, - OwnerRemoved: OwnerRemoved, - } - - #[derive(Drop, starknet::Event)] - struct OwnerAdded { - new_owner_guid: felt252 - } - - #[derive(Drop, starknet::Event)] - struct OwnerRemoved { - removed_owner_guid: felt252 + #[flat] + AccountEvent: AccountComponent::Event, + #[flat] + SRC5Event: SRC5Component::Event } #[constructor] - fn constructor(ref self: ContractState, _public_key: felt252) { - self.initializer(_public_key); - } - - // - // External - // - - #[external(v0)] - impl SRC6Impl of interface::ISRC6 { - fn __execute__(self: @ContractState, mut calls: Array) -> Array> { - // Avoid calls from other contracts - let sender = get_caller_address(); - assert(sender.is_zero(), AccountError::INVALID_CALLER); - - // Check tx version - let tx_info = get_tx_info().unbox(); - let version = tx_info.version; - if version != TRANSACTION_VERSION { - assert(version == QUERY_VERSION, AccountError::INVALID_TX_VERSION); - } - - _execute_calls(calls) - } - - fn __validate__(self: @ContractState, mut calls: Array) -> felt252 { - self.validate_transaction() - } - - fn is_valid_signature( - self: @ContractState, hash: felt252, signature: Array - ) -> felt252 { - if self._is_valid_signature(hash, signature.span()) { - starknet::VALIDATED - } else { - 0 - } - } - } - - #[external(v0)] - impl SRC6CamelOnlyImpl of interface::ISRC6CamelOnly { - fn isValidSignature( - self: @ContractState, hash: felt252, signature: Array - ) -> felt252 { - SRC6Impl::is_valid_signature(self, hash, signature) - } - } - - #[external(v0)] - impl DeclarerImpl of interface::IDeclarer { - fn __validate_declare__(self: @ContractState, class_hash: felt252) -> felt252 { - self.validate_transaction() - } - } - - #[external(v0)] - impl SRC5Impl of ISRC5 { - fn supports_interface(self: @ContractState, interface_id: felt252) -> bool { - let unsafe_state = SRC5::unsafe_new_contract_state(); - SRC5::SRC5Impl::supports_interface(@unsafe_state, interface_id) - } - } - - #[external(v0)] - impl SRC5CamelImpl of ISRC5Camel { - fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool { - let unsafe_state = SRC5::unsafe_new_contract_state(); - SRC5::SRC5CamelImpl::supportsInterface(@unsafe_state, interfaceId) - } - } - - #[external(v0)] - impl PublicKeyImpl of super::PublicKeyTrait { - fn get_public_key(self: @ContractState) -> felt252 { - self.public_key.read() - } - - fn set_public_key(ref self: ContractState, new_public_key: felt252) { - assert_only_self(); - self.emit(OwnerRemoved { removed_owner_guid: self.public_key.read() }); - self._set_public_key(new_public_key); - } - } - - #[external(v0)] - impl PublicKeyCamelImpl of super::PublicKeyCamelTrait { - fn getPublicKey(self: @ContractState) -> felt252 { - self.public_key.read() - } - - fn setPublicKey(ref self: ContractState, newPublicKey: felt252) { - PublicKeyImpl::set_public_key(ref self, newPublicKey); - } - } - - #[external(v0)] - fn __validate_deploy__( - self: @ContractState, - class_hash: felt252, - contract_address_salt: felt252, - _public_key: felt252 - ) -> felt252 { - self.validate_transaction() - } - - // - // Internal - // - - #[generate_trait] - impl InternalImpl of InternalTrait { - fn initializer(ref self: ContractState, _public_key: felt252) { - let mut unsafe_state = SRC5::unsafe_new_contract_state(); - SRC5::InternalImpl::register_interface(ref unsafe_state, interface::ISRC6_ID); - self._set_public_key(_public_key); - } - - fn validate_transaction(self: @ContractState) -> felt252 { - let tx_info = get_tx_info().unbox(); - let tx_hash = tx_info.transaction_hash; - let signature = tx_info.signature; - assert(self._is_valid_signature(tx_hash, signature), AccountError::INVALID_SIGNATURE); - starknet::VALIDATED - } - - fn _set_public_key(ref self: ContractState, new_public_key: felt252) { - self.public_key.write(new_public_key); - self.emit(OwnerAdded { new_owner_guid: new_public_key }); - } - - fn _is_valid_signature( - self: @ContractState, hash: felt252, signature: Span - ) -> bool { - let valid_length = signature.len() == 2_u32; - - if valid_length { - check_ecdsa_signature( - hash, self.public_key.read(), *signature.at(0_u32), *signature.at(1_u32) - ) - } else { - false - } - } - } - - #[internal] - fn assert_only_self() { - let caller = get_caller_address(); - let self = get_contract_address(); - assert(self == caller, AccountError::UNAUTHORIZED); - } - - #[internal] - fn _execute_calls(mut calls: Array) -> Array> { - let mut res = ArrayTrait::new(); - loop { - match calls.pop_front() { - Option::Some(call) => { - let _res = _execute_single_call(call); - res.append(_res); - }, - Option::None(_) => { - break (); - }, - }; - }; - res - } - - #[internal] - fn _execute_single_call(call: Call) -> Span { - let Call{to, selector, calldata } = call; - starknet::call_contract_syscall(to, selector, calldata.span()).unwrap() + fn constructor(ref self: ContractState, public_key: felt252) { + self.account.initializer(public_key); } } diff --git a/src/account/error.cairo b/src/account/error.cairo index 6d97660..5935670 100644 --- a/src/account/error.cairo +++ b/src/account/error.cairo @@ -1,6 +1,6 @@ -mod AccountError { - const INVALID_CALLER: felt252 = 'Account: invalid caller'; - const INVALID_TX_VERSION: felt252 = 'Account: invalid tx version'; - const INVALID_SIGNATURE: felt252 = 'Account: invalid signature'; - const UNAUTHORIZED: felt252 = 'Account: unauthorized'; +mod AccountError { // const INVALID_CALLER: felt252 = 'Account: invalid caller'; +// const INVALID_TX_VERSION: felt252 = 'Account: invalid tx version'; +// const INVALID_SIGNATURE: felt252 = 'Account: invalid signature'; +// const UNAUTHORIZED: felt252 = 'Account: unauthorized'; +// const POSITION_NOT_FOUND: felt252 = 'Account: position not found'; } diff --git a/src/lib.cairo b/src/lib.cairo index c35b07b..d92596d 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -3,6 +3,11 @@ mod account { mod error; } +mod position { + mod position_manager; + mod error; +} + mod router { mod router; mod error; diff --git a/src/position/error.cairo b/src/position/error.cairo new file mode 100644 index 0000000..d2e5b86 --- /dev/null +++ b/src/position/error.cairo @@ -0,0 +1,4 @@ +mod PositionError { + const POSITION_NOT_FOUND: felt252 = 'Position: not found'; + const NOT_AUTHORIZED: felt252 = 'Position: not authorized'; +} diff --git a/src/position/position_manager.cairo b/src/position/position_manager.cairo new file mode 100755 index 0000000..960fe8e --- /dev/null +++ b/src/position/position_manager.cairo @@ -0,0 +1,125 @@ +use serde::Serde; +use starknet::ContractAddress; + +#[derive(Drop, Copy, Serde)] +struct Position { + owner: ContractAddress, + from: ContractAddress, + to: ContractAddress, + amount: u256, + period: u256, + last_swap: u256, + pause: bool +} + + +#[starknet::interface] +trait IPositionManager { + fn get_last_id(self: @TContractState) -> u32; + fn get_position(self: @TContractState, id: u32) -> Position; + fn create_position( + ref self: TContractState, + from: ContractAddress, + to: ContractAddress, + amount: u256, + period: u256 + ) -> u32; + fn pause_position(ref self: TContractState, id: u32); + fn resume_position(ref self: TContractState, id: u32); +} + +#[starknet::contract] +mod PositionManager { + use super::ContractAddress; + use swappy::position::error::PositionError; + use super::Position; + + #[storage] + struct Storage { + last_id: u32, + owner: LegacyMap, + from: LegacyMap, + to: LegacyMap, + amount: LegacyMap, + period: LegacyMap, + last_swap: LegacyMap, + pause: LegacyMap + } + // ************************************************************************* + // CONSTRUCTOR + // ************************************************************************* + + /// Constructor of the contract. + /// # Arguments + /// * `owner` - The owner address. + #[constructor] + fn constructor(ref self: ContractState, owner: ContractAddress) { //self.initialize(owner); + } + + // ************************************************************************* + // EXTERNAL FUNCTIONS + // ************************************************************************* + #[external(v0)] + impl PositionManagerImpl of super::IPositionManager { + fn get_last_id(self: @ContractState) -> u32 { + self.last_id.read() + } + + fn get_position(self: @ContractState, id: u32) -> Position { + let last_id = self.last_id.read(); + assert(id <= last_id, PositionError::POSITION_NOT_FOUND); + + Position { + owner: self.owner.read(id), + from: self.from.read(id), + to: self.to.read(id), + amount: self.amount.read(id), + period: self.period.read(id), + last_swap: self.last_swap.read(id), + pause: self.pause.read(id) + } + } + + fn create_position( + ref self: ContractState, + from: ContractAddress, + to: ContractAddress, + amount: u256, + period: u256 + ) -> u32 { + let new_id = self.last_id.read() + 1; + + self.owner.write(new_id, starknet::get_caller_address()); + self.from.write(new_id, from); + self.to.write(new_id, to); + self.amount.write(new_id, amount); + self.period.write(new_id, period); + self.last_swap.write(new_id, 0); + self.pause.write(new_id, false); + + self.last_id.write(new_id); + + new_id + } + + fn pause_position(ref self: ContractState, id: u32) { + let last_id = self.last_id.read(); + assert(id <= last_id, PositionError::POSITION_NOT_FOUND); + + let owner = self.owner.read(id); + assert(owner == starknet::get_caller_address(), PositionError::NOT_AUTHORIZED); + + self.pause.write(id, true); + } + + fn resume_position(ref self: ContractState, id: u32) { + let last_id = self.last_id.read(); + assert(id <= last_id, PositionError::POSITION_NOT_FOUND); + + let owner = self.owner.read(id); + assert(owner == starknet::get_caller_address(), PositionError::NOT_AUTHORIZED); + + self.pause.write(id, false); + } + } +} diff --git a/src/tests.cairo b/src/tests.cairo index 4858aff..f3e34bb 100644 --- a/src/tests.cairo +++ b/src/tests.cairo @@ -1,5 +1,14 @@ #[cfg(test)] -mod test_account; +mod account { + #[cfg(test)] + mod test_account; +} + +#[cfg(test)] +mod position { + #[cfg(test)] + mod test_position_manager; +} #[cfg(test)] mod router { diff --git a/src/tests/test_account.cairo b/src/tests/account/test_account.cairo similarity index 51% rename from src/tests/test_account.cairo rename to src/tests/account/test_account.cairo index 82e9e5d..b9af3d2 100755 --- a/src/tests/test_account.cairo +++ b/src/tests/account/test_account.cairo @@ -1,13 +1,17 @@ -use starknet::deploy_syscall; +use core::traits::Into; +use starknet::{ + deploy_syscall, get_contract_address, get_caller_address, ContractAddress, + contract_address_const +}; +use starknet::testing::{set_caller_address, set_contract_address, set_account_contract_address}; use openzeppelin::account::{AccountABIDispatcher, AccountABIDispatcherTrait}; use swappy::account::account::Account; -// Deploy the contract and return its dispatcher. -fn deploy(public_key: felt252) -> AccountABIDispatcher { - // Set up constructor arguments. +fn deploy(owner: ContractAddress) -> AccountABIDispatcher { + // Set up constructor arguments.AccountABIDispatcher let mut calldata = ArrayTrait::new(); - public_key.serialize(ref calldata); + owner.serialize(ref calldata); // Declare and deploy let (contract_address, _) = deploy_syscall( @@ -24,11 +28,10 @@ fn deploy(public_key: felt252) -> AccountABIDispatcher { #[available_gas(2000000000)] fn test_deploy() { // Given - let public_key: felt252 = 'test'; + let owner = contract_address_const::<'OWNER'>(); // When - let contract = deploy(public_key); - + let contract = deploy(owner); // Then - assert(contract.get_public_key() == public_key, 'wrong public key'); + assert(contract.get_public_key() == owner.into(), 'wrong public key'); } diff --git a/src/tests/position/test_position_manager.cairo b/src/tests/position/test_position_manager.cairo new file mode 100755 index 0000000..0b29ac6 --- /dev/null +++ b/src/tests/position/test_position_manager.cairo @@ -0,0 +1,159 @@ +use swappy::position::position_manager::IPositionManagerDispatcherTrait; +use core::traits::Into; +use debug::PrintTrait; +use starknet::{ + deploy_syscall, get_contract_address, get_caller_address, ContractAddress, + contract_address_const +}; +use starknet::testing::{set_caller_address, set_contract_address, set_account_contract_address}; + +use swappy::position::position_manager::{PositionManager, IPositionManagerDispatcher}; + + +fn deploy(owner: ContractAddress) -> IPositionManagerDispatcher { + // Set up constructor arguments.AccountABIDispatcher + let mut calldata = ArrayTrait::new(); + owner.serialize(ref calldata); + + // Declare and deploy + let (contract_address, _) = deploy_syscall( + PositionManager::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false + ) + .unwrap(); + + // Return the dispatcher. + // The dispatcher allows to interact with the contract based on its interface. + IPositionManagerDispatcher { contract_address } +} + +#[test] +#[available_gas(2000000000)] +fn test_create_position() { + // Given + let owner = contract_address_const::<'OWNER'>(); + let contract = deploy(owner); + set_contract_address(owner); + + // When + let position_id = contract + .create_position( + contract_address_const::<'FROM_TOKEN'>(), contract_address_const::<'TO_TOKEN'>(), 1, 60 + ); + + // Then + let position = contract.get_position(position_id); + assert(position_id == 1, 'wrong position_id'); + assert(position.owner == owner, 'wrong owner'); + assert(position.from == contract_address_const::<'FROM_TOKEN'>(), 'wrong FROM token'); + assert(position.to == contract_address_const::<'TO_TOKEN'>(), 'wrong TO token'); + assert(position.amount == 1, 'wrong amount'); + assert(position.period == 60, 'wrong period'); + assert(position.pause == false, 'wrong pause value'); + assert(position.last_swap == 0, 'wrong last_swap value'); +} + +#[test] +#[available_gas(2000000000)] +fn test_pause_position() { + // Given + let owner = contract_address_const::<'OWNER'>(); + let contract = deploy(owner); + set_contract_address(owner); + + // When + let position_id = contract + .create_position( + contract_address_const::<'FROM_TOKEN'>(), contract_address_const::<'TO_TOKEN'>(), 1, 60 + ); + contract.pause_position(position_id); + + // Then + let position = contract.get_position(position_id); + assert(position_id == 1, 'wrong position_id'); + assert(position.owner == owner, 'wrong owner'); + assert(position.from == contract_address_const::<'FROM_TOKEN'>(), 'wrong FROM token'); + assert(position.to == contract_address_const::<'TO_TOKEN'>(), 'wrong TO token'); + assert(position.amount == 1, 'wrong amount'); + assert(position.period == 60, 'wrong period'); + assert(position.pause == true, 'wrong pause value'); + assert(position.last_swap == 0, 'wrong last_swap value'); +} + +#[test] +#[available_gas(2000000000)] +#[should_panic(expected: ('Position: not authorized', 'ENTRYPOINT_FAILED',))] +fn test_pause_position_should_fail() { + // Given + let owner = contract_address_const::<'OWNER'>(); + let contract = deploy(owner); + set_contract_address(owner); + + // When + let position_id = contract + .create_position( + contract_address_const::<'FROM_TOKEN'>(), contract_address_const::<'TO_TOKEN'>(), 1, 60 + ); + + set_contract_address(contract_address_const::<'OTHER'>()); + contract.pause_position(position_id); +} + +#[test] +#[available_gas(2000000000)] +#[should_panic(expected: ('Position: not authorized', 'ENTRYPOINT_FAILED',))] +fn test_resume_position_should_fail() { + // Given + let owner = contract_address_const::<'OWNER'>(); + let contract = deploy(owner); + set_contract_address(owner); + + // When + let position_id = contract + .create_position( + contract_address_const::<'FROM_TOKEN'>(), contract_address_const::<'TO_TOKEN'>(), 1, 60 + ); + + set_contract_address(contract_address_const::<'OTHER'>()); + contract.resume_position(position_id); +} + +#[test] +#[available_gas(2000000000)] +fn test_pause_then_resume_position() { + // Given + let owner = contract_address_const::<'OWNER'>(); + let contract = deploy(owner); + set_contract_address(owner); + + // When + let position_id = contract + .create_position( + contract_address_const::<'FROM_TOKEN'>(), contract_address_const::<'TO_TOKEN'>(), 1, 60 + ); + contract.pause_position(position_id); + + // Then + let position = contract.get_position(position_id); + assert(position_id == 1, 'wrong position_id'); + assert(position.owner == owner, 'wrong owner'); + assert(position.from == contract_address_const::<'FROM_TOKEN'>(), 'wrong FROM token'); + assert(position.to == contract_address_const::<'TO_TOKEN'>(), 'wrong TO token'); + assert(position.amount == 1, 'wrong amount'); + assert(position.period == 60, 'wrong period'); + assert(position.pause == true, 'wrong pause value'); + assert(position.last_swap == 0, 'wrong last_swap value'); + + // When + contract.resume_position(position_id); + + // Then + let position = contract.get_position(position_id); + assert(position_id == 1, 'wrong position_id'); + assert(position.owner == owner, 'wrong owner'); + assert(position.from == contract_address_const::<'FROM_TOKEN'>(), 'wrong FROM token'); + assert(position.to == contract_address_const::<'TO_TOKEN'>(), 'wrong TO token'); + assert(position.amount == 1, 'wrong amount'); + assert(position.period == 60, 'wrong period'); + assert(position.pause == false, 'wrong pause value'); + assert(position.last_swap == 0, 'wrong last_swap value'); +} diff --git a/src/tests/router/test_jedi_swap_router.cairo b/src/tests/router/test_jedi_swap_router.cairo index 77a8cc9..b5f1b2c 100644 --- a/src/tests/router/test_jedi_swap_router.cairo +++ b/src/tests/router/test_jedi_swap_router.cairo @@ -66,8 +66,9 @@ fn test_set_router_address_by_owner() { let contract = deploy(owner); set_contract_address(owner); - let router_address = - contract_address_const::<0x02bcc885342ebbcbcd170ae6cafa8a4bed22bb993479f49806e72d96af94c965>(); + let router_address = contract_address_const::< + 0x02bcc885342ebbcbcd170ae6cafa8a4bed22bb993479f49806e72d96af94c965 + >(); // When contract.set_router_address(router_address); @@ -85,8 +86,9 @@ fn test_set_router_address_by_non_owner_should_fail() { let contract = deploy(owner); set_contract_address(contract_address_const::<99999>()); - let router_address = - contract_address_const::<0x02bcc885342ebbcbcd170ae6cafa8a4bed22bb993479f49806e72d96af94c965>(); + let router_address = contract_address_const::< + 0x02bcc885342ebbcbcd170ae6cafa8a4bed22bb993479f49806e72d96af94c965 + >(); // When contract.set_router_address(router_address); @@ -117,8 +119,9 @@ fn test_swap_exact_tokens_for_tokens() { let contract = deploy(owner); set_contract_address(owner); - let router_address = - contract_address_const::<0x02bcc885342ebbcbcd170ae6cafa8a4bed22bb993479f49806e72d96af94c965>(); + let router_address = contract_address_const::< + 0x02bcc885342ebbcbcd170ae6cafa8a4bed22bb993479f49806e72d96af94c965 + >(); contract.set_router_address(router_address); // When