Skip to content

Commit

Permalink
implement provide liquidity functionality in oraiswap factory
Browse files Browse the repository at this point in the history
  • Loading branch information
vuonghuuhung committed Dec 16, 2024
1 parent 2889273 commit b89ba34
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 17 deletions.
6 changes: 0 additions & 6 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@
"prettier.jsxSingleQuote": false,
"prettier.printWidth": 120,
"typescript.tsdk": "node_modules/typescript/lib",
"rust-analyzer.cargo.extraEnv": {
"CARGO_TARGET_DIR": "${userHome}/.cargo/target/analyzer"
},
"rust-analyzer.linkedProjects": [
"./contracts/oraiswap_staking/Cargo.toml"
]
}
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions contracts/oraiswap_factory/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ crate-type = ["cdylib", "rlib"]
backtraces = ["cosmwasm-std/backtraces"]

[dependencies]
cw2 = { workspace = true }
cw20 = { workspace = true }
cw20-base = { workspace = true }
cosmwasm-std = { workspace = true }
cosmwasm-storage = { workspace = true }
cw-storage-plus = { workspace = true, features = ["iterator"] }
Expand Down
122 changes: 114 additions & 8 deletions contracts/oraiswap_factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ use std::convert::TryFrom;
use cosmwasm_std::entry_point;

use cosmwasm_std::{
to_json_binary, Addr, Binary, CanonicalAddr, Deps, DepsMut, Env, MessageInfo, Reply, Response,
StdError, StdResult, SubMsg, WasmMsg,
to_json_binary, Addr, Binary, CanonicalAddr, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env,
MessageInfo, Reply, Response, StdError, StdResult, SubMsg, WasmMsg,
};
use cw20::Cw20ExecuteMsg;
use oraiswap::error::ContractError;
use oraiswap::querier::query_pair_info_from_pair;
use oraiswap::response::MsgInstantiateContractResponse;

use crate::state::{read_pairs, Config, CONFIG, PAIRS};

use oraiswap::asset::{pair_key, AssetInfo, PairInfo, PairInfoRaw};
use oraiswap::asset::{self, pair_key, Asset, AssetInfo, PairInfo, PairInfoRaw};
use oraiswap::factory::{
ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, PairsResponse, QueryMsg,
ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, PairsResponse, ProvideLiquidityParams,
QueryMsg,
};
use oraiswap::pair::{
InstantiateMsg as PairInstantiateMsg, DEFAULT_COMMISSION_RATE, DEFAULT_OPERATOR_FEE,
Expand Down Expand Up @@ -63,13 +65,26 @@ pub fn execute(
asset_infos,
pair_admin,
operator,
} => execute_create_pair(deps, env, info, asset_infos, pair_admin, operator),
provide_liquidity,
} => execute_create_pair(
deps,
env,
info,
asset_infos,
pair_admin,
operator,
provide_liquidity,
),
ExecuteMsg::AddPair { pair_info } => execute_add_pair_manually(deps, env, info, pair_info),
ExecuteMsg::MigrateContract {
contract_addr,
new_code_id,
msg,
} => migrate_pair(deps, env, info, contract_addr, new_code_id, msg),
ExecuteMsg::ProvideLiquidity {
assets,
receiver,
} => execute_provide_liquidity(deps, env, info, assets, receiver),
}
}

Expand Down Expand Up @@ -135,10 +150,11 @@ pub fn execute_update_config(
pub fn execute_create_pair(
deps: DepsMut,
env: Env,
_info: MessageInfo,
info: MessageInfo,
asset_infos: [AssetInfo; 2],
pair_admin: Option<String>,
operator: Option<String>,
provide_liquidity: Option<ProvideLiquidityParams>,
) -> Result<Response, ContractError> {
let config: Config = CONFIG.load(deps.storage)?;
let raw_infos = [
Expand Down Expand Up @@ -169,6 +185,40 @@ pub fn execute_create_pair(

let operator_addr = operator.map(|op| deps.api.addr_validate(&op)).transpose()?;

// if provide_liquidity is not None, transfer all cw20 tokens to this contract
let mut messages: Vec<CosmosMsg> = vec![];

if let Some(ProvideLiquidityParams {
assets,
slippage_tolerance,
receiver,
}) = provide_liquidity
{
for asset in &assets {
// If the pool is token contract, then we need to execute TransferFrom msg to receive funds
if let AssetInfo::Token { contract_addr, .. } = &asset.info {
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract_addr.to_owned().into(),
msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom {
owner: info.sender.to_string(),
recipient: env.contract.address.to_string(),
amount: asset.amount,
})?,
funds: vec![],
}));
}
}

messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: env.contract.address.to_string(),
msg: to_json_binary(&ExecuteMsg::ProvideLiquidity {
assets,
receiver,
})?,
funds: info.funds,
}));
}

