diff --git a/config/osmosis-testnet-config.json b/config/osmosis-testnet-config.json index 0eafa15..fe066ae 100644 --- a/config/osmosis-testnet-config.json +++ b/config/osmosis-testnet-config.json @@ -1,7 +1 @@ -{ - "PREFIX": "osmo", - "CHAIN_ID": "osmo-test-5", - "RPC": "https://rpc.osmotest5.osmosis.zone:443", - "CONTRACT_CODE": "4249", - "CONTRACT_ADDRESS": "osmo1j6v7z76em9ye5jcee22agw9j6g5tmqk7nyg6vcy5cmyk406wgrnq8u0ujc" -} \ No newline at end of file +{ "PREFIX":"osmo", "CHAIN_ID":"osmo-test-5", "RPC":"https://rpc.osmotest5.osmosis.zone:443", "CONTRACT_CODE":"4257", "CONTRACT_ADDRESS":"osmo1n9qe5jjq3w3mc4pgz7jswknrluq6dwzdw2hzc8apddqw4k0p2ulqg5xxee" } diff --git a/contracts/eldorado-aggregator-osmosis/schema/eldorado-aggregator-osmosis.json b/contracts/eldorado-aggregator-osmosis/schema/eldorado-aggregator-osmosis.json index 69e3de5..aeed86d 100644 --- a/contracts/eldorado-aggregator-osmosis/schema/eldorado-aggregator-osmosis.json +++ b/contracts/eldorado-aggregator-osmosis/schema/eldorado-aggregator-osmosis.json @@ -22,9 +22,15 @@ "swap_in": { "type": "object", "required": [ + "pool_id", "vault_address" ], "properties": { + "pool_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, "vault_address": { "type": "string" } @@ -44,7 +50,7 @@ "swap_out": { "type": "object", "required": [ - "denom_out", + "pool_id", "user_address" ], "properties": { @@ -54,8 +60,10 @@ "null" ] }, - "denom_out": { - "type": "string" + "pool_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "user_address": { "type": "string" diff --git a/contracts/eldorado-aggregator-osmosis/src/actions/execute.rs b/contracts/eldorado-aggregator-osmosis/src/actions/execute.rs index c4b1efc..aee1ae1 100644 --- a/contracts/eldorado-aggregator-osmosis/src/actions/execute.rs +++ b/contracts/eldorado-aggregator-osmosis/src/actions/execute.rs @@ -1,11 +1,9 @@ -use std::str::FromStr; - use cosmwasm_std::{CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, SubMsg, Uint128}; use osmosis_std::types::{ cosmos::base::v1beta1::Coin, osmosis::{ - gamm::v1beta1::{MsgSwapExactAmountIn, PoolAsset}, + gamm::v1beta1::{MsgSwapExactAmountIn, Pool}, poolmanager::v1beta1::SwapAmountInRoute, }, }; @@ -14,24 +12,31 @@ use cw_utils::{must_pay, nonpayable, one_coin}; use eldorado_base::{ converters::{str_to_dec, u128_to_dec}, - eldorado_aggregator_osmosis::{ - state::{Config, CONFIG, DENOM_OSMO, RECIPIENT_PARAMETERS, SWAP_IN_REPLY, SWAP_OUT_REPLY}, - types::PairInfo, + eldorado_aggregator_osmosis::state::{ + Config, CONFIG, DENOM_OSMO, RECIPIENT_PARAMETERS, SWAP_IN_REPLY, SWAP_OUT_REPLY, }, error::ContractError, types::RecipientParameters, }; -use crate::actions::query::query_pools; +use crate::actions::query::query_pool; pub fn try_swap_in( deps: DepsMut, env: Env, info: MessageInfo, vault_address: String, + pool_id: u64, ) -> Result { let coin = one_coin(&info).map_err(|e| ContractError::CustomError { val: e.to_string() })?; - let swap_msg = get_swap_msg(&deps.as_ref(), &env, coin.amount, &coin.denom, DENOM_OSMO)?; + let swap_msg = get_swap_msg( + &deps.as_ref(), + &env, + coin.amount, + &coin.denom, + pool_id, + &None, + )?; let submsg = SubMsg::reply_on_success(swap_msg, SWAP_IN_REPLY); RECIPIENT_PARAMETERS.update( @@ -56,14 +61,19 @@ pub fn try_swap_out( env: Env, info: MessageInfo, user_address: String, - denom_out: String, + pool_id: u64, channel_id: Option, ) -> Result { - verify_ibc_parameters(&denom_out, &channel_id)?; - let amount = must_pay(&info, DENOM_OSMO) .map_err(|e| ContractError::CustomError { val: e.to_string() })?; - let swap_msg = get_swap_msg(&deps.as_ref(), &env, amount, DENOM_OSMO, &denom_out)?; + let swap_msg = get_swap_msg( + &deps.as_ref(), + &env, + amount, + DENOM_OSMO, + pool_id, + &channel_id, + )?; let submsg = SubMsg::reply_on_success(swap_msg, SWAP_OUT_REPLY); RECIPIENT_PARAMETERS.update( @@ -117,57 +127,38 @@ fn get_swap_msg( env: &Env, amount_in: Uint128, denom_in: &str, - denom_out: &str, + pool_id: u64, + channel_id: &Option, ) -> Result { - let pools = query_pools(deps.to_owned(), env.to_owned())?; - - let mut target_pool: Option = None; - - for pool in pools { - let mut asset_in_amount = Uint128::zero(); - let mut asset_out_amount = Uint128::zero(); - let mut osmo_amount = Uint128::zero(); - - for PoolAsset { token, .. } in &pool.pool_assets { - if let Some(Coin { denom, amount }) = token { - if denom == denom_in { - asset_in_amount = Uint128::from_str(amount)?; - } else if denom == denom_out { - asset_out_amount = Uint128::from_str(amount)?; - } - - if denom == DENOM_OSMO { - osmo_amount = Uint128::from_str(amount)?; - } - } - } - - if !asset_in_amount.is_zero() - && !asset_out_amount.is_zero() - && (osmo_amount - > target_pool - .clone() - .map_or(Uint128::zero(), |x| x.osmo_amount)) - { - target_pool = Some(PairInfo { - pool_id: pool.id, - asset_in_amount, - asset_out_amount, - osmo_amount, - }); - } - } + let Pool { + id, pool_assets, .. + } = query_pool(deps.to_owned(), env.to_owned(), pool_id)?; + + let asset_list = pool_assets + .into_iter() + .map(|x| -> Result { x.token.ok_or(ContractError::CoinIsNotFound) }) + .collect::, ContractError>>()?; + + let asset_in = asset_list + .iter() + .find(|x| x.denom == denom_in) + .ok_or(ContractError::CoinIsNotFound)?; + + let asset_out = asset_list + .iter() + .find(|x| x.denom != denom_in) + .ok_or(ContractError::CoinIsNotFound)?; - let pair = target_pool.ok_or(ContractError::PoolIsNotFound)?; + verify_ibc_parameters(&asset_out.denom, channel_id)?; let token_out_min_amount = (str_to_dec("0.9") * u128_to_dec(amount_in) - * (u128_to_dec(pair.asset_out_amount) / u128_to_dec(pair.asset_in_amount))) + * (str_to_dec(&asset_in.amount) / str_to_dec(&asset_in.amount))) .to_string(); let routes = vec![SwapAmountInRoute { - pool_id: pair.pool_id, - token_out_denom: denom_out.to_string(), + pool_id: id, + token_out_denom: asset_out.denom.to_owned(), }]; let swap_msg = MsgSwapExactAmountIn { @@ -184,10 +175,10 @@ fn get_swap_msg( } fn verify_ibc_parameters( - denom_out: &str, + ibc_token: &str, channel_id: &Option, ) -> Result<(), ContractError> { - if channel_id.is_some() && !denom_out.contains("ibc/") { + if channel_id.is_some() && !ibc_token.contains("ibc/") { Err(ContractError::AssetIsNotIbcToken)?; } diff --git a/contracts/eldorado-aggregator-osmosis/src/actions/query.rs b/contracts/eldorado-aggregator-osmosis/src/actions/query.rs index d4a7b81..960789c 100644 --- a/contracts/eldorado-aggregator-osmosis/src/actions/query.rs +++ b/contracts/eldorado-aggregator-osmosis/src/actions/query.rs @@ -1,19 +1,18 @@ use cosmwasm_std::{Deps, Env, StdResult}; -use osmosis_std::types::osmosis::gamm::v1beta1::{GammQuerier, Pool}; +use osmosis_std::types::osmosis::{gamm::v1beta1::Pool, poolmanager::v1beta1::PoolmanagerQuerier}; use eldorado_base::{ eldorado_aggregator_osmosis::state::{Config, CONFIG}, error::{to_std_err, ContractError}, }; -pub fn query_pools(deps: Deps, _env: Env) -> StdResult> { - GammQuerier::new(&deps.querier) - .pools(None)? - .pools - .into_iter() - .map(|x| x.try_into()) - .collect::, _>>() +pub fn query_pool(deps: Deps, _env: Env, pool_id: u64) -> StdResult { + PoolmanagerQuerier::new(&deps.querier) + .pool(pool_id)? + .pool + .ok_or(to_std_err(ContractError::PoolIsNotFound))? + .try_into() .map_err(|_| to_std_err(ContractError::PoolsCanNotBeParsed)) } diff --git a/contracts/eldorado-aggregator-osmosis/src/contract.rs b/contracts/eldorado-aggregator-osmosis/src/contract.rs index e4ddce9..91bec4d 100644 --- a/contracts/eldorado-aggregator-osmosis/src/contract.rs +++ b/contracts/eldorado-aggregator-osmosis/src/contract.rs @@ -38,12 +38,15 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::SwapIn { vault_address } => try_swap_in(deps, env, info, vault_address), + ExecuteMsg::SwapIn { + vault_address, + pool_id, + } => try_swap_in(deps, env, info, vault_address, pool_id), ExecuteMsg::SwapOut { user_address, - denom_out, + pool_id, channel_id, - } => try_swap_out(deps, env, info, user_address, denom_out, channel_id), + } => try_swap_out(deps, env, info, user_address, pool_id, channel_id), ExecuteMsg::UpdateConfig { ibc_timeout_in_mins, } => try_update_config(deps, env, info, ibc_timeout_in_mins), diff --git a/contracts/eldorado-aggregator-osmosis/testnet.sh b/contracts/eldorado-aggregator-osmosis/testnet.sh index 54f7dfd..462f89f 100755 --- a/contracts/eldorado-aggregator-osmosis/testnet.sh +++ b/contracts/eldorado-aggregator-osmosis/testnet.sh @@ -24,7 +24,7 @@ KEYRING_PASSWORD="12345678" # instantiate smart contract -CONTRACT_CODE="4249" # tx_hash: 6E2278989A4AE4595D50CD034F88DBA594673D2CD8DDD03B8D859DC877DBC0EF +CONTRACT_CODE="4261" # tx_hash: E67BADEC801E6479EE30843FF8C4CF3D2DE3B1B4E14A2D62C169BDD091159C18 # INIT="{}" # yes $KEYRING_PASSWORD | $DAEMON tx wasm instantiate $CONTRACT_CODE "$INIT" --from "dapp" --label "$DIR_NAME_SNAKE-dev" $TXFLAG --admin $DAPP_ADDRESS @@ -33,15 +33,15 @@ CONTRACT_CODE="4249" # tx_hash: 6E2278989A4AE4595D50CD034F88DBA594673D2CD8DDD03B # write data to file -CONTRACT_ADDRESS="osmo1j6v7z76em9ye5jcee22agw9j6g5tmqk7nyg6vcy5cmyk406wgrnq8u0ujc" # tx_hash: 3CF15FEA102835EDDDFAA4E7371FC0B51EB06815707361A98CCC4CF167D8A0FF +CONTRACT_ADDRESS="osmo17xvvelv6wmqvrjehn6d5kdsm4xymgux3g67sfd3ajnknzuatwffs0ehaw8" # tx_hash: 0A237B159874470BEDD006A771ED7764C4D2CD65F3359727F4EAAE217D4A07EF -R="{ -\"PREFIX\":\"$PREFIX\", -\"CHAIN_ID\":\"$CHAIN_ID\", -\"RPC\":\"$RPC\", -\"CONTRACT_CODE\":\"$CONTRACT_CODE\", -\"CONTRACT_ADDRESS\":\"$CONTRACT_ADDRESS\" -}" +# R="{ +# \"PREFIX\":\"$PREFIX\", +# \"CHAIN_ID\":\"$CHAIN_ID\", +# \"RPC\":\"$RPC\", +# \"CONTRACT_CODE\":\"$CONTRACT_CODE\", +# \"CONTRACT_ADDRESS\":\"$CONTRACT_ADDRESS\" +# }" # echo $R > "../../config/${DAEMON::-1}-testnet-config.json" @@ -51,11 +51,17 @@ R="{ # CONFIG=$($DAEMON q wasm contract-state smart $CONTRACT_ADDRESS "$CONFIG_QUERY_MSG" --node $RPC --chain-id $CHAIN_ID --output json) # echo $CONFIG +# # tx_hash: 2E2E3E8999AB3EAD3DF3966C8E2827EE068C7EF95BA109EF46050F6D9B5846DC +# ATOM="ibc/B28CFD38D84A480EF2A03AC575DCB05004D934A603A5A642888847BCDA6340C0" +# SWAP_RES=$(yes $KEYRING_PASSWORD | $DAEMON tx gamm swap-exact-amount-in "100$ATOM" "1" --swap-route-denoms "uosmo" --swap-route-pool-ids 151 --from=$(echo $DAPP_ADDRESS) $TXFLAG --output json) +# echo $SWAP_RES # Execute SwapIn to swap 0.0001 ATOM -> OSMO and send to vault with memo # tx_hash: # 1) add vault address to compose 'SWAP_IN_MSG' -SWAP_IN_MSG="{\"swap_in\":{\"vault_address\":\"$VAULT_ADDRESS\"}}" +POOL_ID=151 +SWAP_IN_MSG="{\"swap_in\":{\"vault_address\":\"$VAULT_ADDRESS\",\"pool_id\":$POOL_ID}}" +echo $SWAP_IN_MSG # 2) add funds (get denom by symbol here https://raw.githubusercontent.com/osmosis-labs/assetlists/main/osmosis-1/osmosis-1.assetlist.json) # mainnet: FUNDS="100ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2" # testnet: @@ -66,16 +72,16 @@ SWAP_IN_RES=$(yes $KEYRING_PASSWORD | $DAEMON tx wasm execute $CONTRACT_ADDRESS echo $SWAP_IN_RES -# Execute SwapOut to swap 0.0001 OSMO -> ATOM and send to user -# tx_hash: -# For SwapOut we have same steps but added optional IBC channel_id parameter required to transfer IBC token -# to native network. It also can be found here https://raw.githubusercontent.com/osmosis-labs/assetlists/main/osmosis-1/osmosis-1.assetlist.json -# For example we have 'uatom' on Osmosis with IBC denom 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2' -# The channel_id is 'channel-0'. -# There is no infra for IBC transfer on testnet. Then skip channel_id parameter -DENOM_OUT="ibc/B28CFD38D84A480EF2A03AC575DCB05004D934A603A5A642888847BCDA6340C0" -SWAP_OUT_MSG="{\"swap_out\":{\"user_address\":\"$VAULT_ADDRESS\",\"denom_out\":$DENOM_OUT}}" -FUNDS="100uosmo" -SWAP_OUT_RES=$(yes $KEYRING_PASSWORD | $DAEMON tx wasm execute $CONTRACT_ADDRESS "$SWAP_OUT_MSG" --from=$(echo $DAPP_ADDRESS) --amount "$FUNDS" $TXFLAG --output json) -echo $SWAP_OUT_RES +# # Execute SwapOut to swap 0.0001 OSMO -> ATOM and send to user +# # tx_hash: +# # For SwapOut we have same steps but added optional IBC channel_id parameter required to transfer IBC token +# # to native network. It also can be found here https://raw.githubusercontent.com/osmosis-labs/assetlists/main/osmosis-1/osmosis-1.assetlist.json +# # For example we have 'uatom' on Osmosis with IBC denom 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2' +# # The channel_id is 'channel-0'. +# # There is no infra for IBC transfer on testnet. Then skip channel_id parameter +# DENOM_OUT="ibc/B28CFD38D84A480EF2A03AC575DCB05004D934A603A5A642888847BCDA6340C0" +# SWAP_OUT_MSG="{\"swap_out\":{\"user_address\":\"$VAULT_ADDRESS\",\"denom_out\":$DENOM_OUT}}" +# FUNDS="100uosmo" +# SWAP_OUT_RES=$(yes $KEYRING_PASSWORD | $DAEMON tx wasm execute $CONTRACT_ADDRESS "$SWAP_OUT_MSG" --from=$(echo $DAPP_ADDRESS) --amount "$FUNDS" $TXFLAG --output json) +# echo $SWAP_OUT_RES diff --git a/packages/eldorado-base/src/eldorado_aggregator_osmosis/msg.rs b/packages/eldorado-base/src/eldorado_aggregator_osmosis/msg.rs index 62a3352..c2b610d 100644 --- a/packages/eldorado-base/src/eldorado_aggregator_osmosis/msg.rs +++ b/packages/eldorado-base/src/eldorado_aggregator_osmosis/msg.rs @@ -10,13 +10,14 @@ pub enum ExecuteMsg { /// 2) send native Osmo to vault SwapIn { vault_address: String, // must be passed every time to ensure its actuality + pool_id: u64, }, /// Called by vault to: /// 1) swap native Osmo -> token on Osmosis /// 2) send token on Osmosis to user address on Osmosis or other Cosmos network SwapOut { user_address: String, - denom_out: String, + pool_id: u64, channel_id: Option, // must be specified to enable IBC transfer }, /// Called by admin diff --git a/packages/eldorado-base/src/eldorado_aggregator_osmosis/types.rs b/packages/eldorado-base/src/eldorado_aggregator_osmosis/types.rs deleted file mode 100644 index 7287940..0000000 --- a/packages/eldorado-base/src/eldorado_aggregator_osmosis/types.rs +++ /dev/null @@ -1,10 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::Uint128; - -#[cw_serde] -pub struct PairInfo { - pub pool_id: u64, - pub asset_in_amount: Uint128, - pub asset_out_amount: Uint128, - pub osmo_amount: Uint128, -} diff --git a/packages/eldorado-base/src/lib.rs b/packages/eldorado-base/src/lib.rs index dcf71e9..1b7d1c4 100644 --- a/packages/eldorado-base/src/lib.rs +++ b/packages/eldorado-base/src/lib.rs @@ -6,7 +6,6 @@ pub mod eldorado_aggregator_kujira { pub mod eldorado_aggregator_osmosis { pub mod msg; pub mod state; - pub mod types; } pub mod mantaswap {