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

Staking contract #25

Draft
wants to merge 1 commit 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
266 changes: 145 additions & 121 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
[workspace]
resolver = "2"
members = [
"contracts/*",
"contracts/proxies/proxy_to_vkr",
"contracts/stakings/staking_vkr",
"packages/*"
]


[profile.release]
opt-level = 3
opt-level = "z"
debug = false
rpath = false
lto = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
wasm = "build --release --target wasm32-unknown-unknown"
wasm-debug = "build --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --example schema"
schema = "run --example proxy_to_vkr_schema"
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ cw-storage-plus = "0.15"
thiserror = { version = "1.0" }
cw2 = "0.15"
cw20 = "0.15"
valkyrie = { git = "https://github.com/astroport-fi/valkyrieprotocol", rev = "b5fcb666f17d7e291f40365756e50fc0d7b9bf54" }
astroport = { git = "https://github.com/astroport-fi/astroport-core", branch = "main" }
ap-valkyrie = { path = "../../packages/valkyrie" }
astroport = { git = "https://github.com/astroport-fi/astroport-core" }
ap-valkyrie = { path = "../../../packages/valkyrie" }
cosmwasm-schema = "1.1"
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use ap_valkyrie::MigrateMsg;
use astroport::generator_proxy::{ExecuteMsg, InstantiateMsg, QueryMsg};
use astroport::generator_proxy::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use cosmwasm_schema::write_api;

fn main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, Cw20ReceiveMsg};

use crate::error::ContractError;
use crate::state::{Config, CONFIG};
use ap_valkyrie::MigrateMsg;
use astroport::generator_proxy::{
CallbackMsg, ConfigResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg,
};

use cw2::set_contract_version;
use valkyrie::lp_staking::execute_msgs::{
Cw20HookMsg as VkrCw20HookMsg, ExecuteMsg as VkrExecuteMsg,
use ap_valkyrie::staking_vkr::{
Cw20HookMsg as VkrCw20HookMsg, ExecuteMsg as VkrExecuteMsg, MigrateMsg,
QueryMsg as VkrQueryMsg, StakerInfoResponse,
};
use valkyrie::lp_staking::query_msgs::{QueryMsg as VkrQueryMsg, StakerInfoResponse};
use cw2::set_contract_version;

// version info for migration info
const CONTRACT_NAME: &str = "astroport-generator-proxy-to-vkr";
Expand Down Expand Up @@ -102,7 +101,7 @@ fn receive_cw20(
msg: to_binary(&Cw20ExecuteMsg::Send {
contract: cfg.reward_contract_addr.to_string(),
amount: cw20_msg.amount,
msg: to_binary(&VkrCw20HookMsg::Bond {})?,
msg: to_binary(&VkrCw20HookMsg::Bond { schedules: vec![] })?, // TODO:
})?,
})));
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use ap_valkyrie::staking_vkr::StakerInfoResponse;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR};
use cosmwasm_std::{
Expand All @@ -6,7 +7,6 @@ use cosmwasm_std::{
};
use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg};
use std::collections::HashMap;
use valkyrie::lp_staking::query_msgs::StakerInfoResponse;

/// mock_dependencies is a drop-in replacement for cosmwasm_std::testing::mock_dependencies
/// this uses our CustomQuerier.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use crate::contract::{execute, instantiate, query};
use crate::error::ContractError;
use crate::state::{Config, CONFIG};
use crate::testing::mock_querier::mock_dependencies;
use ap_valkyrie::staking_vkr::{Cw20HookMsg as VkrCw20HookMsg, ExecuteMsg as VkrExecuteMsg};
use astroport::generator_proxy::{CallbackMsg, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg};
use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR};
use cosmwasm_std::{from_binary, to_binary, Addr, CosmosMsg, SubMsg, Uint128, WasmMsg};
use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg};
use valkyrie::lp_staking::execute_msgs::{
Cw20HookMsg as VkrCw20HookMsg, ExecuteMsg as VkrExecuteMsg,
};

#[test]
fn test_proper_initialization() {
Expand Down Expand Up @@ -92,7 +90,7 @@ fn test_deposit() {
msg: to_binary(&Cw20ExecuteMsg::Send {
contract: "reward0000".to_string(),
amount: Uint128::from(100u128),
msg: to_binary(&VkrCw20HookMsg::Bond {}).unwrap(),
msg: to_binary(&VkrCw20HookMsg::Bond { schedules: vec![] }).unwrap(),
})
.unwrap(),
}))]
Expand Down
6 changes: 6 additions & 0 deletions contracts/stakings/staking_vkr/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[alias]
wasm = "build --release --target wasm32-unknown-unknown"
wasm-debug = "build --target wasm32-unknown-unknown"
unit-test = "test --lib"
integration-test = "test --test integration"
schema = "run --example staking_vkr_schema"
34 changes: 34 additions & 0 deletions contracts/stakings/staking_vkr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "valkyrie-lp-staking"
version = "1.1.0"
authors = ["Valkyrie Protocol, Astroport"]
edition = "2021"
description = "A Staking contract for Valkyrie Protocol - distribute rewards to stakers"
license = "Apache-2.0"

