Skip to content

Commit 9c2fac1

Browse files
committed
add support for cw20 alliances and ginkou usdc proxy
1 parent d40231a commit 9c2fac1

File tree

22 files changed

+469
-44
lines changed

22 files changed

+469
-44
lines changed

Cargo.lock

Lines changed: 20 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
22
members = [
33
"contracts/amp-governance/*",
4+
"contracts/proxies/*",
45
"contracts/dao-lst",
56
"contracts/alliance-hub-lst",
67
"contracts/lst-factory",

contracts/alliance-hub-lst/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "eris-alliance-hub-lst-terra"
2+
name = "eris-alliance-hub-lst-whitewhale"
33
version = "1.2.0"
44
authors = ["devs <devs@erisprotocol.com>"]
55
edition = "2018"
@@ -17,7 +17,7 @@ X-injective-X = []
1717
X-osmosis-X = []
1818
X-sei-X = []
1919
X-terra-X = []
20-
default = ["X-terra-X"]
20+
default = ["X-whitewhale-X"]
2121

2222
[dependencies]
2323
cosmwasm-std = { version = "1.1.3", features = ["staking"] }

contracts/dao-lst/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "eris-dao-lst-terra"
2+
name = "eris-dao-lst-whitewhale"
33
version = "1.0.1"
44
authors = ["devs <devs@erisprotocol.com>"]
55
edition = "2018"
@@ -17,7 +17,7 @@ X-injective-X = []
1717
X-osmosis-X = []
1818
X-sei-X = []
1919
X-terra-X = []
20-
default = ["X-terra-X"]
20+
default = ["X-whitewhale-X"]
2121

2222
[dependencies]
2323
cosmwasm-std = { version = "1.1.3", features = ["staking"] }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[alias]
2+
wasm = "build --release --lib --target wasm32-unknown-unknown"
3+
unit-test = "test --lib"
4+
schema = "run --example schema_ginkou_usdc_proxy"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[package]
2+
name = "eris-ginkou-usdc-proxy"
3+
version = "1.0.0"
4+
authors = ["devs <devs@erisprotocol.com>"]
5+
edition = "2021"
6+
7+
exclude = [
8+
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
9+
"contract.wasm",
10+
"hash.txt",
11+
]
12+
13+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
14+
15+
[lib]
16+
crate-type = ["cdylib", "rlib"]
17+
18+
19+
[features]
20+
# for more explicit tests, cargo test --features=backtraces
21+
backtraces = ["cosmwasm-std/backtraces"]
22+
# use library feature to disable all instantiate/execute/query exports
23+
library = []
24+
25+
26+
[dependencies]
27+
cosmwasm-std = "1.1.3"
28+
cosmwasm-schema = "1.1.3"
29+
cw2 = "0.13.2"
30+
cw20 = "1.1.0"
31+
cw-storage-plus = "0.15.1"
32+
cw-ownable = "0.5.1"
33+
schemars = "0.8.10"
34+
serde = { version = "1.0.145", default-features = false, features = ["derive"] }
35+
thiserror = { version = "1.0.31" }
36+
eris = { git = "https://github.com/erisprotocol/contracts-tokenfactory.git", default-features = false, rev = "f38bd370400dd9873e6872538ee10e3602b19684" }
37+
astroport = { git = "https://github.com/astroport-fi/astroport-core.git", default-features = false, rev = "3b44a4044b823a145730f66ffaf7ae4205b2cd35" }
38+
39+
40+
[dev-dependencies]
41+
cw-multi-test = "0.15.1"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Ginkou USDC Swap Proxy
2+
3+
This proxy is for using the swap interface to swap between mUSDC and USDC on Migaloo through Ginkou.
4+
It is used for auto compounding WHALE -> USDC -> mUSDC on Migaloo.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use cosmwasm_schema::write_api;
2+
use eris_ginkou_usdc_proxy::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
3+
4+
fn main() {
5+
write_api! {
6+
instantiate: InstantiateMsg,
7+
query: QueryMsg,
8+
execute: ExecuteMsg,
9+
migrate: MigrateMsg
10+
}
11+
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
const CONTRACT_NAME: &str = "eris-ginkou-usdc-proxy";
2+
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
3+
4+
use crate::{
5+
error::{ContractError, ContractResult, CustomResult},
6+
ginkou::Ginkou,
7+
msg::{CallbackMsg, Config, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, ReceiveMsg},
8+
state::CONFIG,
9+
};
10+
use astroport::asset::{native_asset_info, token_asset_info, AssetInfoExt, PairInfo};
11+
12+
#[cfg(not(feature = "library"))]
13+
use cosmwasm_std::entry_point;
14+
use cosmwasm_std::{
15+
from_binary, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response,
16+
StdResult, Storage, WasmMsg,
17+
};
18+
use cw2::set_contract_version;
19+
use cw20::Cw20ReceiveMsg;
20+
21+
#[cfg_attr(not(feature = "library"), entry_point)]
22+
pub fn instantiate(
23+
deps: DepsMut,
24+
_env: Env,
25+
_info: MessageInfo,
26+
msg: InstantiateMsg,
27+
) -> ContractResult {
28+
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
29+
30+
CONFIG.save(
31+
deps.storage,
32+
&Config {
33+
ginkou: Ginkou {
34+
contract: deps.api.addr_validate(&msg.ginkou)?,
35+
usdc_denom: msg.usdc_denom,
36+
musdc_addr: deps.api.addr_validate(&msg.musdc_addr)?,
37+
},
38+
},
39+
)?;
40+
Ok(Response::default())
41+
}
42+
43+
#[cfg_attr(not(feature = "library"), entry_point)]
44+
pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> ContractResult {
45+
match msg {
46+
ExecuteMsg::Receive(cw20_msg) => receive(deps, env, info, cw20_msg),
47+
ExecuteMsg::Swap {
48+
offer_asset,
49+
to,
50+
..
51+
} => {
52+
offer_asset.assert_sent_native_token_balance(&info)?;
53+
let config = CONFIG.load(deps.storage)?;
54+
55+
if offer_asset.info != native_asset_info(config.ginkou.usdc_denom.clone()) {
56+
return Err(ContractError::ExpectingUsdcToken(offer_asset.info.to_string()));
57+
}
58+
59+
Ok(Response::new()
60+
.add_attribute("action", "virtual-swap")
61+
.add_message(config.ginkou.deposit_usdc(offer_asset.amount.u128())?)
62+
.add_message(send_to(
63+
deps,
64+
&env,
65+
to.unwrap_or(info.sender.to_string()),
66+
token_asset_info(config.ginkou.musdc_addr),
67+
)?))
68+
},
69+
ExecuteMsg::Callback(callback_msg) => callback(deps, env, info, callback_msg),
70+
}
71+
}
72+
73+
fn receive(deps: DepsMut, env: Env, info: MessageInfo, cw20_msg: Cw20ReceiveMsg) -> ContractResult {
74+
match from_binary(&cw20_msg.msg)? {
75+
ReceiveMsg::Swap {
76+
to,
77+
..
78+
} => {
79+
let config = CONFIG.load(deps.storage)?;
80+
81+
if info.sender != config.ginkou.musdc_addr {
82+
return Err(ContractError::ExpectingMusdcToken(info.sender.into()));
83+
}
84+
85+
Ok(Response::new()
86+
.add_attribute("action", "virtual-swap_receive")
87+
.add_message(config.ginkou.withdraw_msg(cw20_msg.amount)?)
88+
.add_message(send_to(
89+
deps,
90+
&env,
91+
to.unwrap_or(info.sender.to_string()),
92+
native_asset_info(config.ginkou.usdc_denom),
93+
)?))
94+
},
95+
}
96+
}
97+
98+
fn send_to(
99+
deps: DepsMut,
100+
env: &Env,
101+
to: String,
102+
asset_info: astroport::asset::AssetInfo,
103+
) -> CustomResult<CosmosMsg> {
104+
let receiver = deps.api.addr_validate(&to)?;
105+
Ok(CosmosMsg::Wasm(WasmMsg::Execute {
106+
contract_addr: env.contract.address.to_string(),
107+
msg: to_binary(&ExecuteMsg::Callback(CallbackMsg::SendTo {
108+
to: receiver,
109+
asset_info,
110+
}))?,
111+
funds: vec![],
112+
}))
113+
}
114+
115+
fn callback(
116+
deps: DepsMut,
117+
env: Env,
118+
info: MessageInfo,
119+
callback_msg: CallbackMsg,
120+
) -> ContractResult {
121+
if env.contract.address != info.sender {
122+
return Err(ContractError::CallbackOnlyCalledByContract {});
123+
}
124+
125+
match callback_msg {
126+
CallbackMsg::SendTo {
127+
to: receiver,
128+
asset_info: token,
129+
} => {
130+
let amount = token.query_pool(&deps.querier, env.contract.address)?;
131+
let send = token.with_balance(amount).into_msg(receiver)?;
132+
133+
Ok(Response::new().add_attribute("action", "callback-send_to").add_message(send))
134+
},
135+
}
136+
}
137+
138+
#[cfg_attr(not(feature = "library"), entry_point)]
139+
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
140+
match msg {
141+
QueryMsg::Config {} => to_binary(&get_config(deps.storage)?),
142+
QueryMsg::Pair {} => to_binary(&query_pair(deps, env)?),
143+
}
144+
}
145+
146+
pub fn query_pair(deps: Deps, env: Env) -> StdResult<PairInfo> {
147+
let config = CONFIG.load(deps.storage)?;
148+
149+
Ok(PairInfo {
150+
asset_infos: vec![
151+
native_asset_info(config.ginkou.usdc_denom),
152+
token_asset_info(config.ginkou.musdc_addr),
153+
],
154+
contract_addr: env.contract.address.clone(),
155+
liquidity_token: env.contract.address,
156+
pair_type: astroport::factory::PairType::Custom("virtual".to_string()),
157+
})
158+
}
159+
160+
fn get_config(store: &dyn Storage) -> StdResult<Config> {
161+
CONFIG.load(store)
162+
}
163+
164+
#[cfg_attr(not(feature = "library"), entry_point)]
165+
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> ContractResult {
166+
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
167+
168+
Ok(Response::new()
169+
.add_attribute("new_contract_name", CONTRACT_NAME)
170+
.add_attribute("new_contract_version", CONTRACT_VERSION))
171+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use std::num::TryFromIntError;
2+
3+
use cosmwasm_std::{Response, StdError};
4+
use cw_ownable::OwnershipError;
5+
use thiserror::Error;
6+
7+
pub type ContractResult = Result<Response, ContractError>;
8+
pub type CustomResult<T> = Result<T, ContractError>;
9+
10+
/// This enum describes hub contract errors
11+
#[derive(Error, Debug, PartialEq)]
12+
pub enum ContractError {
13+
#[error("{0}")]
14+
Std(#[from] StdError),
15+
16+
#[error("{0}")]
17+
TryFromInt(#[from] TryFromIntError),
18+
19+
#[error("{0}")]
20+
Ownership(#[from] OwnershipError),
21+
22+
#[error("not supported")]
23+
NotSupported,
24+
25+
#[error("callback only callable by contract")]
26+
CallbackOnlyCalledByContract,
27+
28+
#[error("Expecting USDC coin, received {0}")]
29+
ExpectingUsdcToken(String),
30+
31+
#[error("Expecting mUSDC token, received {0}")]
32+
ExpectingMusdcToken(String),
33+
}

0 commit comments

Comments
 (0)