Skip to content

Commit

Permalink
remove claim step. make stages obsolete. fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
NeverHappened committed Oct 25, 2023
1 parent c2784fa commit e207e8b
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 350 deletions.
Binary file removed integration-tests/artifacts/credits.wasm
Binary file not shown.
Binary file not shown.
236 changes: 53 additions & 183 deletions integration-tests/testcases/claimer.test.ts

Large diffs are not rendered by default.

125 changes: 25 additions & 100 deletions src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use cosmos_sdk_proto::cosmos::distribution::v1beta1::MsgFundCommunityPool;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_binary, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdError,
StdResult, Storage, Uint128, WasmMsg,
to_binary, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult,
Storage, Uint128,
};
use cw2::set_contract_version;
use prost::Message;
Expand All @@ -19,10 +19,9 @@ use serde_json_wasm::de::Error;

use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use crate::outer::cw20_merkle_airdrop;
use crate::state::{
Config, IbcCallbackState, InterchainAccount, OpenAckVersion, Stage, CONFIG,
IBC_CALLBACK_STATES, INTERCHAIN_ACCOUNT, INTERCHAIN_TX_IN_PROGRESS, STAGE, TRANSFER_AMOUNT,
Config, IbcCallbackState, InterchainAccount, OpenAckVersion, CONFIG, IBC_CALLBACK_STATES,
INTERCHAIN_ACCOUNT, INTERCHAIN_TX_IN_PROGRESS,
};

const ICA_ID: &str = "funder";
Expand All @@ -49,16 +48,13 @@ pub fn instantiate(
) -> Result<Response, ContractError> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

STAGE.save(deps.storage, &Stage::ClaimUnclaimed {})?;
CONFIG.save(
deps.storage,
&Config {
connection_id: msg.connection_id,
airdrop_address: deps.api.addr_validate(&msg.airdrop_address)?,
channel_id_to_hub: msg.channel_id_to_hub,
transfer_channel_id: msg.transfer_channel_id,
ibc_neutron_denom: msg.ibc_neutron_denom,
ica_timeout_seconds: msg.ica_timeout_seconds,
ibc_transfer_timeout_seconds: msg.ibc_transfer_timeout_seconds,
ibc_timeout_seconds: msg.ibc_timeout_seconds,
},
)?;
INTERCHAIN_ACCOUNT.save(deps.storage, &None)?;
Expand All @@ -83,11 +79,12 @@ pub fn execute(

match msg {
ExecuteMsg::CreateHubICA {} => execute_create_hub_ica(deps, env, info),
ExecuteMsg::ClaimUnclaimed {} => execute_claim_unclaimed(deps, env, info),
ExecuteMsg::SendClaimedTokensToICA {} => {
execute_send_claimed_tokens_to_ica(deps, env, info)
}
ExecuteMsg::FundCommunityPool {} => execute_fund_community_pool(deps, env, info),
ExecuteMsg::FundCommunityPool { amount } => {
execute_fund_community_pool(deps, env, info, amount)
}
}
}

Expand All @@ -110,34 +107,11 @@ fn execute_create_hub_ica(
Ok(Response::default().add_message(register_ica))
}

fn execute_claim_unclaimed(
deps: DepsMut<NeutronQuery>,
_env: Env,
_info: MessageInfo,
) -> NeutronResult<Response<NeutronMsg>> {
assert_stage(deps.storage, Stage::ClaimUnclaimed)?;

STAGE.save(deps.storage, &Stage::SendClaimedTokensToICA {})?;

let config = CONFIG.load(deps.storage)?;

// generate withdraw submessage and return a response
let claim_message = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: config.airdrop_address.to_string(),
msg: to_binary(&cw20_merkle_airdrop::ExecuteMsg::WithdrawAll {})?,
funds: vec![],
});

Ok(Response::default().add_message(claim_message))
}

fn execute_send_claimed_tokens_to_ica(
deps: DepsMut<NeutronQuery>,
env: Env,
info: MessageInfo,
) -> NeutronResult<Response<NeutronMsg>> {
assert_stage(deps.storage, Stage::SendClaimedTokensToICA)?;

INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &true)?;

