From 626ee5f0c0156b2fdf15993e42b7804610d0dc95 Mon Sep 17 00:00:00 2001 From: Florian Bellotti Date: Thu, 4 Apr 2024 14:08:08 +0200 Subject: [PATCH] :sparkles: Introducing sphinx (#10) * :sparkles: Introducing sphinx * :truck: Rename sphinx to haiko * :wrench: Update haiko router --- src/adapters.cairo | 1 + src/adapters/haiko_adapter.cairo | 86 ++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/adapters/haiko_adapter.cairo diff --git a/src/adapters.cairo b/src/adapters.cairo index 087ae83..3ecc5f0 100644 --- a/src/adapters.cairo +++ b/src/adapters.cairo @@ -1,4 +1,5 @@ mod ekubo_adapter; +mod haiko_adapter; mod jediswap_adapter; mod myswap_adapter; mod myswapv2_adapter; diff --git a/src/adapters/haiko_adapter.cairo b/src/adapters/haiko_adapter.cairo new file mode 100644 index 0000000..4a5e07a --- /dev/null +++ b/src/adapters/haiko_adapter.cairo @@ -0,0 +1,86 @@ +use starknet::ContractAddress; + +#[derive(Copy, Drop, Serde, PartialEq)] +struct SwapResult { + amount_in: u256, + zero_for_one: bool, + amount_out: u256, + exact_input: bool +} + +#[starknet::interface] +trait IHaikoRouter { + fn curr_sqrt_price(self: @TContractState, market_id: felt252) -> u256; + fn base_token(self: @TContractState, market_id: felt252) -> felt252; + fn swap( + self: @TContractState, + market_id: felt252, + is_buy: bool, + amount: u256, + exact_input: bool, + threshold_sqrt_price: Option, + threshold_amount: Option, + deadline: Option + ) -> SwapResult; +} + +#[starknet::contract] +mod HaikoAdapter { + use array::ArrayTrait; + use avnu::adapters::ISwapAdapter; + use avnu::interfaces::erc20::{IERC20Dispatcher, IERC20DispatcherTrait}; + use avnu::math::sqrt_ratio::compute_sqrt_ratio_limit; + use starknet::{get_block_timestamp, ContractAddress}; + use super::{IHaikoRouterDispatcher, IHaikoRouterDispatcherTrait, SwapResult}; + use traits::Into; + + const MIN_SQRT_RATIO: u256 = 67774731328; + const MAX_SQRT_RATIO: u256 = 1475476155217232889259591669213284373330197463; + + #[storage] + struct Storage {} + + #[external(v0)] + impl HaikoAdapter of ISwapAdapter { + fn swap( + self: @ContractState, + exchange_address: ContractAddress, + token_from_address: ContractAddress, + token_from_amount: u256, + token_to_address: ContractAddress, + token_to_min_amount: u256, + to: ContractAddress, + additional_swap_params: Array, + ) { + // Verify additional_swap_params + assert(additional_swap_params.len() == 2, 'Invalid swap params'); + + // Prepare swap params + let sphinx = IHaikoRouterDispatcher { contract_address: exchange_address }; + let market_id = *additional_swap_params[0]; + let sqrt_ratio_distance: u256 = (*additional_swap_params[1]).into(); + let is_buy = sphinx.base_token(market_id) == token_to_address.into(); + let sqrt_price = sphinx.curr_sqrt_price(market_id); + let sqrt_ratio_limit = compute_sqrt_ratio_limit( + sqrt_price, sqrt_ratio_distance, is_buy, MIN_SQRT_RATIO, MAX_SQRT_RATIO + ); + let deadline = get_block_timestamp(); + + // Approve + IERC20Dispatcher { contract_address: token_from_address } + .approve(exchange_address, token_from_amount); + + // Swap + sphinx + .swap( + market_id, + is_buy, + token_from_amount, + true, + Option::Some(sqrt_ratio_limit), + Option::None, + Option::Some(deadline) + ); + } + } +}