Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Treasury FT #41

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions contracts/treasury/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
coin, to_binary, Addr, BankMsg, Binary, Decimal, Deps, DepsMut, DistributionMsg, Env,
MessageInfo, QuerierWrapper, Response, StakingMsg, StdError, StdResult, Uint128, WasmMsg,
};

use cw2::set_contract_version;
use cw20_base::allowances::{
execute_burn_from, execute_decrease_allowance, execute_increase_allowance, execute_send_from,
execute_transfer_from, query_allowance,
};
use cw20_base::contract::{
execute_burn, execute_mint, execute_send, execute_transfer, query_balance, query_token_info,
};
use cw20_base::state::{MinterData, TokenInfo, TOKEN_INFO};

use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::state::{Supply, CLAIMS};

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:cw20-staking";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

// ensure the validator is registered
let vals = deps.querier.query_all_validators()?;
if !vals.iter().any(|v| v.address == msg.validator) {
return Err(ContractError::NotInValidatorSet {
validator: msg.validator,
});
}

Ok(Response::default())
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
// these all come from cw20-base to implement the cw20 standard
ExecuteMsg::transfer_treasury_fungible_token { recipient, amount } => {
Ok(execute_transfer(deps, env, info, recipient, amount)?)
}

}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::get_treasury_fungible_token_balance { address } => to_binary(&query_balance(deps, address)?),
}
}
46 changes: 46 additions & 0 deletions contracts/treasury/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use cosmwasm_std::{StdError, Uint128};
use thiserror::Error;

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

#[error("Unauthorized")]
Unauthorized {},

#[error("Validator '{validator}' not in current validator set")]
NotInValidatorSet { validator: String },

#[error("No {denom} tokens sent")]
EmptyBalance { denom: String },

#[error("Insufficient balance in contract to process claim")]
BalanceTooSmall {},

#[error("Cannot set to own account")]
CannotSetOwnAccount {},

#[error("Invalid zero amount")]
InvalidZeroAmount {},

#[error("Duplicate initial balance addresses")]
DuplicateInitialBalanceAddresses {},
}

impl From<cw20_base::ContractError> for ContractError {
fn from(err: cw20_base::ContractError) -> Self {
match err {
cw20_base::ContractError::Std(error) => ContractError::Std(error),
cw20_base::ContractError::Unauthorized {} => ContractError::Unauthorized {},
cw20_base::ContractError::CannotSetOwnAccount {} => {
ContractError::CannotSetOwnAccount {}
}
cw20_base::ContractError::InvalidZeroAmount {} => ContractError::InvalidZeroAmount {},
// This should never happen, as this contract doesn't use logo
cw20_base::ContractError::DuplicateInitialBalanceAddresses {} => {
ContractError::DuplicateInitialBalanceAddresses {}
}
}
}
}
5 changes: 5 additions & 0 deletions contracts/treasury/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod contract;
mod error;
pub mod msg;

pub use crate::error::ContractError;
44 changes: 44 additions & 0 deletions contracts/treasury/msg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use cosmwasm_std::{Binary, Coin, Decimal, Uint128};
use cw20::Expiration;
pub use cw_controllers::ClaimsResponse;
use cw_utils::Duration;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg {
/// name of the derivative token
pub name: String,
/// symbol / ticker of the derivative token
pub symbol: String,
/// decimal places of the derivative token (for UI)
pub decimals: u8,

/// This is the validator that all tokens will be bonded to
pub validator: String,
/// This is the unbonding period of the native staking module
/// We need this to only allow claims to be redeemed after the money has arrived
pub unbonding_period: Duration,

/// this is how much the owner takes as a cut when someone unbonds
pub exit_tax: Decimal,
/// This is the minimum amount we will pull out to reinvest, as well as a minimum
/// that can be unbonded (to avoid needless staking tx)
pub min_withdrawal: Uint128,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
/// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions
transfer_treasury_fungible_token { recipient: String, amount: Uint128 },

}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
/// Implements CW20. Returns the current balance of the given address, 0 if unset.
get_treasury_fungible_token_balance { address: String },
}
5 changes: 1 addition & 4 deletions interact/tests/suite1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ async fn check_block_number() {
}

/// by requesting the full node, checks whether the account given by the config has enough native token to pay gas fee
#[ignore]