let config = CONFIG.load(deps.storage)?;
Expand All @@ -151,15 +125,17 @@ fn execute_send_claimed_tokens_to_ica(
.query_balance(env.contract.address.clone(), NEUTRON_DENOM)?;

let (fee_funds, fee) = ibc_fee_from_funds(&info)?;
let neutron_to_send = Coin::new(
(neutron_on_balance.amount - fee_funds.amount).u128(),
NEUTRON_DENOM,
);
TRANSFER_AMOUNT.save(deps.storage, &neutron_to_send.amount)?;
let neutron_amount_to_send = neutron_on_balance.amount - fee_funds.amount;
if neutron_amount_to_send.is_zero() {
return Err(NeutronError::Std(StdError::generic_err(
"zero neutron to send".to_string(),
)));
}
let neutron_to_send = Coin::new(neutron_amount_to_send.u128(), NEUTRON_DENOM);

let send_msg = NeutronMsg::IbcTransfer {
source_port: TRANSFER_PORT.to_string(),
source_channel: config.channel_id_to_hub,
source_channel: config.transfer_channel_id,
sender: env.contract.address.to_string(),
receiver: ica.address,
token: neutron_to_send,
Expand All @@ -170,7 +146,7 @@ fn execute_send_claimed_tokens_to_ica(
timeout_timestamp: env
.block
.time
.plus_seconds(config.ibc_transfer_timeout_seconds)
.plus_seconds(config.ibc_timeout_seconds)
.nanos(),
memo: SEND_TO_ICA_MEMO.to_string(),
fee,
Expand All @@ -183,9 +159,8 @@ fn execute_fund_community_pool(
deps: DepsMut<NeutronQuery>,
_env: Env,
info: MessageInfo,
amount: Uint128,
) -> NeutronResult<Response<NeutronMsg>> {
assert_stage(deps.storage, Stage::FundCommunityPool)?;

INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &true)?;
let config = CONFIG.load(deps.storage)?;
let ica = INTERCHAIN_ACCOUNT.load(deps.storage)?.ok_or_else(|| {
Expand All @@ -194,13 +169,13 @@ fn execute_fund_community_pool(
))
})?;

let amount = CosmosCoin {
let coin = CosmosCoin {
denom: config.ibc_neutron_denom.to_string(),
amount: TRANSFER_AMOUNT.load(deps.storage)?.to_string(),
amount: amount.to_string(),
};

let ica_msg = MsgFundCommunityPool {
amount: vec![amount],
amount: vec![coin],
depositor: ica.address,
};

Expand All @@ -227,7 +202,7 @@ fn execute_fund_community_pool(
ICA_ID.to_string(),
vec![any_msg],
FUND_COMMUNITY_POOL_MEMO.to_string(),
config.ica_timeout_seconds,
config.ibc_timeout_seconds,
fee,
);

Expand All @@ -237,29 +212,17 @@ fn execute_fund_community_pool(
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::Stage {} => query_stage(deps),
QueryMsg::InterchainAccount {} => query_interchain_account(deps),
QueryMsg::TransferAmount {} => query_transfer_amount(deps),
QueryMsg::InterchainTxInProgress {} => query_interchain_tx_in_progress(deps),
QueryMsg::IbcCallbackStates {} => query_ibc_callback_states(deps),
}
}

fn query_transfer_amount(deps: Deps) -> StdResult<Binary> {
let amount = TRANSFER_AMOUNT.load(deps.storage)?;
to_binary(&amount)
}

fn query_interchain_account(deps: Deps) -> StdResult<Binary> {
let ica = INTERCHAIN_ACCOUNT.load(deps.storage)?;
to_binary(&ica)
}

fn query_stage(deps: Deps) -> StdResult<Binary> {
let stage = STAGE.load(deps.storage)?;
to_binary(&stage)
}

fn query_interchain_tx_in_progress(deps: Deps) -> StdResult<Binary> {
let ica_in_progress = INTERCHAIN_TX_IN_PROGRESS.load(deps.storage)?;
to_binary(&ica_in_progress)
Expand Down Expand Up @@ -301,28 +264,11 @@ fn sudo_response(
) -> StdResult<Response> {
INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &false)?;

let source_port = request
.source_port
.clone()
.ok_or_else(|| StdError::generic_err("source_port not found"))?;

save_ibc_callback_state(
deps.storage,
IbcCallbackState::Response(request, env.block.height),
)?;

if source_port == TRANSFER_PORT {
STAGE.save(deps.storage, &Stage::FundCommunityPool)?;
return Ok(Response::default());
}

// is ICA transaction
if let Some(ica) = INTERCHAIN_ACCOUNT.load(deps.storage)? {
if source_port == ica.port_id {
STAGE.save(deps.storage, &Stage::Done)?;
}
}

Ok(Response::default())
}

Expand Down Expand Up @@ -437,17 +383,6 @@ fn ibc_fee_from_funds(info: &MessageInfo) -> NeutronResult<(Coin, IbcFee)> {
Ok((fee_funds, fee))
}

fn assert_stage(storage: &dyn Storage, expected_stage: Stage) -> Result<(), NeutronError> {
let current_stage = STAGE.load(storage)?;
if current_stage != expected_stage {
return Err(NeutronError::Std(StdError::generic_err(format!(
"incorrect stage: {:?}",
current_stage
))));
}
Ok(())
}

fn save_ibc_callback_state(
storage: &mut dyn Storage,
callback_state: IbcCallbackState,
Expand All @@ -467,14 +402,8 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult<Response>

let new_config = {
let mut config = CONFIG.load(deps.storage)?;
if let Some(ica_timeout_seconds) = msg.ica_timeout_seconds {
config.ica_timeout_seconds = ica_timeout_seconds;
}
if let Some(ibc_transfer_timeout_seconds) = msg.ibc_transfer_timeout_seconds {
config.ibc_transfer_timeout_seconds = ibc_transfer_timeout_seconds;
}
if let Some(ibc_neutron_denom) = msg.ibc_neutron_denom {
config.ibc_neutron_denom = ibc_neutron_denom;
if let Some(ibc_timeout_seconds) = msg.ibc_timeout_seconds {
config.ibc_timeout_seconds = ibc_timeout_seconds;
}
config
};
Expand All @@ -487,9 +416,5 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult<Response>
}
}

if let Some(transfer_amount) = msg.transfer_amount {
TRANSFER_AMOUNT.save(deps.storage, &transfer_amount)?;
}

Ok(Response::default())
}
4 changes: 0 additions & 4 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@ pub enum ContractError {

#[error("Unauthorized")]
Unauthorized {},
// Add any other custom errors you like here.
// Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
#[error("Incorrect execution stage")]
IncorrectStage {},
}
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ pub mod helpers;
pub mod msg;
pub mod state;

pub mod outer;

pub use crate::error::ContractError;
36 changes: 6 additions & 30 deletions src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,34 @@ pub struct InstantiateMsg {
// connection_id between neutron-1 and cosmoshub-4 to make IBC transactions
pub connection_id: String,

// airdrop contract address that we claim neutrons from
pub airdrop_address: String,

// neutron to cosmoshub transfer channel id
pub channel_id_to_hub: String,
pub transfer_channel_id: String,

// IBC denom of neutron that was sent over our `cosmoshub_channel`
pub ibc_neutron_denom: String,

/// relative timeout for ica transactions
pub ica_timeout_seconds: u64,

/// relative timeout for ibc transfer
pub ibc_transfer_timeout_seconds: u64,
pub ibc_timeout_seconds: u64,
}

#[cw_serde]
pub enum ExecuteMsg {
/// Creates ICA. Can be called if ICA is not created or channel was closed.
CreateHubICA {},

/// Step 1. Claim unclaimed airdrops and send them to this contract.
ClaimUnclaimed {},

/// Step 2. Requires ICA to be created. Send funds to ICA account.
/// Requires ICA to be created and open. Sends funds to ICA account.
SendClaimedTokensToICA {},

/// Step 3. Requires ICA to be created and open. Fund cosmoshub community pool with sent funds.
FundCommunityPool {},
/// Requires ICA to be created and open. Funds cosmoshub community pool with given `amount` of funds.
FundCommunityPool { amount: Uint128 },
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(crate::state::Stage)]
Stage {},

#[returns(Option<crate::state::InterchainAccount>)]
InterchainAccount {},

#[returns(cosmwasm_std::Uint128)]
TransferAmount {},

#[returns(bool)]
InterchainTxInProgress {},

Expand All @@ -60,16 +45,7 @@ pub enum QueryMsg {
#[cw_serde]
pub struct MigrateMsg {
/// timeout for ica transactions
pub ica_timeout_seconds: Option<u64>,

/// relative timeout for ibc transfer
pub ibc_transfer_timeout_seconds: Option<u64>,

/// fund community pool amount
pub transfer_amount: Option<Uint128>,

/// IBC of untrn on gaia network
pub ibc_neutron_denom: Option<String>,
pub ibc_timeout_seconds: Option<u64>,

// ica address to send funds to
pub ica_address: Option<String>,
Expand Down
11 changes: 0 additions & 11 deletions src/outer.rs

This file was deleted.

Loading

0 comments on commit e207e8b

Please sign in to comment.