Skip to content

Commit

Permalink
feat(amm v3 rebalancer): add function remove position
Browse files Browse the repository at this point in the history
  • Loading branch information
quanpt239 committed Oct 29, 2024
1 parent 1167d27 commit f6238ad
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 6 deletions.
7 changes: 6 additions & 1 deletion package/plus/amm-v3-rebalancer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@ library = []
backtraces = ["cosmwasm-std/backtraces"]

[dependencies]
cosmwasm-std = { version = "1.5" }
cosmwasm-std = { version = "1.5", features = ["stargate"] }
cosmwasm-storage = { version = "1.5", features = ["iterator"] }
cosmwasm-schema = { version = "1.5" }
cw20 = { version = "1.0.1" }
schemars = "0.8"
serde = { version = "1.0.204", default-features = false, features = ["derive"] }
oraiswap-v3-common = { git = "https://github.com/oraichain/oraiswap-v3.git", rev = "dc94a86" }
cosmos-sdk-proto = { version = "=0.19.0", default-features = false, features = [
"cosmwasm",
] }
thiserror = "1.0"
cosmwasm-crypto = "0.14"
sha3 = "0.10"
Expand Down
113 changes: 113 additions & 0 deletions package/plus/amm-v3-rebalancer/src/asset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
use cosmos_sdk_proto::{
cosmos::{authz::v1beta1::MsgExec, bank::v1beta1::MsgSend, base::v1beta1::Coin as ProtoCoin},
traits::{Message, MessageExt},
};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{to_json_binary, BankMsg, Binary, Coin, CosmosMsg, Env, Uint128, WasmMsg};
use cw20::Cw20ExecuteMsg;
use oraiswap_v3_common::asset::AssetInfo;

use crate::error::ContractError;

#[cw_serde]
pub struct Asset {
pub info: AssetInfo,
pub amount: Uint128,
}

impl Asset {
pub fn new(info: AssetInfo, amount: Uint128) -> Self {
Self { info, amount }
}

pub fn transfer(
&self,
msgs: &mut Vec<CosmosMsg>,
recipient: String,
) -> Result<(), ContractError> {
if !self.amount.is_zero() {
match &self.info {
AssetInfo::Token { contract_addr } => {
msgs.push(
WasmMsg::Execute {
contract_addr: contract_addr.to_string(),
msg: to_json_binary(&Cw20ExecuteMsg::Transfer {
recipient,
amount: self.amount,
})?,
funds: vec![],
}
.into(),
);
}
AssetInfo::NativeToken { denom } => msgs.push(
BankMsg::Send {
to_address: recipient,
amount: vec![Coin {
amount: self.amount,
denom: denom.to_string(),
}],
}
.into(),
),
}
}
Ok(())
}

pub fn transfer_from(
&self,
env: &Env,
msgs: &mut Vec<CosmosMsg>,
allower: String,
recipient: String,
) -> Result<(), ContractError> {
if !self.amount.is_zero() {
match &self.info {
AssetInfo::Token { contract_addr } => {
msgs.push(
WasmMsg::Execute {
contract_addr: contract_addr.to_string(),
msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom {
owner: allower.to_string(),
recipient,
amount: self.amount,
})?,
funds: vec![],
}
.into(),
);
}
AssetInfo::NativeToken { denom } => {
let send = MsgSend {
from_address: allower.to_string(),
to_address: recipient.to_string(),
amount: vec![ProtoCoin {
denom: denom.clone(),
amount: self.amount.to_string(),
}],
};
let send_any_result = send.to_any();
if send_any_result.is_err() {
return Ok(());
}
let stargate_value = Binary::from(
MsgExec {
grantee: env.contract.address.to_string(),
msgs: vec![send_any_result.unwrap()],
}
.encode_to_vec(),
);

let stargate = CosmosMsg::Stargate {
type_url: "/cosmos.authz.v1beta1.MsgExec".to_string(),
value: stargate_value,
};
msgs.push(stargate)
}
}
}

Ok(())
}
}
122 changes: 119 additions & 3 deletions package/plus/amm-v3-rebalancer/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::{
entry_point, to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo,
Response, StdResult,
entry_point, to_json_binary, Addr, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo,
Response, StdResult, WasmMsg,
};
use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg::Balance as Cw20Balance};
use oraiswap_v3_common::{
oraiswap_v3_msg::{ExecuteMsg as OraiswapV3ExecuteMsg, QueryMsg as OraiswapV3QueryMsg},
storage::{Pool, PoolKey, Position},
};

