diff --git a/package/plus/amm-v3-rebalancer/src/contract.rs b/package/plus/amm-v3-rebalancer/src/contract.rs index 2c33687..34c362f 100644 --- a/package/plus/amm-v3-rebalancer/src/contract.rs +++ b/package/plus/amm-v3-rebalancer/src/contract.rs @@ -1,14 +1,17 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::{ - entry_point, to_json_binary, Addr, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, - Response, StdResult, WasmMsg, + entry_point, to_json_binary, Addr, Api, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, + MessageInfo, Response, StdResult, Uint128, WasmMsg, }; use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg::Balance as Cw20Balance}; use oraiswap_v3_common::{ + asset::AssetInfo, + math::{liquidity::Liquidity, sqrt_price::SqrtPrice}, oraiswap_v3_msg::{ExecuteMsg as OraiswapV3ExecuteMsg, QueryMsg as OraiswapV3QueryMsg}, storage::{Pool, PoolKey, Position}, }; +use crate::asset::Asset; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::state::{Config, CONFIG}; @@ -50,6 +53,28 @@ pub fn execute( wallet, amm_v3, } => update_config(deps, info, owner, executor, wallet, amm_v3), + ExecuteMsg::CreatePosition { + pool_key, + lower_tick, + upper_tick, + liquidity_delta, + slippage_limit_lower, + slippage_limit_upper, + amount_x, + amount_y, + } => create_position( + deps, + info, + env, + pool_key, + lower_tick, + upper_tick, + liquidity_delta, + slippage_limit_lower, + slippage_limit_upper, + amount_x, + amount_y, + ), ExecuteMsg::BurnPosition { token_id } => burn_position(deps, info, env, token_id), ExecuteMsg::SendToken { denom } => send_token(deps, info, env, denom), } @@ -85,6 +110,88 @@ fn update_config( Ok(Response::new().add_attributes(vec![("action", "update_config")])) } +fn create_position( + deps: DepsMut, + info: MessageInfo, + env: Env, + pool_key: PoolKey, + lower_tick: i32, + upper_tick: i32, + liquidity_delta: Liquidity, + slippage_limit_lower: SqrtPrice, + slippage_limit_upper: SqrtPrice, + amount_x: Uint128, + amount_y: Uint128, +) -> Result { + let config = CONFIG.load(deps.storage)?; + if info.sender != config.executor { + return Err(ContractError::Unauthorized {}); + } + + let mut funds: Vec = vec![]; + let mut messages = vec![]; + + collect_and_increase_allowance( + deps.api, + &env, + &pool_key.token_x, + amount_x, + &mut funds, + &mut messages, + config.wallet.to_string(), + config.amm_v3.to_string(), + )?; + collect_and_increase_allowance( + deps.api, + &env, + &pool_key.token_y, + amount_y, + &mut funds, + &mut messages, + config.wallet.to_string(), + config.amm_v3.to_string(), + )?; + + messages.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: config.amm_v3.to_string(), + msg: to_json_binary(&OraiswapV3ExecuteMsg::CreatePosition { + pool_key, + lower_tick, + upper_tick, + liquidity_delta, + slippage_limit_lower, + slippage_limit_upper, + })?, + funds, + })); + + Ok(Response::new() + .add_attributes(vec![("action", "create_position")]) + .add_messages(messages)) +} + +fn collect_and_increase_allowance( + api: &dyn Api, + env: &Env, + denom: &String, + amount: Uint128, + coins: &mut Vec, + msgs: &mut Vec, + collect_from: String, + spender: String, +) -> Result<(), ContractError> { + let asset = Asset::new(AssetInfo::from_denom(api, &denom), amount); + + // collect tokens + asset.transfer_from(env, msgs, collect_from, env.contract.address.to_string())?; + + asset + .info + .increase_allowance(coins, msgs, spender, amount)?; + + Ok(()) +} + fn burn_position( deps: DepsMut, info: MessageInfo, diff --git a/package/plus/amm-v3-rebalancer/src/msg.rs b/package/plus/amm-v3-rebalancer/src/msg.rs index 48f8733..449f79a 100644 --- a/package/plus/amm-v3-rebalancer/src/msg.rs +++ b/package/plus/amm-v3-rebalancer/src/msg.rs @@ -1,5 +1,9 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Addr; +use cosmwasm_std::{Addr, Uint128}; +use oraiswap_v3_common::{ + math::{liquidity::Liquidity, sqrt_price::SqrtPrice}, + storage::PoolKey, +}; use crate::state::Config; @@ -19,6 +23,16 @@ pub enum ExecuteMsg { wallet: Option, amm_v3: Option, }, + CreatePosition { + pool_key: PoolKey, + lower_tick: i32, + upper_tick: i32, + liquidity_delta: Liquidity, + slippage_limit_lower: SqrtPrice, + slippage_limit_upper: SqrtPrice, + amount_x: Uint128, + amount_y: Uint128, + }, BurnPosition { token_id: u64, },