#[tokio::test]
async fn check_account() {
//let _config = Config::read_from_env();
Expand Down Expand Up @@ -184,7 +184,6 @@ async fn test_execute_increment_fail() {
// deliver_tx failed: TxResult { code: Err(5), data: None, log: Log("failed to execute message; message index: 0: Unauthorized: execute wasm contract failed"), info: Info(""), gas_wanted: Gas(2000000), gas_used: Gas(136249), events: [Event { type_str: "coin_spent", attributes: [Tag { key: Key("spender"), value: Value("wasm1quzyfdgzw42aelcdkrw2v8vnfdxsk9jkl7a4qf") }, Tag { key: Key("amount"), value: Value("2000000umlg") }] }, Event { type_str: "coin_received", attributes: [Tag { key: Key("receiver"), value: Value("wasm17xpfvakm2amg962yls6f84z3kell8c5l69j4zk") }, Tag { key: Key("amount"), value: Value("2000000umlg") }] }, Event { type_str: "transfer", attributes: [Tag { key: Key("recipient"), value: Value("wasm17xpfvakm2amg962yls6f84z3kell8c5l69j4zk") }, Tag { key: Key("sender"), value: Value("wasm1quzyfdgzw42aelcdkrw2v8vnfdxsk9jkl7a4qf") }, Tag { key: Key("amount"), value: Value("2000000umlg") }] }, Event { type_str: "message", attributes: [Tag { key: Key("sender"), value: Value("wasm1quzyfdgzw42aelcdkrw2v8vnfdxsk9jkl7a4qf") }] }, Event { type_str: "tx", attributes: [Tag { key: Key("fee"), value: Value("2000000umlg") }] }, Event { type_str: "tx", attributes: [Tag { key: Key("acc_seq"), value: Value("wasm1quzyfdgzw42aelcdkrw2v8vnfdxsk9jkl7a4qf/5") }] }, Event { type_str: "tx", attributes: [Tag { key: Key("signature"), value: Value("dHGDLpzY8zHIO/E1K6MHTNWkbF5RMlYbYzTzlIqpjzgfUfk7EO7L0hC7mHoJO+9lQJhV01JJMnAWDQToe+RogA==") }] }], codespace: Codespace("wasm") }
}

#[ignore]
#[tokio::test]
async fn test_execute_increment() {
let mnemonic = "coyote electric million purchase tennis skin quiz inside helmet call glimpse pulse turkey hint maze iron festival run bomb regular legend prepare service angry".to_string();
Expand Down Expand Up @@ -247,7 +246,6 @@ async fn test_execute_reset() {
// [{"events":[{"type":"coin_received","attributes":[{"key":"receiver","value":"wasm1rpfxxy379eq2lq8wjz0lcke9ql49p5uzx2246vx6pml7yvd954tstdaaae"},{"key":"amount","value":"10000umlg"}]},{"type":"coin_spent","attributes":[{"key":"spender","value":"wasm1quzyfdgzw42aelcdkrw2v8vnfdxsk9jkl7a4qf"},{"key":"amount","value":"10000umlg"}]},{"type":"execute","attributes":[{"key":"_contract_address","value":"wasm1rpfxxy379eq2lq8wjz0lcke9ql49p5uzx2246vx6pml7yvd954tstdaaae"}]},{"type":"message","attributes":[{"key":"action","value":"/cosmwasm.wasm.v1.MsgExecuteContract"},{"key":"module","value":"wasm"},{"key":"sender","value":"wasm1quzyfdgzw42aelcdkrw2v8vnfdxsk9jkl7a4qf"}]},{"type":"transfer","attributes":[{"key":"recipient","value":"wasm1rpfxxy379eq2lq8wjz0lcke9ql49p5uzx2246vx6pml7yvd954tstdaaae"},{"key":"sender","value":"wasm1quzyfdgzw42aelcdkrw2v8vnfdxsk9jkl7a4qf"},{"key":"amount","value":"10000umlg"}]},{"type":"wasm","attributes":[{"key":"_contract_address","value":"wasm1rpfxxy379eq2lq8wjz0lcke9ql49p5uzx2246vx6pml7yvd954tstdaaae"},{"key":"method","value":"reset"}]}]}]
}

#[ignore]
#[tokio::test]
async fn test_store_contract() {
// Sender publickey {"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Aggx3Gp4SJOHzZK4WDen/j5EXutf78JB87DQA5/7Z59y"}
Expand Down Expand Up @@ -275,7 +273,6 @@ async fn test_store_contract() {
// code_id = 547
}

#[ignore]
#[tokio::test]
async fn test_instantiate_contract() {
let mnemonic = "coyote electric million purchase tennis skin quiz inside helmet call glimpse pulse turkey hint maze iron festival run bomb regular legend prepare service angry".to_string();
Expand Down