use crate::error::ContractError;
Expand Down Expand Up @@ -34,7 +39,7 @@ pub fn instantiate(
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
_env: Env,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
Expand All @@ -45,6 +50,8 @@ pub fn execute(
wallet,
amm_v3,
} => update_config(deps, info, owner, executor, wallet, amm_v3),
ExecuteMsg::BurnPosition { token_id } => burn_position(deps, info, env, token_id),
ExecuteMsg::SendToken { denom } => send_token(deps, info, env, denom),
}
}

Expand Down Expand Up @@ -78,6 +85,115 @@ fn update_config(
Ok(Response::new().add_attributes(vec![("action", "update_config")]))
}

fn burn_position(
deps: DepsMut,
info: MessageInfo,
env: Env,
token_id: u64,
) -> Result<Response, ContractError> {
let config = CONFIG.load(deps.storage)?;
if info.sender != config.executor {
return Err(ContractError::Unauthorized {});
}
let position_info: Position = deps.querier.query_wasm_smart(
config.amm_v3.to_string(),
&OraiswapV3QueryMsg::NftInfo { token_id },
)?;

let mut messages = vec![
CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: config.amm_v3.to_string(),
msg: to_json_binary(&OraiswapV3ExecuteMsg::Burn { token_id })?,
funds: vec![],
}),
CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: env.contract.address.to_string(),
msg: to_json_binary(&ExecuteMsg::SendToken {
denom: position_info.clone().pool_key.token_x,
})?,
funds: vec![],
}),
CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: env.contract.address.to_string(),
msg: to_json_binary(&ExecuteMsg::SendToken {
denom: position_info.clone().pool_key.token_y,
})?,
funds: vec![],
}),
];

let pool_info: Pool = deps.querier.query_wasm_smart(
config.amm_v3.to_string(),
&OraiswapV3QueryMsg::Pool {
token_0: position_info.clone().pool_key.token_x,
token_1: position_info.clone().pool_key.token_y,
fee_tier: position_info.clone().pool_key.fee_tier,
},
)?;

for incentive in pool_info.incentives.iter() {
messages.push(
CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: env.contract.address.to_string(),
msg: to_json_binary(&ExecuteMsg::SendToken {
denom: incentive.reward_token.denom(),
})?,
funds: vec![],
})
)
}

Ok(Response::new()
.add_attributes(vec![
("action", "remove_position"),
("token_id", &token_id.to_string()),
])
.add_messages(messages))
}

fn send_token(
deps: DepsMut,
info: MessageInfo,
env: Env,
denom: String,
) -> Result<Response, ContractError> {
if info.sender != env.contract.address {
return Err(ContractError::Unauthorized {});
}

match deps.api.addr_validate(&denom) {
Ok(_) => {
let bal: Cw20BalanceResponse = deps.querier.query_wasm_smart(
denom,
&Cw20Balance {
address: env.contract.address.to_string(),
},
)?;
if bal.balance.is_zero() {
return Ok(Response::default());
}

return Ok(Response::new().add_attributes(vec![
("action", "send_token"),
("token", "denom"),
("amount", &bal.balance.to_string()),
]));
}
Err(_) => {
let bal = deps.querier.query_balance(env.contract.address, denom)?;
if bal.amount.is_zero() {
return Ok(Response::default());
}

return Ok(Response::new().add_attributes(vec![
("action", "send_token"),
("token", "denom"),
("amount", &bal.amount.to_string()),
]));
}
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
Expand Down
4 changes: 4 additions & 0 deletions package/plus/amm-v3-rebalancer/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use cosmwasm_std::StdError;
use thiserror::Error;
use oraiswap_v3_common::error::ContractError as OraiswapV3Error;

#[derive(Error, Debug)]
pub enum ContractError {
#[error("{0}")]
Std(#[from] StdError),

#[error("{0}")]
V3Error(#[from] OraiswapV3Error),

#[error("Unauthorized")]
Unauthorized {},
}
2 changes: 2 additions & 0 deletions package/plus/amm-v3-rebalancer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ pub mod contract;
pub mod error;
pub mod msg;
pub mod state;

pub mod asset;
10 changes: 8 additions & 2 deletions package/plus/amm-v3-rebalancer/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@ pub enum ExecuteMsg {
executor: Option<Addr>,
wallet: Option<Addr>,
amm_v3: Option<Addr>,
}
},
BurnPosition {
token_id: u64,
},
SendToken {
denom: String,
},
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(Config)]
Config
Config,
}

#[cw_serde]
Expand Down

0 comments on commit f6238ad

Please sign in to comment.