Ok(Response::new()
.add_submessage(SubMsg::reply_on_success(
WasmMsg::Instantiate {
Expand All @@ -191,10 +241,11 @@ pub fn execute_create_pair(
.add_attributes(vec![
("action", "create_pair"),
("pair", &format!("{}-{}", asset_infos[0], asset_infos[1])),
]))
])
.add_messages(messages))
}

// Anyone can execute it to create swap pair
// Only owner can execute it
pub fn execute_add_pair_manually(
deps: DepsMut,
_env: Env,
Expand Down Expand Up @@ -245,6 +296,61 @@ pub fn execute_add_pair_manually(
]))
}

pub fn execute_provide_liquidity(
deps: DepsMut,
_env: Env,
info: MessageInfo,
assets: [Asset; 2],
receiver: Option<Addr>,
) -> Result<Response, ContractError> {
let asset_infos = [assets[0].info.clone(), assets[1].info.clone()];
let pair_key = pair_key(&asset_infos.map(|a| a.to_raw(deps.api).unwrap()));
let pair_raw = PAIRS.load(deps.storage, &pair_key)?;
let pair_contract = deps.api.addr_humanize(&pair_raw.contract_addr)?;

let receiver = receiver.unwrap_or(info.sender.clone());

// Transfer native asset to pair contract
let mut funds: Vec<Coin> = vec![];
let mut cw20_msgs: Vec<CosmosMsg> = vec![];
for (_i, asset) in assets.iter().enumerate() {
match &asset.info {
AssetInfo::NativeToken { denom } => {
funds.push(Coin {
denom: denom.clone(),
amount: asset.amount,
});
}
AssetInfo::Token { contract_addr, .. } => {
cw20_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract_addr.to_owned().into(),
msg: to_json_binary(&Cw20ExecuteMsg::IncreaseAllowance {
spender: pair_contract.to_string(),
amount: asset.amount,
expires: None,
})?,
funds: vec![],
}));
}
}
}

// Execute provide liquidity
let provide_msg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: pair_contract.to_string(),
msg: to_json_binary(&oraiswap::pair::ExecuteMsg::ProvideLiquidity {
assets,
slippage_tolerance: None,
receiver: Some(receiver),
})?,
funds,
});

Ok(Response::new()
.add_messages(cw20_msgs)
.add_message(provide_msg))
}

/// This just stores the result for future query
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
Expand Down
16 changes: 14 additions & 2 deletions packages/oraiswap/src/factory.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, Binary};
use cosmwasm_std::{Addr, Binary, Decimal};

use crate::asset::{AssetInfo, PairInfo};
use crate::asset::{Asset, AssetInfo, PairInfo};

#[cw_serde]
pub struct InstantiateMsg {
Expand All @@ -27,6 +27,7 @@ pub enum ExecuteMsg {
asset_infos: [AssetInfo; 2],
pair_admin: Option<String>,
operator: Option<String>,
provide_liquidity: Option<ProvideLiquidityParams>
},
AddPair {
pair_info: PairInfo,
Expand All @@ -36,6 +37,10 @@ pub enum ExecuteMsg {
new_code_id: u64,
msg: Binary,
},
ProvideLiquidity {
assets: [Asset; 2],
receiver: Option<Addr>,
}
}

#[cw_serde]
Expand Down Expand Up @@ -70,3 +75,10 @@ pub struct MigrateMsg {}
pub struct PairsResponse {
pub pairs: Vec<PairInfo>,
}

#[cw_serde]
pub struct ProvideLiquidityParams {
pub assets: [Asset; 2],
pub slippage_tolerance: Option<Decimal>,
pub receiver: Option<Addr>,
}
2 changes: 1 addition & 1 deletion packages/oraiswap/src/pair.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::convert::TryInto;

use crate::{
asset::{Asset, AssetInfo, PairInfo, PairInfoRaw},
asset::{Asset, AssetInfo, PairInfo},
error::ContractError,
};
use cosmwasm_schema::{cw_serde, QueryResponses};
Expand Down
1 change: 1 addition & 0 deletions packages/oraiswap/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ impl MockApp {
asset_infos: asset_infos.clone(),
pair_admin: Some("admin".to_string()),
operator: Some("operator".to_string()),
provide_liquidity: None,
},
&[],
)
Expand Down

0 comments on commit b89ba34

Please sign in to comment.