exclude = [
# 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.
"contract.wasm",
"hash.txt",
]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib", "rlib"]

[features]
# for quicker tests, cargo test --lib
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]

[dependencies]
cosmwasm-std = { version = "1.3" }
cw-storage-plus = { version = "1.1"}
cw20 = { version = "1.1" }
ap-valkyrie = { path = "../../../packages/valkyrie" }
cosmwasm-schema = { version = "1.1" }
thiserror = { version = "1.0" }

[dev-dependencies]
astroport = { git = "https://github.com/astroport-fi/astroport-core" }
5 changes: 5 additions & 0 deletions contracts/stakings/staking_vkr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Staking

The Staking Contract contains the logic for LP Token staking and reward distribution. VKR tokens
allocated for as liquidity incentives are distributed pro-rata to stakers of the VKR-USDC
Astroport pair LP token.
12 changes: 12 additions & 0 deletions contracts/stakings/staking_vkr/examples/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use ap_valkyrie::staking_vkr::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};

use cosmwasm_schema::write_api;

fn main() {
write_api! {
instantiate: InstantiateMsg,
query: QueryMsg,
execute: ExecuteMsg,
migrate: MigrateMsg,
}
}
118 changes: 118 additions & 0 deletions contracts/stakings/staking_vkr/src/entrypoints.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use crate::errors::ContractError;
#[cfg(not(feature = "library"))]
use crate::executions::{bond, migrate_reward, unbond, update_config, withdraw};
use crate::queries::{query_config, query_staker_info, query_state};
use crate::states::{Config, State};
use crate::ContractResult;
use ap_valkyrie::staking_vkr::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use cosmwasm_std::entry_point;
use cosmwasm_std::{
from_binary, to_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Response, Uint128,
};
use cw20::Cw20ReceiveMsg;

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> ContractResult<Response> {
Config {
admin: info.sender,
token: deps.api.addr_validate(&msg.token)?,
usdc_token: deps.api.addr_validate(&msg.token)?,
pair: deps.api.addr_validate(&msg.pair)?,
lp_token: deps.api.addr_validate(&msg.lp_token)?,
whitelisted_contracts: msg
.whitelisted_contracts
.iter()
.map(|item| deps.api.addr_validate(item).unwrap())
.collect(),
distribution_schedule: vec![],
}
.save(deps.storage)?;

State {
last_distributed: env.block.height,
total_bond_amount: Uint128::zero(),
global_reward_index: Decimal::zero(),
}
.save(deps.storage)?;

Ok(Response::new().add_attribute("action", "instantiate"))
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> ContractResult<Response> {
match msg {
ExecuteMsg::Receive(msg) => receive_cw20(deps, env, info, msg),
ExecuteMsg::Unbond { amount } => unbond(deps, env, info, amount),
ExecuteMsg::Withdraw {} => withdraw(deps, env, info),
ExecuteMsg::UpdateConfig {
token,
pair,
lp_token,
admin,
whitelisted_contracts,
} => update_config(
deps,
info,
token,
pair,
lp_token,
admin,
whitelisted_contracts,
),
ExecuteMsg::MigrateReward { recipient, amount } => {
migrate_reward(deps, env, info, recipient, amount)
}
ExecuteMsg::ApproveAdminNominee {} => crate::executions::approve_admin_nominee(deps, info),
}
}

pub fn receive_cw20(
deps: DepsMut,
env: Env,
info: MessageInfo,
cw20_msg: Cw20ReceiveMsg,
) -> ContractResult<Response> {
let mut config: Config = Config::load(deps.storage)?;

// only staking token contract can execute this message
if config.lp_token != info.sender {
return Err(ContractError::Unauthorized {});
}

match from_binary(&cw20_msg.msg)? {
Cw20HookMsg::Bond { schedules } => bond(
deps,
env,
&mut config,
&cw20_msg.sender,
schedules,
cw20_msg.amount,
),
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> ContractResult<Binary> {
let result = match msg {
QueryMsg::Config {} => to_binary(&query_config(deps)?),
QueryMsg::State { block_height } => to_binary(&query_state(deps, block_height)?),
QueryMsg::StakerInfo { staker } => to_binary(&query_staker_info(deps, env, &staker)?),
}?;

Ok(result)
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> ContractResult<Response> {
Ok(Response::default())
}
37 changes: 37 additions & 0 deletions contracts/stakings/staking_vkr/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use cosmwasm_std::{OverflowError, StdError};
use thiserror::Error;

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

#[error("{0}")]
OverflowError(#[from] OverflowError),

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

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

#[error("Asset mismatch")]
AssetMismatch {},

#[error("Not found")]
NotFound {},

#[error("Exceed limit")]
ExceedLimit {},

#[error("Already exists")]
AlreadyExists {},

#[error(
"Schedule error. Should satisfy: (start_block < end_block, end_block > current_block)"
)]
ScheduleError {},

#[error("Schedules amount error. The total amount should be equal to the received amount.")]
SchedulesAmountError {},
}
Loading