Tag contract errors, and print out lines for easier QA (#1084)
* Tag contract errors, and print out lines for easier QA * Allow updating mixnet address by admin * Add reply endpoint, and unbond callback * Extract vesting messages * Wrap up
This commit is contained in:
Generated
+6
@@ -7660,6 +7660,7 @@ dependencies = [
|
||||
"url",
|
||||
"validator-api-requests",
|
||||
"vesting-contract",
|
||||
"vesting-contract-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7734,7 +7735,12 @@ dependencies = [
|
||||
name = "vesting-contract-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"config",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"mixnet-contract-common",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
all: clippy-all test fmt
|
||||
all: clippy-all test wasm fmt
|
||||
happy: clippy-happy test fmt
|
||||
clippy-all: clippy-all-main clippy-all-contracts clippy-all-wallet
|
||||
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet
|
||||
|
||||
@@ -10,6 +10,7 @@ rust-version = "1.56"
|
||||
[dependencies]
|
||||
base64 = "0.13"
|
||||
mixnet-contract-common = { path= "../../cosmwasm-smart-contracts/mixnet-contract" }
|
||||
vesting-contract-common = { path= "../../cosmwasm-smart-contracts/vesting-contract" }
|
||||
vesting-contract = { path = "../../../contracts/vesting" }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
@@ -45,6 +45,7 @@ pub enum Operation {
|
||||
AdvanceCurrentInterval,
|
||||
WriteRewardedSet,
|
||||
ClearRewardedSet,
|
||||
UpdateMixnetAddress,
|
||||
}
|
||||
|
||||
pub(crate) fn calculate_fee(gas_price: &GasPrice, gas_limit: Gas) -> Coin {
|
||||
@@ -85,6 +86,7 @@ impl fmt::Display for Operation {
|
||||
Operation::AdvanceCurrentInterval => f.write_str("AdvanceCurrentInterval"),
|
||||
Operation::WriteRewardedSet => f.write_str("WriteRewardedSet"),
|
||||
Operation::ClearRewardedSet => f.write_str("ClearRewardedSet"),
|
||||
Operation::UpdateMixnetAddress => f.write_str("UpdateMixnetAddress"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,6 +127,7 @@ impl Operation {
|
||||
Operation::AdvanceCurrentInterval => 175_000u64.into(),
|
||||
Operation::WriteRewardedSet => 175_000u64.into(),
|
||||
Operation::ClearRewardedSet => 175_000u64.into(),
|
||||
Operation::UpdateMixnetAddress => 80_000u64.into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@ use crate::nymd::error::NymdError;
|
||||
use crate::nymd::NymdClient;
|
||||
use async_trait::async_trait;
|
||||
use cosmwasm_std::{Coin, Timestamp};
|
||||
use vesting_contract::messages::QueryMsg as VestingQueryMsg;
|
||||
use vesting_contract::vesting::Account;
|
||||
use vesting_contract::vesting::PledgeData;
|
||||
use vesting_contract::vesting::{Account, PledgeData};
|
||||
use vesting_contract_common::messages::QueryMsg as VestingQueryMsg;
|
||||
|
||||
#[async_trait]
|
||||
pub trait VestingQueryClient {
|
||||
|
||||
@@ -9,10 +9,12 @@ use crate::nymd::{cosmwasm_coin_to_cosmos_coin, NymdClient};
|
||||
use async_trait::async_trait;
|
||||
use cosmwasm_std::Coin;
|
||||
use mixnet_contract_common::{Gateway, IdentityKey, IdentityKeyRef, MixNode};
|
||||
use vesting_contract::messages::{ExecuteMsg as VestingExecuteMsg, VestingSpecification};
|
||||
use vesting_contract_common::messages::{ExecuteMsg as VestingExecuteMsg, VestingSpecification};
|
||||
|
||||
#[async_trait]
|
||||
pub trait VestingSigningClient {
|
||||
async fn update_mixnet_address(&self, address: &str) -> Result<ExecuteResult, NymdError>;
|
||||
|
||||
async fn vesting_bond_gateway(
|
||||
&self,
|
||||
gateway: Gateway,
|
||||
@@ -297,4 +299,21 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn update_mixnet_address(&self, address: &str) -> Result<ExecuteResult, NymdError> {
|
||||
let fee = self.operation_fee(Operation::UpdateMixnetAddress);
|
||||
let req = VestingExecuteMsg::UpdateMixnetAddress {
|
||||
address: address.to_string(),
|
||||
};
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.vesting_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"VestingContract::UpdateMixnetAddress",
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -7,3 +7,8 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cosmwasm-std = "1.0.0-beta3"
|
||||
mixnet-contract-common = { path = "../mixnet-contract" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
schemars = "0.8"
|
||||
cw-storage-plus = "0.11.1"
|
||||
config = {path = "../../config"}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::Coin;
|
||||
|
||||
pub mod events;
|
||||
pub mod messages;
|
||||
|
||||
pub fn one_unym() -> Coin {
|
||||
Coin::new(1, DENOM)
|
||||
}
|
||||
|
||||
+4
-1
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct InitMsg {
|
||||
pub(crate) mixnet_contract_address: String,
|
||||
pub mixnet_contract_address: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
@@ -49,6 +49,9 @@ impl VestingSpecification {
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ExecuteMsg {
|
||||
UpdateMixnetAddress {
|
||||
address: String,
|
||||
},
|
||||
DelegateToMixnode {
|
||||
mix_identity: IdentityKey,
|
||||
amount: Coin,
|
||||
Generated
+6
-1
@@ -855,7 +855,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"time 0.3.6",
|
||||
"vergen",
|
||||
"vesting-contract",
|
||||
"vesting-contract-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1557,7 +1557,12 @@ dependencies = [
|
||||
name = "vesting-contract-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"config",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"mixnet-contract-common",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -17,8 +17,8 @@ crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" }
|
||||
vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" }
|
||||
config = { path = "../../common/config"}
|
||||
vesting-contract = { path = "../vesting" }
|
||||
|
||||
cosmwasm-std = "1.0.0-beta3"
|
||||
cosmwasm-storage = "1.0.0-beta3"
|
||||
|
||||
@@ -9,7 +9,8 @@ use cosmwasm_std::{coins, wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, Messa
|
||||
use cw_storage_plus::PrimaryKey;
|
||||
use mixnet_contract_common::events::{new_delegation_event, new_undelegation_event};
|
||||
use mixnet_contract_common::{Delegation, IdentityKey};
|
||||
use vesting_contract::messages::ExecuteMsg as VestingContractExecuteMsg;
|
||||
use vesting_contract_common::messages::ExecuteMsg as VestingContractExecuteMsg;
|
||||
use vesting_contract_common::one_unym;
|
||||
|
||||
fn validate_delegation_stake(mut delegation: Vec<Coin>) -> Result<Coin, ContractError> {
|
||||
// check if anything was put as delegation
|
||||
@@ -212,7 +213,7 @@ pub(crate) fn _try_remove_delegation_from_mixnode(
|
||||
amount: old_delegation.amount.clone(),
|
||||
});
|
||||
|
||||
let track_undelegation_msg = wasm_execute(proxy, &msg, coins(0, DENOM))?;
|
||||
let track_undelegation_msg = wasm_execute(proxy, &msg, vec![one_unym()])?;
|
||||
|
||||
response = response.add_message(track_undelegation_msg);
|
||||
}
|
||||
|
||||
@@ -12,113 +12,113 @@ use thiserror::Error;
|
||||
/// Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum ContractError {
|
||||
#[error("{0}")]
|
||||
#[error("MIXNET ({}): {0}", line!())]
|
||||
Std(#[from] StdError),
|
||||
|
||||
#[error("Not enough funds sent for mixnode bond. (received {received}, minimum {minimum})")]
|
||||
#[error("MIXNET ({}): Not enough funds sent for mixnode bond. (received {received}, minimum {minimum})", line!())]
|
||||
InsufficientMixNodeBond { received: u128, minimum: u128 },
|
||||
|
||||
#[error("Mixnode ({identity}) does not exist")]
|
||||
#[error("MIXNET ({}): Mixnode ({identity}) does not exist", line!())]
|
||||
MixNodeBondNotFound { identity: IdentityKey },
|
||||
|
||||
#[error("Not enough funds sent for gateway bond. (received {received}, minimum {minimum})")]
|
||||
#[error("MIXNET ({}): Not enough funds sent for gateway bond. (received {received}, minimum {minimum})", line!())]
|
||||
InsufficientGatewayBond { received: u128, minimum: u128 },
|
||||
|
||||
#[error("{owner} does not seem to own any mixnodes")]
|
||||
#[error("MIXNET ({}): {owner} does not seem to own any mixnodes", line!())]
|
||||
NoAssociatedMixNodeBond { owner: Addr },
|
||||
|
||||
#[error("{owner} does not seem to own any gateways")]
|
||||
#[error("MIXNET ({}): {owner} does not seem to own any gateways", line!())]
|
||||
NoAssociatedGatewayBond { owner: Addr },
|
||||
|
||||
#[error("Unauthorized")]
|
||||
#[error("MIXNET ({}): Unauthorized", line!())]
|
||||
Unauthorized,
|
||||
|
||||
#[error("Wrong coin denomination, you must send {}", DENOM)]
|
||||
#[error("MIXNET ({}): Wrong coin denomination, you must send {}", line!(), DENOM)]
|
||||
WrongDenom,
|
||||
|
||||
#[error("Received multiple coin types during staking")]
|
||||
#[error("MIXNET ({}): Received multiple coin types during staking", line!())]
|
||||
MultipleDenoms,
|
||||
|
||||
#[error("No coin was sent for the bonding, you must send {}", DENOM)]
|
||||
#[error("MIXNET ({}): No coin was sent for the bonding, you must send {}", line!(), DENOM)]
|
||||
NoBondFound,
|
||||
|
||||
#[error("Provided active set size is bigger than the rewarded set")]
|
||||
#[error("MIXNET ({}): Provided active set size is bigger than the rewarded set", line!())]
|
||||
InvalidActiveSetSize,
|
||||
|
||||
#[error("Provided active set size is zero")]
|
||||
#[error("MIXNET ({}): Provided active set size is zero", line!())]
|
||||
ZeroActiveSet,
|
||||
|
||||
#[error("Provided rewarded set size is zero")]
|
||||
#[error("MIXNET ({}): Provided rewarded set size is zero", line!())]
|
||||
ZeroRewardedSet,
|
||||
|
||||
#[error("This address has already bonded a mixnode")]
|
||||
#[error("MIXNET ({}): This address has already bonded a mixnode", line!())]
|
||||
AlreadyOwnsMixnode,
|
||||
|
||||
#[error("This address has already bonded a gateway")]
|
||||
#[error("MIXNET ({}): This address has already bonded a gateway", line!())]
|
||||
AlreadyOwnsGateway,
|
||||
|
||||
#[error("Mixnode with this identity already exists. Its owner is {owner}")]
|
||||
#[error("MIXNET ({}): Mixnode with this identity already exists. Its owner is {owner}", line!())]
|
||||
DuplicateMixnode { owner: Addr },
|
||||
|
||||
#[error("Gateway with this identity already exists. Its owner is {owner}")]
|
||||
#[error("MIXNET ({}): Gateway with this identity already exists. Its owner is {owner}", line!())]
|
||||
DuplicateGateway { owner: Addr },
|
||||
|
||||
#[error("No funds were provided for the delegation")]
|
||||
#[error("MIXNET ({}): No funds were provided for the delegation", line!())]
|
||||
EmptyDelegation,
|
||||
|
||||
#[error("Could not find any delegation information associated with mixnode {identity} for {address}")]
|
||||
#[error("MIXNET ({}): Could not find any delegation information associated with mixnode {identity} for {address}", line!())]
|
||||
NoMixnodeDelegationFound {
|
||||
identity: IdentityKey,
|
||||
address: Addr,
|
||||
},
|
||||
|
||||
#[error("We tried to remove more funds then are available in the Reward pool. Wanted to remove {to_remove}, but have only {reward_pool}")]
|
||||
#[error("MIXNET ({}): We tried to remove more funds then are available in the Reward pool. Wanted to remove {to_remove}, but have only {reward_pool}", line!())]
|
||||
OutOfFunds { to_remove: u128, reward_pool: u128 },
|
||||
|
||||
#[error("Received invalid interval id. Expected {expected}, received {received}")]
|
||||
#[error("MIXNET ({}): Received invalid interval id. Expected {expected}, received {received}", line!())]
|
||||
InvalidIntervalId { received: u32, expected: u32 },
|
||||
|
||||
#[error("Mixnode {identity} has already been rewarded during the current rewarding interval")]
|
||||
#[error("MIXNET ({}): Mixnode {identity} has already been rewarded during the current rewarding interval", line!())]
|
||||
MixnodeAlreadyRewarded { identity: IdentityKey },
|
||||
|
||||
#[error("Some of mixnodes {identity} delegators are still pending reward")]
|
||||
#[error("MIXNET ({}): Some of mixnodes {identity} delegators are still pending reward", line!())]
|
||||
DelegatorsPendingReward { identity: IdentityKey },
|
||||
|
||||
#[error("Mixnode's {identity} operator has not been rewarded yet - cannot perform delegator rewarding until that happens")]
|
||||
#[error("MIXNET ({}): Mixnode's {identity} operator has not been rewarded yet - cannot perform delegator rewarding until that happens", line!())]
|
||||
MixnodeOperatorNotRewarded { identity: IdentityKey },
|
||||
|
||||
#[error("Proxy address mismatch, expected {existing}, got {incoming}")]
|
||||
#[error("MIXNET ({}): Proxy address mismatch, expected {existing}, got {incoming}", line!())]
|
||||
ProxyMismatch { existing: String, incoming: String },
|
||||
|
||||
#[error("Failed to recover ed25519 public key from its base58 representation - {0}")]
|
||||
#[error("MIXNET ({}): Failed to recover ed25519 public key from its base58 representation - {0}", line!())]
|
||||
MalformedEd25519IdentityKey(String),
|
||||
|
||||
#[error("Failed to recover ed25519 signature from its base58 representation - {0}")]
|
||||
#[error("MIXNET ({}): Failed to recover ed25519 signature from its base58 representation - {0}", line!())]
|
||||
MalformedEd25519Signature(String),
|
||||
|
||||
#[error("Provided ed25519 signature did not verify correctly")]
|
||||
#[error("MIXNET ({}): Provided ed25519 signature did not verify correctly", line!())]
|
||||
InvalidEd25519Signature,
|
||||
|
||||
#[error("Profit margin percent needs to be an integer in range [0, 100], received {0}")]
|
||||
#[error("MIXNET ({}): Profit margin percent needs to be an integer in range [0, 100], received {0}", line!())]
|
||||
InvalidProfitMarginPercent(u8),
|
||||
|
||||
#[error("Rewarded set height not set, was rewarding set determined?")]
|
||||
#[error("MIXNET ({}): Rewarded set height not set, was rewarding set determined?", line!())]
|
||||
RewardSetHeightMapEmpty,
|
||||
|
||||
#[error("Received unexpected value for the active set. Got: {received}, expected: {expected}")]
|
||||
#[error("MIXNET ({}): Received unexpected value for the active set. Got: {received}, expected: {expected}", line!())]
|
||||
UnexpectedActiveSetSize { received: u32, expected: u32 },
|
||||
|
||||
#[error("Received unexpected value for the rewarded set. Got: {received}, expected at most: {expected}")]
|
||||
#[error("MIXNET ({}): Received unexpected value for the rewarded set. Got: {received}, expected at most: {expected}", line!())]
|
||||
UnexpectedRewardedSetSize { received: u32, expected: u32 },
|
||||
|
||||
#[error("There hasn't been sufficient delay since last rewarded set update. It was last updated at height {last_update}. The delay is {minimum_delay}. The current block height is {current_height}")]
|
||||
#[error("MIXNET ({}): There hasn't been sufficient delay since last rewarded set update. It was last updated at height {last_update}. The delay is {minimum_delay}. The current block height is {current_height}", line!())]
|
||||
TooFrequentRewardedSetUpdate {
|
||||
last_update: u64,
|
||||
minimum_delay: u64,
|
||||
current_height: u64,
|
||||
},
|
||||
|
||||
#[error("Can't change to the desired interval as it's not in progress yet. It starts at {interval_start} and finishes at {interval_end}, while the current block time is {current_block_time}")]
|
||||
#[error("MIXNET ({}): Can't change to the desired interval as it's not in progress yet. It starts at {interval_start} and finishes at {interval_end}, while the current block time is {current_block_time}", line!())]
|
||||
IntervalNotInProgress {
|
||||
current_block_time: u64,
|
||||
interval_start: i64,
|
||||
|
||||
@@ -7,11 +7,12 @@ use crate::mixnet_contract_settings::storage as mixnet_params_storage;
|
||||
use crate::support::helpers::{ensure_no_existing_bond, validate_node_identity_signature};
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::{
|
||||
coins, wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Uint128,
|
||||
wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Uint128,
|
||||
};
|
||||
use mixnet_contract_common::events::{new_gateway_bonding_event, new_gateway_unbonding_event};
|
||||
use mixnet_contract_common::{Gateway, GatewayBond, Layer};
|
||||
use vesting_contract::messages::ExecuteMsg as VestingContractExecuteMsg;
|
||||
use vesting_contract_common::messages::ExecuteMsg as VestingContractExecuteMsg;
|
||||
use vesting_contract_common::one_unym;
|
||||
|
||||
pub fn try_add_gateway(
|
||||
deps: DepsMut,
|
||||
@@ -176,7 +177,7 @@ pub(crate) fn _try_remove_gateway(
|
||||
amount: gateway_bond.pledge_amount(),
|
||||
};
|
||||
|
||||
let track_unbond_message = wasm_execute(proxy, &msg, coins(0, DENOM))?;
|
||||
let track_unbond_message = wasm_execute(proxy, &msg, vec![one_unym()])?;
|
||||
response = response.add_message(track_unbond_message);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,12 @@ use crate::mixnodes::storage::StoredMixnodeBond;
|
||||
use crate::support::helpers::{ensure_no_existing_bond, validate_node_identity_signature};
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::{
|
||||
coins, wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Uint128,
|
||||
wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Uint128,
|
||||
};
|
||||
use mixnet_contract_common::events::{new_mixnode_bonding_event, new_mixnode_unbonding_event};
|
||||
use mixnet_contract_common::MixNode;
|
||||
use vesting_contract::messages::ExecuteMsg as VestingContractExecuteMsg;
|
||||
use vesting_contract_common::messages::ExecuteMsg as VestingContractExecuteMsg;
|
||||
use vesting_contract_common::one_unym;
|
||||
|
||||
pub fn try_add_mixnode(
|
||||
deps: DepsMut,
|
||||
@@ -192,7 +193,7 @@ pub(crate) fn _try_remove_mixnode(
|
||||
// decrement layer count
|
||||
mixnet_params_storage::decrement_layer_count(deps.storage, mixnode_bond.layer)?;
|
||||
|
||||
let mut response = Response::new().add_message(return_tokens);
|
||||
let mut response = Response::new();
|
||||
|
||||
if let Some(proxy) = &proxy {
|
||||
let msg = VestingContractExecuteMsg::TrackUnbondMixnode {
|
||||
@@ -200,10 +201,12 @@ pub(crate) fn _try_remove_mixnode(
|
||||
amount: mixnode_bond.pledge_amount(),
|
||||
};
|
||||
|
||||
let track_unbond_message = wasm_execute(proxy, &msg, coins(0, DENOM))?;
|
||||
let track_unbond_message = wasm_execute(proxy, &msg, vec![one_unym()])?;
|
||||
response = response.add_message(track_unbond_message);
|
||||
}
|
||||
|
||||
let response = response.add_message(return_tokens);
|
||||
|
||||
Ok(response.add_event(new_mixnode_unbonding_event(
|
||||
&owner,
|
||||
&proxy,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::errors::ContractError;
|
||||
use crate::messages::{ExecuteMsg, InitMsg, MigrateMsg, QueryMsg, VestingSpecification};
|
||||
use crate::storage::{account_from_address, ADMIN, MIXNET_CONTRACT_ADDRESS};
|
||||
use crate::traits::{
|
||||
DelegatingAccount, GatewayBondingAccount, MixnodeBondingAccount, VestingAccount,
|
||||
@@ -16,6 +15,9 @@ use vesting_contract_common::events::{
|
||||
new_staking_address_update_event, new_track_gateway_unbond_event,
|
||||
new_track_mixnode_unbond_event, new_track_undelegation_event, new_vested_coins_withdraw_event,
|
||||
};
|
||||
use vesting_contract_common::messages::{
|
||||
ExecuteMsg, InitMsg, MigrateMsg, QueryMsg, VestingSpecification,
|
||||
};
|
||||
|
||||
#[entry_point]
|
||||
pub fn instantiate(
|
||||
@@ -43,6 +45,9 @@ pub fn execute(
|
||||
msg: ExecuteMsg,
|
||||
) -> Result<Response, ContractError> {
|
||||
match msg {
|
||||
ExecuteMsg::UpdateMixnetAddress { address } => {
|
||||
try_update_mixnet_address(address, info, deps)
|
||||
}
|
||||
ExecuteMsg::DelegateToMixnode {
|
||||
mix_identity,
|
||||
amount,
|
||||
@@ -97,7 +102,20 @@ pub fn execute(
|
||||
}
|
||||
}
|
||||
|
||||
// Only owner
|
||||
// Only contract admin, set at init
|
||||
pub fn try_update_mixnet_address(
|
||||
address: String,
|
||||
info: MessageInfo,
|
||||
deps: DepsMut,
|
||||
) -> Result<Response, ContractError> {
|
||||
if info.sender != ADMIN.load(deps.storage)? {
|
||||
return Err(ContractError::NotAdmin(info.sender.as_str().to_string()));
|
||||
}
|
||||
MIXNET_CONTRACT_ADDRESS.save(deps.storage, &address)?;
|
||||
Ok(Response::default())
|
||||
}
|
||||
|
||||
// Only contract owner of vesting account
|
||||
pub fn try_withdraw_vested_coins(
|
||||
amount: Coin,
|
||||
env: Env,
|
||||
@@ -311,14 +329,31 @@ fn try_create_periodic_vesting_account(
|
||||
periods,
|
||||
deps.storage,
|
||||
)?;
|
||||
Ok(
|
||||
Response::new().add_event(new_periodic_vesting_account_event(
|
||||
&owner_address,
|
||||
&coin,
|
||||
&staking_address,
|
||||
start_time,
|
||||
)),
|
||||
)
|
||||
|
||||
let mut response = Response::new();
|
||||
|
||||
let send_tokens_owner = BankMsg::Send {
|
||||
to_address: owner_address.as_str().to_string(),
|
||||
amount: vec![Coin::new(1_000_000, DENOM)],
|
||||
};
|
||||
|
||||
response = response.add_message(send_tokens_owner);
|
||||
|
||||
if let Some(staking_address) = staking_address.as_ref() {
|
||||
let send_tokens_staking = BankMsg::Send {
|
||||
to_address: staking_address.clone().as_str().to_string(),
|
||||
amount: vec![Coin::new(1_000_000, DENOM)],
|
||||
};
|
||||
|
||||
response = response.add_message(send_tokens_staking);
|
||||
}
|
||||
|
||||
Ok(response.add_event(new_periodic_vesting_account_event(
|
||||
&owner_address,
|
||||
&coin,
|
||||
&staking_address,
|
||||
start_time,
|
||||
)))
|
||||
}
|
||||
|
||||
#[entry_point]
|
||||
|
||||
@@ -4,42 +4,42 @@ use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum ContractError {
|
||||
#[error("{0}")]
|
||||
#[error("VESTING ({}): {0}", line!())]
|
||||
Std(#[from] StdError),
|
||||
#[error("Account does not exist - {0}")]
|
||||
#[error("VESTING ({}): Account does not exist - {0}", line!())]
|
||||
NoAccountForAddress(String),
|
||||
#[error("Only admin can perform this action, {0} is not admin")]
|
||||
#[error("VESTING ({}): Only admin can perform this action, {0} is not admin", line!())]
|
||||
NotAdmin(String),
|
||||
#[error("Balance not found for existing account ({0}), this is a bug")]
|
||||
#[error("VESTING ({}): Balance not found for existing account ({0}), this is a bug", line!())]
|
||||
NoBalanceForAddress(String),
|
||||
#[error("Insufficient balance for address {0} -> {1}")]
|
||||
#[error("VESTING ({}): Insufficient balance for address {0} -> {1}", line!())]
|
||||
InsufficientBalance(String, u128),
|
||||
#[error("Insufficient spendable balance for address {0} -> {1}")]
|
||||
#[error("VESTING ({}): Insufficient spendable balance for address {0} -> {1}", line!())]
|
||||
InsufficientSpendable(String, u128),
|
||||
#[error(
|
||||
"Only delegation owner can perform delegation actions, {0} is not the delegation owner"
|
||||
)]
|
||||
"VESTING ({}):Only delegation owner can perform delegation actions, {0} is not the delegation owner"
|
||||
, line!())]
|
||||
NotDelegate(String),
|
||||
#[error("Total vesting amount is inprobably low -> {0}, this is likely an error")]
|
||||
#[error("VESTING ({}): Total vesting amount is inprobably low -> {0}, this is likely an error", line!())]
|
||||
ImprobableVestingAmount(u128),
|
||||
#[error("Address {0} has already bonded a node")]
|
||||
#[error("VESTING ({}): Address {0} has already bonded a node", line!())]
|
||||
AlreadyBonded(String),
|
||||
#[error("Received empty funds vector")]
|
||||
#[error("VESTING ({}): Received empty funds vector", line!())]
|
||||
EmptyFunds,
|
||||
#[error("Received wrong denom: {0}, expected {1}")]
|
||||
#[error("VESTING ({}): Received wrong denom: {0}, expected {1}", line!())]
|
||||
WrongDenom(String, String),
|
||||
#[error("Received multiple denoms, expected 1")]
|
||||
#[error("VESTING ({}): Received multiple denoms, expected 1", line!())]
|
||||
MultipleDenoms,
|
||||
#[error("No delegations found for account {0}, mix_identity {1}")]
|
||||
#[error("VESTING ({}): No delegations found for account {0}, mix_identity {1}", line!())]
|
||||
NoSuchDelegation(Addr, IdentityKey),
|
||||
#[error("Only mixnet contract can perform this operation, got {0}")]
|
||||
#[error("VESTING ({}): Only mixnet contract can perform this operation, got {0}", line!())]
|
||||
NotMixnetContract(Addr),
|
||||
#[error("Calculation underflowed")]
|
||||
#[error("VESTING ({}): Calculation underflowed", line!())]
|
||||
Underflow,
|
||||
#[error("No bond found for account {0}")]
|
||||
#[error("VESTING ({}): No bond found for account {0}", line!())]
|
||||
NoBondFound(String),
|
||||
#[error("Action can only be executed by account owner -> {0}")]
|
||||
#[error("VESTING ({}): Action can only be executed by account owner -> {0}", line!())]
|
||||
NotOwner(String),
|
||||
#[error("Invalid address: {0}")]
|
||||
#[error("VESTING ({}): Invalid address: {0}", line!())]
|
||||
InvalidAddress(String),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
pub mod contract;
|
||||
mod errors;
|
||||
pub mod messages;
|
||||
mod storage;
|
||||
mod support;
|
||||
mod traits;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#[cfg(test)]
|
||||
pub mod helpers {
|
||||
use crate::contract::instantiate;
|
||||
use crate::messages::{InitMsg, VestingSpecification};
|
||||
use crate::vesting::{populate_vesting_periods, Account};
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier};
|
||||
use cosmwasm_std::{Addr, Coin, Empty, Env, MemoryStorage, OwnedDeps, Storage, Uint128};
|
||||
use vesting_contract_common::messages::{InitMsg, VestingSpecification};
|
||||
|
||||
pub fn init_contract() -> OwnedDeps<MemoryStorage, MockApi, MockQuerier<Empty>> {
|
||||
let mut deps = mock_dependencies();
|
||||
|
||||
@@ -2,13 +2,13 @@ use crate::errors::ContractError;
|
||||
use crate::storage::save_delegation;
|
||||
use crate::storage::MIXNET_CONTRACT_ADDRESS;
|
||||
use crate::traits::DelegatingAccount;
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::{wasm_execute, Coin, Env, Response, Storage, Uint128};
|
||||
use mixnet_contract_common::ExecuteMsg as MixnetExecuteMsg;
|
||||
use mixnet_contract_common::IdentityKey;
|
||||
use vesting_contract_common::events::{
|
||||
new_vesting_delegation_event, new_vesting_undelegation_event,
|
||||
};
|
||||
use vesting_contract_common::one_unym;
|
||||
|
||||
use super::Account;
|
||||
|
||||
@@ -70,10 +70,7 @@ impl DelegatingAccount for Account {
|
||||
let undelegate_from_mixnode = wasm_execute(
|
||||
MIXNET_CONTRACT_ADDRESS.load(storage)?,
|
||||
&msg,
|
||||
vec![Coin {
|
||||
amount: Uint128::new(0),
|
||||
denom: DENOM.to_string(),
|
||||
}],
|
||||
vec![one_unym()],
|
||||
)?;
|
||||
|
||||
Ok(Response::new()
|
||||
|
||||
@@ -7,6 +7,7 @@ use mixnet_contract_common::{ExecuteMsg as MixnetExecuteMsg, Gateway};
|
||||
use vesting_contract_common::events::{
|
||||
new_vesting_gateway_bonding_event, new_vesting_gateway_unbonding_event,
|
||||
};
|
||||
use vesting_contract_common::one_unym;
|
||||
|
||||
use super::Account;
|
||||
|
||||
@@ -64,7 +65,11 @@ impl GatewayBondingAccount for Account {
|
||||
};
|
||||
|
||||
if let Some(_bond) = self.load_gateway_pledge(storage)? {
|
||||
let unbond_msg = wasm_execute(MIXNET_CONTRACT_ADDRESS.load(storage)?, &msg, vec![])?;
|
||||
let unbond_msg = wasm_execute(
|
||||
MIXNET_CONTRACT_ADDRESS.load(storage)?,
|
||||
&msg,
|
||||
vec![one_unym()],
|
||||
)?;
|
||||
|
||||
Ok(Response::new()
|
||||
.add_message(unbond_msg)
|
||||
|
||||
@@ -7,6 +7,7 @@ use mixnet_contract_common::{ExecuteMsg as MixnetExecuteMsg, MixNode};
|
||||
use vesting_contract_common::events::{
|
||||
new_vesting_mixnode_bonding_event, new_vesting_mixnode_unbonding_event,
|
||||
};
|
||||
use vesting_contract_common::one_unym;
|
||||
|
||||
use super::Account;
|
||||
|
||||
@@ -64,7 +65,11 @@ impl MixnodeBondingAccount for Account {
|
||||
};
|
||||
|
||||
if self.load_mixnode_pledge(storage)?.is_some() {
|
||||
let unbond_msg = wasm_execute(MIXNET_CONTRACT_ADDRESS.load(storage)?, &msg, vec![])?;
|
||||
let unbond_msg = wasm_execute(
|
||||
MIXNET_CONTRACT_ADDRESS.load(storage)?,
|
||||
&msg,
|
||||
vec![one_unym()],
|
||||
)?;
|
||||
|
||||
Ok(Response::new()
|
||||
.add_message(unbond_msg)
|
||||
|
||||
@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
mod account;
|
||||
pub use account::*;
|
||||
|
||||
use crate::messages::VestingSpecification;
|
||||
use vesting_contract_common::messages::VestingSpecification;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct VestingPeriod {
|
||||
@@ -43,7 +43,6 @@ pub fn populate_vesting_periods(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::contract::execute;
|
||||
use crate::messages::ExecuteMsg;
|
||||
use crate::storage::load_account;
|
||||
use crate::support::tests::helpers::{init_contract, vesting_account_fixture};
|
||||
use crate::traits::DelegatingAccount;
|
||||
@@ -53,6 +52,7 @@ mod tests {
|
||||
use cosmwasm_std::testing::{mock_env, mock_info};
|
||||
use cosmwasm_std::{coins, Addr, Coin, Timestamp, Uint128};
|
||||
use mixnet_contract_common::{Gateway, MixNode};
|
||||
use vesting_contract_common::messages::ExecuteMsg;
|
||||
|
||||
#[test]
|
||||
fn test_account_creation() {
|
||||
|
||||
Generated
+6
@@ -5338,6 +5338,7 @@ dependencies = [
|
||||
"url",
|
||||
"validator-api-requests",
|
||||
"vesting-contract",
|
||||
"vesting-contract-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5382,7 +5383,12 @@ dependencies = [
|
||||
name = "vesting-contract-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"config",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"mixnet-contract-common",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -27,4 +27,5 @@ export type Operation =
|
||||
| "CreatePeriodicVestingAccount"
|
||||
| "AdvanceCurrentInterval"
|
||||
| "WriteRewardedSet"
|
||||
| "ClearRewardedSet";
|
||||
| "ClearRewardedSet"
|
||||
| "UpdateMixnetAddress";
|
||||
Reference in New Issue
Block a user