From f923d7daa70f1fd84c05e032de962993244bea13 Mon Sep 17 00:00:00 2001 From: Mitar Djakovic Date: Tue, 26 Nov 2024 11:34:37 +0200 Subject: [PATCH 1/6] Functionality Update of Curve ADO (#663) --- Cargo.lock | 2 +- contracts/modules/andromeda-curve/Cargo.toml | 2 +- .../modules/andromeda-curve/src/contract.rs | 111 ++++++++---------- contracts/modules/andromeda-curve/src/mock.rs | 109 ++++------------- .../modules/andromeda-curve/src/state.rs | 3 +- .../andromeda-curve/src/testing/mock.rs | 31 ++--- .../andromeda-curve/src/testing/tests.rs | 95 +++++++-------- packages/andromeda-modules/src/curve.rs | 28 ++--- 8 files changed, 133 insertions(+), 248 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 595c11738..c3d35a52d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,7 +257,7 @@ dependencies = [ [[package]] name = "andromeda-curve" -version = "0.1.0-beta" +version = "0.1.1-beta" dependencies = [ "andromeda-app", "andromeda-modules", diff --git a/contracts/modules/andromeda-curve/Cargo.toml b/contracts/modules/andromeda-curve/Cargo.toml index ffcf2d575..557edcf04 100644 --- a/contracts/modules/andromeda-curve/Cargo.toml +++ b/contracts/modules/andromeda-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-curve" -version = "0.1.0-beta" +version = "0.1.1-beta" edition = "2021" rust-version = "1.75.0" diff --git a/contracts/modules/andromeda-curve/src/contract.rs b/contracts/modules/andromeda-curve/src/contract.rs index 31c602b00..40cca5ec5 100644 --- a/contracts/modules/andromeda-curve/src/contract.rs +++ b/contracts/modules/andromeda-curve/src/contract.rs @@ -1,21 +1,21 @@ #[cfg(not(feature = "library"))] -use crate::state::{ - CURVE_CONFIG, DEFAULT_CONSTANT_VALUE, DEFAULT_MULTIPLE_VARIABLE_VALUE, RESTRICTION, -}; +use crate::state::{CURVE_CONFIG, DEFAULT_CONSTANT_VALUE, DEFAULT_MULTIPLE_VARIABLE_VALUE}; use andromeda_modules::curve::{ - CurveConfig, CurveId, CurveRestriction, ExecuteMsg, GetCurveConfigResponse, - GetPlotYFromXResponse, GetRestrictionResponse, InstantiateMsg, QueryMsg, + CurveConfig, CurveType, ExecuteMsg, GetCurveConfigResponse, GetPlotYFromXResponse, + InstantiateMsg, QueryMsg, }; use andromeda_std::{ - ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_base::{ + permissioning::{LocalPermission, Permission}, + InstantiateMsg as BaseInstantiateMsg, MigrateMsg, + }, ado_contract::ADOContract, common::{actions::call_action, context::ExecuteContext, encode_binary}, error::ContractError, }; use cosmwasm_std::{ - ensure, entry_point, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, - Storage, + entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, Storage, }; use cw_utils::nonpayable; @@ -24,6 +24,9 @@ use cw_utils::nonpayable; const CONTRACT_NAME: &str = "crates.io:andromeda-curve"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +pub const UPDATE_CURVE_CONFIG_ACTION: &str = "update_curve_config"; +pub const RESET_ACTION: &str = "reset"; + #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, @@ -45,9 +48,30 @@ pub fn instantiate( }, )?; - msg.curve_config.validate()?; + if let Some(authorized_operator_addresses) = msg.authorized_operator_addresses { + if !authorized_operator_addresses.is_empty() { + ADOContract::default().permission_action(UPDATE_CURVE_CONFIG_ACTION, deps.storage)?; + ADOContract::default().permission_action(RESET_ACTION, deps.storage)?; + } + + for address in authorized_operator_addresses { + let addr = address.get_raw_address(&deps.as_ref())?; + ADOContract::set_permission( + deps.storage, + UPDATE_CURVE_CONFIG_ACTION, + addr.clone(), + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + ADOContract::set_permission( + deps.storage, + RESET_ACTION, + addr.clone(), + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + } - RESTRICTION.save(deps.storage, &msg.restriction)?; + msg.curve_config.validate()?; CURVE_CONFIG.save(deps.storage, &msg.curve_config)?; Ok(resp) @@ -82,9 +106,6 @@ fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { execute_update_curve_config(ctx, curve_config) } - ExecuteMsg::UpdateRestriction { restriction } => { - execute_update_restriction(ctx, restriction) - } ExecuteMsg::Reset {} => execute_reset(ctx), _ => ADOContract::default().execute(ctx, msg), }?; @@ -96,15 +117,17 @@ fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result Result { nonpayable(&ctx.info)?; let sender = ctx.info.sender.clone(); - ensure!( - has_permission(ctx.deps.storage, &sender)?, - ContractError::Unauthorized {} - ); + ADOContract::default().is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + UPDATE_CURVE_CONFIG_ACTION, + sender.clone(), + )?; curve_config.validate()?; CURVE_CONFIG.update(ctx.deps.storage, |_| { @@ -116,50 +139,25 @@ pub fn execute_update_curve_config( .add_attribute("sender", sender)) } -pub fn execute_update_restriction( - ctx: ExecuteContext, - restriction: CurveRestriction, -) -> Result { - nonpayable(&ctx.info)?; - let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); - RESTRICTION.save(ctx.deps.storage, &restriction)?; - - Ok(Response::new() - .add_attribute("method", "update_restriction") - .add_attribute("sender", sender)) -} - -pub fn execute_reset(ctx: ExecuteContext) -> Result { +pub fn execute_reset(mut ctx: ExecuteContext) -> Result { nonpayable(&ctx.info)?; let sender = ctx.info.sender.clone(); - ensure!( - has_permission(ctx.deps.storage, &sender)?, - ContractError::Unauthorized {} - ); + ADOContract::default().is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + RESET_ACTION, + sender.clone(), + )?; CURVE_CONFIG.remove(ctx.deps.storage); Ok(Response::new().add_attribute("method", "reset")) } -pub fn has_permission(storage: &dyn Storage, addr: &Addr) -> Result { - let is_operator = ADOContract::default().is_owner_or_operator(storage, addr.as_str())?; - let allowed = match RESTRICTION.load(storage)? { - CurveRestriction::Private => is_operator, - CurveRestriction::Public => true, - }; - Ok(is_operator || allowed) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::GetCurveConfig {} => encode_binary(&query_curve_config(deps.storage)?), - QueryMsg::GetRestriction {} => encode_binary(&query_restriction(deps.storage)?), QueryMsg::GetPlotYFromX { x_value } => { encode_binary(&query_plot_y_from_x(deps.storage, x_value)?) } @@ -172,11 +170,6 @@ pub fn query_curve_config(storage: &dyn Storage) -> Result Result { - let restriction = RESTRICTION.load(storage)?; - Ok(GetRestrictionResponse { restriction }) -} - pub fn query_plot_y_from_x( storage: &dyn Storage, x_value: f64, @@ -185,14 +178,14 @@ pub fn query_plot_y_from_x( let y_value = match curve_config { CurveConfig::ExpConfig { - curve_id, + curve_type, base_value, multiple_variable_value, constant_value, } => { - let curve_id_f64 = match curve_id { - CurveId::Growth => 1_f64, - CurveId::Decay => -1_f64, + let curve_id_f64 = match curve_type { + CurveType::Growth => 1_f64, + CurveType::Decay => -1_f64, }; let base_value_f64 = base_value as f64; let constant_value_f64 = constant_value.unwrap_or(DEFAULT_CONSTANT_VALUE) as f64; diff --git a/contracts/modules/andromeda-curve/src/mock.rs b/contracts/modules/andromeda-curve/src/mock.rs index 0b84cee93..ee64c212a 100644 --- a/contracts/modules/andromeda-curve/src/mock.rs +++ b/contracts/modules/andromeda-curve/src/mock.rs @@ -1,10 +1,10 @@ #![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] use crate::contract::{execute, instantiate, query}; use andromeda_modules::curve::{ - CurveId, CurveRestriction, CurveType, ExecuteMsg, GetConfigurationExpResponse, - GetCurveTypeResponse, GetPlotYFromXResponse, GetRestrictionResponse, InstantiateMsg, QueryMsg, + CurveConfig, ExecuteMsg, GetCurveConfigResponse, GetPlotYFromXResponse, InstantiateMsg, + QueryMsg, }; -use andromeda_std::ado_base::rates::{Rate, RatesMessage}; +use andromeda_std::amp::AndrAddr; use andromeda_testing::mock::MockApp; use andromeda_testing::{ mock_ado, @@ -23,10 +23,15 @@ impl MockCurve { app: &mut MockApp, kernel_address: String, owner: Option, - curve_type: CurveType, - restriction: CurveRestriction, + curve_config: CurveConfig, + authorized_operator_addresses: Option>, ) -> MockCurve { - let msg = mock_curve_instantiate_msg(kernel_address, owner, curve_type, restriction); + let msg = mock_curve_instantiate_msg( + kernel_address, + owner, + curve_config, + authorized_operator_addresses, + ); let addr = app .instantiate_contract( code_id, @@ -40,52 +45,14 @@ impl MockCurve { MockCurve(Addr::unchecked(addr)) } - pub fn execute_update_curve_type( - &self, - app: &mut MockApp, - sender: Addr, - curve_type: CurveType, - funds: Option, - ) -> ExecuteResult { - let msg = mock_execute_update_curve_type_msg(curve_type); - if let Some(funds) = funds { - app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) - } else { - app.execute_contract(sender, self.addr().clone(), &msg, &[]) - } - } - - pub fn execute_update_restriction( + pub fn execute_update_curve_config( &self, app: &mut MockApp, sender: Addr, - restriction: CurveRestriction, + curve_config: CurveConfig, funds: Option, ) -> ExecuteResult { - let msg = mock_execute_update_restriction_msg(restriction); - if let Some(funds) = funds { - app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) - } else { - app.execute_contract(sender, self.addr().clone(), &msg, &[]) - } - } - - pub fn execute_configure_exponential( - &self, - app: &mut MockApp, - sender: Addr, - curve_id: CurveId, - base_value: u64, - multiple_variable_value: Option, - constant_value: Option, - funds: Option, - ) -> ExecuteResult { - let msg = mock_execute_configure_exponential_msg( - curve_id, - base_value, - multiple_variable_value, - constant_value, - ); + let msg = ExecuteMsg::UpdateCurveConfig { curve_config }; if let Some(funds) = funds { app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) } else { @@ -107,21 +74,9 @@ impl MockCurve { } } - pub fn query_restriction(&self, app: &mut MockApp) -> GetRestrictionResponse { - let msg = QueryMsg::GetRestriction {}; - let res: GetRestrictionResponse = self.query(app, msg); - res - } - - pub fn query_curve_type(&self, app: &mut MockApp) -> GetCurveTypeResponse { - let msg = QueryMsg::GetCurveType {}; - let res: GetCurveTypeResponse = self.query(app, msg); - res - } - - pub fn query_configuration_exp(&self, app: &mut MockApp) -> GetConfigurationExpResponse { - let msg = QueryMsg::GetConfigurationExp {}; - let res: GetConfigurationExpResponse = self.query(app, msg); + pub fn query_config(&self, app: &mut MockApp) -> GetCurveConfigResponse { + let msg = QueryMsg::GetCurveConfig {}; + let res: GetCurveConfigResponse = self.query(app, msg); res } @@ -140,35 +95,13 @@ pub fn mock_andromeda_curve() -> Box> { pub fn mock_curve_instantiate_msg( kernel_address: String, owner: Option, - curve_type: CurveType, - restriction: CurveRestriction, + curve_config: CurveConfig, + authorized_operator_addresses: Option>, ) -> InstantiateMsg { InstantiateMsg { kernel_address, owner, - curve_type, - restriction, - } -} - -pub fn mock_execute_update_curve_type_msg(curve_type: CurveType) -> ExecuteMsg { - ExecuteMsg::UpdateCurveType { curve_type } -} - -pub fn mock_execute_update_restriction_msg(restriction: CurveRestriction) -> ExecuteMsg { - ExecuteMsg::UpdateRestriction { restriction } -} - -pub fn mock_execute_configure_exponential_msg( - curve_id: CurveId, - base_value: u64, - multiple_variable_value: Option, - constant_value: Option, -) -> ExecuteMsg { - ExecuteMsg::ConfigureExponential { - curve_id, - base_value, - multiple_variable_value, - constant_value, + curve_config, + authorized_operator_addresses, } } diff --git a/contracts/modules/andromeda-curve/src/state.rs b/contracts/modules/andromeda-curve/src/state.rs index 34967e01c..0e0ef0c78 100644 --- a/contracts/modules/andromeda-curve/src/state.rs +++ b/contracts/modules/andromeda-curve/src/state.rs @@ -1,8 +1,7 @@ -use andromeda_modules::curve::{CurveConfig, CurveRestriction}; +use andromeda_modules::curve::CurveConfig; use cw_storage_plus::Item; pub const CURVE_CONFIG: Item = Item::new("curve_config"); -pub const RESTRICTION: Item = Item::new("curve_restriction"); pub const DEFAULT_MULTIPLE_VARIABLE_VALUE: u64 = 1; pub const DEFAULT_CONSTANT_VALUE: u64 = 1; diff --git a/contracts/modules/andromeda-curve/src/testing/mock.rs b/contracts/modules/andromeda-curve/src/testing/mock.rs index 1d7ed9b1c..18be90a65 100644 --- a/contracts/modules/andromeda-curve/src/testing/mock.rs +++ b/contracts/modules/andromeda-curve/src/testing/mock.rs @@ -1,8 +1,9 @@ use andromeda_modules::curve::{ - CurveConfig, CurveRestriction, ExecuteMsg, GetCurveConfigResponse, GetPlotYFromXResponse, - GetRestrictionResponse, InstantiateMsg, QueryMsg, + CurveConfig, ExecuteMsg, GetCurveConfigResponse, GetPlotYFromXResponse, InstantiateMsg, + QueryMsg, }; use andromeda_std::{ + amp::AndrAddr, error::ContractError, testing::mock_querier::{mock_dependencies_custom, WasmMockQuerier, MOCK_KERNEL_CONTRACT}, }; @@ -18,7 +19,7 @@ pub type MockDeps = OwnedDeps; pub fn proper_initialization( curve_config: CurveConfig, - restriction: CurveRestriction, + authorized_operator_addresses: Option>, ) -> (MockDeps, MessageInfo) { let mut deps = mock_dependencies_custom(&[]); let info = mock_info("creator", &[]); @@ -26,7 +27,7 @@ pub fn proper_initialization( kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, curve_config, - restriction, + authorized_operator_addresses, }; let env = mock_env(); let res = instantiate(deps.as_mut(), env, info.clone(), msg).unwrap(); @@ -36,7 +37,7 @@ pub fn proper_initialization( pub fn error_initialization( curve_config: CurveConfig, - restriction: CurveRestriction, + authorized_operator_addresses: Option>, ) -> ContractError { let mut deps = mock_dependencies_custom(&[]); let info = mock_info("creator", &[]); @@ -44,7 +45,7 @@ pub fn error_initialization( kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, curve_config, - restriction, + authorized_operator_addresses, }; let env = mock_env(); let res = instantiate(deps.as_mut(), env, info.clone(), msg).unwrap_err(); @@ -67,24 +68,6 @@ pub fn reset(deps: DepsMut<'_>, sender: &str) -> Result execute(deps, mock_env(), info, msg) } -pub fn update_restriction( - deps: DepsMut<'_>, - restriction: CurveRestriction, - sender: &str, -) -> Result { - let msg = ExecuteMsg::UpdateRestriction { restriction }; - let info = mock_info(sender, &[]); - execute(deps, mock_env(), info, msg) -} - -pub fn query_restriction(deps: Deps) -> Result { - let res = query(deps, mock_env(), QueryMsg::GetRestriction {}); - match res { - Ok(res) => Ok(from_json(res).unwrap()), - Err(err) => Err(err), - } -} - pub fn query_curve_config(deps: Deps) -> Result { let res = query(deps, mock_env(), QueryMsg::GetCurveConfig {}); match res { diff --git a/contracts/modules/andromeda-curve/src/testing/tests.rs b/contracts/modules/andromeda-curve/src/testing/tests.rs index 2bb3cd31a..254655e0e 100644 --- a/contracts/modules/andromeda-curve/src/testing/tests.rs +++ b/contracts/modules/andromeda-curve/src/testing/tests.rs @@ -1,9 +1,9 @@ use super::mock::{ - error_initialization, proper_initialization, query_curve_config, query_plot_y_from_x, - query_restriction, reset, update_curve_config, update_restriction, + error_initialization, proper_initialization, query_curve_config, query_plot_y_from_x, reset, + update_curve_config, }; -use andromeda_modules::curve::{CurveConfig, CurveId, CurveRestriction}; -use andromeda_std::error::ContractError; +use andromeda_modules::curve::{CurveConfig, CurveType}; +use andromeda_std::{amp::AndrAddr, error::ContractError}; use cosmwasm_std::StdError; use test_case::test_case; @@ -11,78 +11,69 @@ use test_case::test_case; fn test_instantiation() { proper_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 2, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + None, ); } #[test] -fn test_update_restriction() { - let (mut deps, info) = proper_initialization( +fn test_reset() { + let (mut deps, _) = proper_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 2, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + Some(vec![AndrAddr::from_string("user1")]), ); - let external_user = "external".to_string(); - let res = - update_restriction(deps.as_mut(), CurveRestriction::Private, &external_user).unwrap_err(); - assert_eq!(res, ContractError::Unauthorized {}); - update_restriction( - deps.as_mut(), - CurveRestriction::Public, - info.sender.as_ref(), - ) - .unwrap(); - let restriction = query_restriction(deps.as_ref()).unwrap().restriction; - assert_eq!(restriction, CurveRestriction::Public); -} + let err_res = reset(deps.as_mut(), "user2").unwrap_err(); + assert_eq!(err_res, ContractError::Unauthorized {}); -#[test] -fn test_reset() { - let (mut deps, info) = proper_initialization( - CurveConfig::ExpConfig { - curve_id: CurveId::Growth, - base_value: 2, - multiple_variable_value: None, - constant_value: None, - }, - CurveRestriction::Private, - ); + reset(deps.as_mut(), "user1").unwrap(); - reset(deps.as_mut(), info.sender.as_ref()).unwrap(); let err_res = query_curve_config(deps.as_ref()).unwrap_err(); assert_eq!(err_res, ContractError::Std(StdError::NotFound { kind: "type: andromeda_modules::curve::CurveConfig; key: [63, 75, 72, 76, 65, 5F, 63, 6F, 6E, 66, 69, 67]".to_string() })); } #[test] fn test_update_curve_config() { - let (mut deps, info) = proper_initialization( + let (mut deps, _) = proper_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 2, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + Some(vec![AndrAddr::from_string("user1")]), ); + let err_res = update_curve_config( + deps.as_mut(), + CurveConfig::ExpConfig { + curve_type: CurveType::Growth, + base_value: 4, + multiple_variable_value: None, + constant_value: Some(2), + }, + "user2", + ) + .unwrap_err(); + assert_eq!(err_res, ContractError::Unauthorized {}); + update_curve_config( deps.as_mut(), CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 4, multiple_variable_value: None, constant_value: Some(2), }, - info.sender.as_ref(), + "user1", ) .unwrap(); @@ -90,7 +81,7 @@ fn test_update_curve_config() { assert_eq!( res, CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 4, multiple_variable_value: None, constant_value: Some(2), @@ -102,18 +93,18 @@ fn test_update_curve_config() { fn test_query_curve_config() { let (deps, _info) = proper_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 2, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + None, ); let res = query_curve_config(deps.as_ref()).unwrap().curve_config; assert_eq!( res, CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 2, multiple_variable_value: None, constant_value: None, @@ -125,12 +116,12 @@ fn test_query_curve_config() { fn test_query_curve_config_base_is_0() { let err_res = error_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 0, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + None, ); assert_eq!( err_res, @@ -146,12 +137,12 @@ fn test_query_curve_config_base_is_0() { fn test_query_plot_y_from_x_base_2_growth(input_x: f64, expected_y: String) { let (deps, _info) = proper_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 2, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + None, ); let res = query_plot_y_from_x(deps.as_ref(), input_x).unwrap().y_value; @@ -164,12 +155,12 @@ fn test_query_plot_y_from_x_base_2_growth(input_x: f64, expected_y: String) { fn test_query_plot_y_from_x_base_3_growth(input_x: f64, expected_y: String) { let (deps, _info) = proper_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 3, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + None, ); let res = query_plot_y_from_x(deps.as_ref(), input_x).unwrap().y_value; @@ -182,12 +173,12 @@ fn test_query_plot_y_from_x_base_3_growth(input_x: f64, expected_y: String) { fn test_query_plot_y_from_x_base_2_decay(input_x: f64, expected_y: String) { let (deps, _info) = proper_initialization( CurveConfig::ExpConfig { - curve_id: CurveId::Decay, + curve_type: CurveType::Decay, base_value: 2, multiple_variable_value: None, constant_value: None, }, - CurveRestriction::Private, + None, ); let res = query_plot_y_from_x(deps.as_ref(), input_x).unwrap().y_value; diff --git a/packages/andromeda-modules/src/curve.rs b/packages/andromeda-modules/src/curve.rs index cfab24592..74e48caf5 100644 --- a/packages/andromeda-modules/src/curve.rs +++ b/packages/andromeda-modules/src/curve.rs @@ -1,4 +1,4 @@ -use andromeda_std::{andr_exec, andr_instantiate, andr_query, error::ContractError}; +use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query, error::ContractError}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::ensure; @@ -6,17 +6,11 @@ use cosmwasm_std::ensure; #[cw_serde] pub struct InstantiateMsg { pub curve_config: CurveConfig, - pub restriction: CurveRestriction, + pub authorized_operator_addresses: Option>, } #[cw_serde] -pub enum CurveRestriction { - Private, - Public, -} - -#[cw_serde] -pub enum CurveId { +pub enum CurveType { Growth, Decay, } @@ -24,7 +18,7 @@ pub enum CurveId { #[cw_serde] pub enum CurveConfig { ExpConfig { - curve_id: CurveId, + curve_type: CurveType, base_value: u64, multiple_variable_value: Option, constant_value: Option, @@ -35,7 +29,7 @@ impl CurveConfig { pub fn validate(&self) -> Result<(), ContractError> { match self { CurveConfig::ExpConfig { - curve_id: _, + curve_type: _, base_value, multiple_variable_value: _, constant_value: _, @@ -56,7 +50,6 @@ impl CurveConfig { #[cw_serde] pub enum ExecuteMsg { UpdateCurveConfig { curve_config: CurveConfig }, - UpdateRestriction { restriction: CurveRestriction }, Reset {}, } @@ -66,8 +59,6 @@ pub enum ExecuteMsg { pub enum QueryMsg { #[returns(GetCurveConfigResponse)] GetCurveConfig {}, - #[returns(GetRestrictionResponse)] - GetRestriction {}, #[returns(GetPlotYFromXResponse)] GetPlotYFromX { x_value: f64 }, } @@ -82,11 +73,6 @@ pub struct GetPlotYFromXResponse { pub y_value: String, } -#[cw_serde] -pub struct GetRestrictionResponse { - pub restriction: CurveRestriction, -} - #[cfg(test)] mod test { use super::*; @@ -94,7 +80,7 @@ mod test { #[test] fn test_validate_valid() { let curve_config = CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 4, multiple_variable_value: None, constant_value: None, @@ -105,7 +91,7 @@ mod test { #[test] fn test_validate_invalid() { let curve_config = CurveConfig::ExpConfig { - curve_id: CurveId::Growth, + curve_type: CurveType::Growth, base_value: 0, multiple_variable_value: None, constant_value: None, From b497e7d2f26d017ae0067e5688782256aa4e3e26 Mon Sep 17 00:00:00 2001 From: Joe Monem <66594578+joemonem@users.noreply.github.com> Date: Wed, 27 Nov 2024 16:24:31 +0200 Subject: [PATCH 2/6] ref: rename release_unit to release_duration (#674) --- Cargo.lock | 2 +- .../finance/andromeda-vesting/Cargo.toml | 2 +- .../finance/andromeda-vesting/src/contract.rs | 30 ++-- .../finance/andromeda-vesting/src/state.rs | 10 +- .../andromeda-vesting/src/testing/tests.rs | 161 ++++++++++-------- packages/andromeda-finance/src/vesting.rs | 8 +- 6 files changed, 113 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3d35a52d..e7a11fd32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -958,7 +958,7 @@ dependencies = [ [[package]] name = "andromeda-vesting" -version = "3.0.4-b.1" +version = "3.0.4-b.2" dependencies = [ "andromeda-app", "andromeda-finance", diff --git a/contracts/finance/andromeda-vesting/Cargo.toml b/contracts/finance/andromeda-vesting/Cargo.toml index 439fcd695..1e1326ca3 100644 --- a/contracts/finance/andromeda-vesting/Cargo.toml +++ b/contracts/finance/andromeda-vesting/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-vesting" -version = "3.0.4-b.1" +version = "3.0.4-b.2" edition = "2021" rust-version = "1.75.0" diff --git a/contracts/finance/andromeda-vesting/src/contract.rs b/contracts/finance/andromeda-vesting/src/contract.rs index 16f8a5a1a..9b4a8b316 100644 --- a/contracts/finance/andromeda-vesting/src/contract.rs +++ b/contracts/finance/andromeda-vesting/src/contract.rs @@ -89,9 +89,9 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_create_batch(ctx, lockup_duration, release_unit, release_amount), + } => execute_create_batch(ctx, lockup_duration, release_duration, release_amount), ExecuteMsg::Claim { number_of_claims, batch_id, @@ -105,7 +105,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result, - release_unit: Milliseconds, + release_duration: Milliseconds, release_amount: WithdrawalType, ) -> Result { let ExecuteContext { @@ -136,7 +136,7 @@ fn execute_create_batch( ); ensure!( - !release_unit.is_zero() && !release_amount.is_zero(), + !release_duration.is_zero() && !release_amount.is_zero(), ContractError::InvalidZeroAmount {} ); ensure!( @@ -180,7 +180,7 @@ fn execute_create_batch( amount: funds.amount, amount_claimed: Uint128::zero(), lockup_end, - release_unit, + release_duration, release_amount, last_claimed_release_time: lockup_end, }; @@ -191,7 +191,7 @@ fn execute_create_batch( .add_attribute("action", "create_batch") .add_attribute("amount", funds.amount) .add_attribute("lockup_end", lockup_end.to_string()) - .add_attribute("release_unit", release_unit.to_string()) + .add_attribute("release_duration", release_duration.to_string()) .add_attribute("release_amount", release_amount_string)) } @@ -274,7 +274,8 @@ fn execute_claim_all( let key = batches().key(batch_id); let elapsed_time = up_to_time.minus_milliseconds(batch.last_claimed_release_time); - let num_available_claims = elapsed_time.milliseconds() / batch.release_unit.milliseconds(); + let num_available_claims = + elapsed_time.milliseconds() / batch.release_duration.milliseconds(); let amount_to_send = claim_batch( &deps.querier, @@ -321,7 +322,7 @@ fn claim_batch( .query_balance(querier, env.contract.address.to_owned())?; let elapsed_time = current_time.minus_milliseconds(batch.last_claimed_release_time); - let num_available_claims = elapsed_time.milliseconds() / batch.release_unit.milliseconds(); + let num_available_claims = elapsed_time.milliseconds() / batch.release_duration.milliseconds(); let number_of_claims = cmp::min( number_of_claims.unwrap_or(num_available_claims), @@ -342,19 +343,20 @@ fn claim_batch( batch.amount_claimed = batch.amount_claimed.checked_add(amount_to_send)?; // Safe math version - let claims_release_unit = number_of_claims.checked_mul(batch.release_unit.milliseconds()); - if claims_release_unit.is_none() { + let claims_release_duration = + number_of_claims.checked_mul(batch.release_duration.milliseconds()); + if claims_release_duration.is_none() { return Err(ContractError::Overflow {}); } - let claims_release_unit = Milliseconds(claims_release_unit.unwrap()); + let claims_release_duration = Milliseconds(claims_release_duration.unwrap()); batch.last_claimed_release_time = batch .last_claimed_release_time - .plus_milliseconds(claims_release_unit); + .plus_milliseconds(claims_release_duration); // The unsafe version - // batch.last_claimed_release_time += number_of_claims * batch.release_unit; + // batch.last_claimed_release_time += number_of_claims * batch.release_duration; } Ok(amount_to_send) @@ -433,7 +435,7 @@ fn get_batch_response( number_of_available_claims, lockup_end: batch.lockup_end, release_amount: batch.release_amount, - release_unit: batch.release_unit, + release_duration: batch.release_duration, last_claimed_release_time: previous_last_claimed_release_time, }; diff --git a/contracts/finance/andromeda-vesting/src/state.rs b/contracts/finance/andromeda-vesting/src/state.rs index 7b96f0b45..c82a08ba4 100644 --- a/contracts/finance/andromeda-vesting/src/state.rs +++ b/contracts/finance/andromeda-vesting/src/state.rs @@ -22,8 +22,8 @@ pub struct Batch { /// When the lockup ends. pub lockup_end: Milliseconds, /// How often releases occur. - pub release_unit: Milliseconds, - /// Specifies how much is to be released after each `release_unit`. If + pub release_duration: Milliseconds, + /// Specifies how much is to be released after each `release_duration`. If /// it is a percentage, it would be the percentage of the original amount. pub release_amount: WithdrawalType, /// The time at which the last claim took place in seconds. @@ -140,7 +140,7 @@ mod tests { amount: Uint128::new(100), amount_claimed: Uint128::zero(), lockup_end: current_time.plus_seconds(10), - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: current_time.minus_seconds(1), }; @@ -149,7 +149,7 @@ mod tests { amount: Uint128::new(100), amount_claimed: Uint128::zero(), lockup_end: current_time.minus_seconds(1), - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: current_time.minus_seconds(1), }; @@ -158,7 +158,7 @@ mod tests { amount: Uint128::new(100), amount_claimed: Uint128::new(100), lockup_end: current_time.minus_seconds(1), - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: current_time.minus_seconds(1), }; diff --git a/contracts/finance/andromeda-vesting/src/testing/tests.rs b/contracts/finance/andromeda-vesting/src/testing/tests.rs index c54c1715d..8bc2aed2f 100644 --- a/contracts/finance/andromeda-vesting/src/testing/tests.rs +++ b/contracts/finance/andromeda-vesting/src/testing/tests.rs @@ -33,13 +33,13 @@ fn init(deps: DepsMut) -> Response { fn create_batch( deps: DepsMut, lockup_duration: Option, - release_unit: Milliseconds, + release_duration: Milliseconds, release_amount: WithdrawalType, ) -> Response { - // Create batch with half of the release_unit. + // Create batch with half of the release_duration. let msg = ExecuteMsg::CreateBatch { lockup_duration, - release_unit, + release_duration, release_amount, }; @@ -116,7 +116,7 @@ fn test_create_batch_unauthorized() { let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::from_seconds(1), + release_duration: Milliseconds::from_seconds(1), release_amount: WithdrawalType::Amount(Uint128::zero()), }; @@ -135,7 +135,7 @@ fn test_create_batch_no_funds() { let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::from_seconds(1), + release_duration: Milliseconds::from_seconds(1), release_amount: WithdrawalType::Amount(Uint128::zero()), }; @@ -158,7 +158,7 @@ fn test_create_batch_invalid_denom() { let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::from_seconds(1), + release_duration: Milliseconds::from_seconds(1), release_amount: WithdrawalType::Amount(Uint128::zero()), }; @@ -181,7 +181,7 @@ fn test_create_batch_valid_denom_zero_amount() { let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::from_seconds(1), + release_duration: Milliseconds::from_seconds(1), release_amount: WithdrawalType::Amount(Uint128::zero()), }; @@ -191,7 +191,7 @@ fn test_create_batch_valid_denom_zero_amount() { } #[test] -fn test_create_batch_release_unit_zero() { +fn test_create_batch_release_duration_zero() { let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); init(deps.as_mut()); @@ -199,7 +199,7 @@ fn test_create_batch_release_unit_zero() { let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::zero(), + release_duration: Milliseconds::zero(), release_amount: WithdrawalType::Amount(Uint128::zero()), }; @@ -217,7 +217,7 @@ fn test_create_batch_release_amount_zero() { let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::zero()), }; @@ -235,7 +235,7 @@ fn test_create_batch() { let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -247,7 +247,10 @@ fn test_create_batch() { .add_attribute("action", "create_batch") .add_attribute("amount", "100") .add_attribute("lockup_end", current_time.to_string()) - .add_attribute("release_unit", Milliseconds::from_seconds(10).to_string()) + .add_attribute( + "release_duration", + Milliseconds::from_seconds(10).to_string() + ) .add_attribute("release_amount", "Amount(Uint128(10))"), res ); @@ -259,7 +262,7 @@ fn test_create_batch() { amount: Uint128::new(100), amount_claimed: Uint128::zero(), lockup_end: current_time, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: current_time, }, @@ -271,7 +274,7 @@ fn test_create_batch() { // Try to create another batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: Some(Milliseconds::from_seconds(100)), - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -282,7 +285,10 @@ fn test_create_batch() { .add_attribute("action", "create_batch") .add_attribute("amount", "100") .add_attribute("lockup_end", (current_time.plus_seconds(100)).to_string()) - .add_attribute("release_unit", Milliseconds::from_seconds(10).to_string()) + .add_attribute( + "release_duration", + Milliseconds::from_seconds(10).to_string() + ) .add_attribute("release_amount", "Amount(Uint128(10))"), res ); @@ -294,7 +300,7 @@ fn test_create_batch() { amount: Uint128::new(100), amount_claimed: Uint128::zero(), lockup_end: current_time.plus_seconds(100), - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: current_time.plus_seconds(100), }, @@ -330,7 +336,7 @@ fn test_claim_batch_still_locked() { // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: Some(Milliseconds::from_seconds(100)), - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -356,7 +362,7 @@ fn test_claim_batch_no_funds_available() { // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -380,12 +386,12 @@ fn test_claim_batch_single_claim() { init(deps.as_mut()); let info = mock_info("owner", &coins(100, "uusd")); - let release_unit = Milliseconds::from_seconds(10); + let release_duration = Milliseconds::from_seconds(10); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -398,7 +404,7 @@ fn test_claim_batch_single_claim() { // Skip time. let mut env = mock_env(); // A single release is available. - env.block.time = env.block.time.plus_seconds(release_unit.seconds()); + env.block.time = env.block.time.plus_seconds(release_duration.seconds()); // Query created batch. let msg = QueryMsg::Batch { id: 1 }; @@ -413,7 +419,7 @@ fn test_claim_batch_single_claim() { amount_available_to_claim: Uint128::new(10), number_of_available_claims: Uint128::new(1), lockup_end, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: lockup_end, }, @@ -447,9 +453,9 @@ fn test_claim_batch_single_claim() { amount: Uint128::new(100), amount_claimed: Uint128::new(10), lockup_end, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), - last_claimed_release_time: lockup_end.plus_milliseconds(release_unit), + last_claimed_release_time: lockup_end.plus_milliseconds(release_duration), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -461,12 +467,12 @@ fn test_claim_batch_not_nice_numbers_single_release() { init(deps.as_mut()); let info = mock_info("owner", &coins(10, "uusd")); - let release_unit = Milliseconds::from_seconds(10); + let release_duration = Milliseconds::from_seconds(10); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -479,7 +485,7 @@ fn test_claim_batch_not_nice_numbers_single_release() { // Skip time. let mut env = mock_env(); // A single release is available. - env.block.time = env.block.time.plus_seconds(release_unit.seconds()); + env.block.time = env.block.time.plus_seconds(release_duration.seconds()); // Claim batch. let msg = ExecuteMsg::Claim { @@ -508,9 +514,9 @@ fn test_claim_batch_not_nice_numbers_single_release() { amount: Uint128::new(10), amount_claimed: Uint128::new(7), lockup_end, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), - last_claimed_release_time: lockup_end.plus_milliseconds(release_unit), + last_claimed_release_time: lockup_end.plus_milliseconds(release_duration), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -523,14 +529,14 @@ fn test_claim_batch_not_nice_numbers_multiple_releases() { let vesting_amount = 1_000_000_000_000_000_000u128; let info = mock_info("owner", &coins(vesting_amount, "uusd")); - let release_unit = Milliseconds::from_seconds(1); // 1 second + let release_duration = Milliseconds::from_seconds(1); // 1 second let duration: u64 = 60 * 60 * 24 * 365 * 5; // 5 years let percent_release = Decimal::from_ratio(Uint128::one(), Uint128::from(duration)); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit, + release_duration, release_amount: WithdrawalType::Percentage(percent_release), }; @@ -543,7 +549,7 @@ fn test_claim_batch_not_nice_numbers_multiple_releases() { // Skip time. let mut env = mock_env(); // Two releases are out. - env.block.time = env.block.time.plus_seconds(2 * release_unit.seconds()); + env.block.time = env.block.time.plus_seconds(2 * release_duration.seconds()); // Claim batch. let msg = ExecuteMsg::Claim { @@ -572,9 +578,9 @@ fn test_claim_batch_not_nice_numbers_multiple_releases() { amount: Uint128::new(vesting_amount), amount_claimed: Uint128::new(12683916792), lockup_end, - release_unit: Milliseconds::from_seconds(1), + release_duration: Milliseconds::from_seconds(1), release_amount: WithdrawalType::Percentage(percent_release), - last_claimed_release_time: lockup_end.plus_seconds(2 * release_unit.seconds()), + last_claimed_release_time: lockup_end.plus_seconds(2 * release_duration.seconds()), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -600,7 +606,7 @@ fn test_claim_batch_not_nice_numbers_multiple_releases() { amount: Uint128::new(vesting_amount), amount_claimed: Uint128::from(vesting_amount), lockup_end, - release_unit: Milliseconds::from_seconds(1), + release_duration: Milliseconds::from_seconds(1), release_amount: WithdrawalType::Percentage(percent_release), last_claimed_release_time: lockup_end.plus_seconds(duration + 2), }, @@ -614,12 +620,12 @@ fn test_claim_batch_middle_of_interval() { init(deps.as_mut()); let info = mock_info("owner", &coins(100, "uusd")); - let release_unit = Milliseconds::from_seconds(10); + let release_duration = Milliseconds::from_seconds(10); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -637,14 +643,14 @@ fn test_claim_batch_middle_of_interval() { let mut env = mock_env(); // Only halfway to first release. - env.block.time = env.block.time.plus_seconds(release_unit.seconds() / 2); + env.block.time = env.block.time.plus_seconds(release_duration.seconds() / 2); let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); assert_eq!(ContractError::WithdrawalIsEmpty {}, res.unwrap_err()); // First release available and halfway to second -> result is rounding down. - env.block.time = env.block.time.plus_seconds(release_unit.seconds()); + env.block.time = env.block.time.plus_seconds(release_duration.seconds()); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( @@ -666,9 +672,9 @@ fn test_claim_batch_middle_of_interval() { amount: Uint128::new(100), amount_claimed: Uint128::new(10), lockup_end, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), - last_claimed_release_time: lockup_end.plus_milliseconds(release_unit), + last_claimed_release_time: lockup_end.plus_milliseconds(release_duration), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -680,12 +686,12 @@ fn test_claim_batch_multiple_claims() { init(deps.as_mut()); let info = mock_info("owner", &coins(100, "uusd")); - let release_unit = Milliseconds::from_seconds(10); + let release_duration = Milliseconds::from_seconds(10); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -698,7 +704,7 @@ fn test_claim_batch_multiple_claims() { let mut env = mock_env(); // 4 releases are available. - env.block.time = env.block.time.plus_seconds(4 * release_unit.seconds()); + env.block.time = env.block.time.plus_seconds(4 * release_duration.seconds()); // Claim only the first release. let msg = ExecuteMsg::Claim { @@ -726,9 +732,9 @@ fn test_claim_batch_multiple_claims() { amount: Uint128::new(100), amount_claimed: Uint128::new(10), lockup_end, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), - last_claimed_release_time: lockup_end.plus_milliseconds(release_unit), + last_claimed_release_time: lockup_end.plus_milliseconds(release_duration), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -759,9 +765,9 @@ fn test_claim_batch_multiple_claims() { amount: Uint128::new(100), amount_claimed: Uint128::new(40), lockup_end, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), - last_claimed_release_time: lockup_end.plus_seconds(4 * release_unit.seconds()), + last_claimed_release_time: lockup_end.plus_seconds(4 * release_duration.seconds()), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -773,12 +779,12 @@ fn test_claim_batch_all_releases() { init(deps.as_mut()); let info = mock_info("owner", &coins(100, "uusd")); - let release_unit = Milliseconds::from_seconds(10); + let release_duration = Milliseconds::from_seconds(10); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -790,9 +796,9 @@ fn test_claim_batch_all_releases() { let mut env = mock_env(); - // All releases are available and then some (10 * release_unit would be when all releases + // All releases are available and then some (10 * release_duration would be when all releases // become available). - env.block.time = env.block.time.plus_seconds(15 * release_unit.seconds()); + env.block.time = env.block.time.plus_seconds(15 * release_duration.seconds()); // Claim only the first release. let msg = ExecuteMsg::Claim { @@ -820,9 +826,9 @@ fn test_claim_batch_all_releases() { amount: Uint128::new(100), amount_claimed: Uint128::new(100), lockup_end, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), - last_claimed_release_time: lockup_end.plus_seconds(15 * release_unit.seconds()), + last_claimed_release_time: lockup_end.plus_seconds(15 * release_duration.seconds()), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -839,12 +845,12 @@ fn test_claim_batch_too_high_of_claim() { init(deps.as_mut()); let info = mock_info("owner", &coins(100, "uusd")); - let release_unit = Milliseconds::from_seconds(10); + let release_duration = Milliseconds::from_seconds(10); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), }; @@ -856,7 +862,7 @@ fn test_claim_batch_too_high_of_claim() { let mut env = mock_env(); // A single release is available. - env.block.time = env.block.time.plus_seconds(release_unit.seconds()); + env.block.time = env.block.time.plus_seconds(release_duration.seconds()); // Try to claim 3 releases. let msg = ExecuteMsg::Claim { @@ -886,9 +892,9 @@ fn test_claim_batch_too_high_of_claim() { amount: Uint128::new(100), amount_claimed: Uint128::new(10), lockup_end, - release_unit: Milliseconds::from_seconds(10), + release_duration: Milliseconds::from_seconds(10), release_amount: WithdrawalType::Amount(Uint128::new(10)), - last_claimed_release_time: lockup_end.plus_milliseconds(release_unit), + last_claimed_release_time: lockup_end.plus_milliseconds(release_duration), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -916,21 +922,26 @@ fn test_claim_all() { let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); init(deps.as_mut()); - let release_unit = Milliseconds::from_seconds(10); + let release_duration = Milliseconds::from_seconds(10); let release_amount = WithdrawalType::Amount(Uint128::new(10)); // Create batch. - create_batch(deps.as_mut(), None, release_unit, release_amount.clone()); + create_batch( + deps.as_mut(), + None, + release_duration, + release_amount.clone(), + ); - // Create batch with half of the release_unit. + // Create batch with half of the release_duration. create_batch( deps.as_mut(), None, - Milliseconds::from_seconds(release_unit.seconds() / 2), + Milliseconds::from_seconds(release_duration.seconds() / 2), release_amount.clone(), ); - // Create batch with a different release_unit scale (not a factor). + // Create batch with a different release_duration scale (not a factor). create_batch( deps.as_mut(), None, @@ -942,7 +953,7 @@ fn test_claim_all() { create_batch( deps.as_mut(), Some(Milliseconds::from_seconds(100)), - release_unit, + release_duration, release_amount.clone(), ); @@ -952,7 +963,7 @@ fn test_claim_all() { // Speed up time. let mut env = mock_env(); - env.block.time = env.block.time.plus_seconds(release_unit.seconds() * 2); + env.block.time = env.block.time.plus_seconds(release_duration.seconds() * 2); // Query batches let msg = QueryMsg::Batches { @@ -972,7 +983,7 @@ fn test_claim_all() { amount_available_to_claim: Uint128::new(20), number_of_available_claims: Uint128::new(2), lockup_end, - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: lockup_end, }, @@ -983,7 +994,7 @@ fn test_claim_all() { amount_available_to_claim: Uint128::new(40), number_of_available_claims: Uint128::new(4), lockup_end, - release_unit: Milliseconds::from_seconds(release_unit.seconds() / 2), + release_duration: Milliseconds::from_seconds(release_duration.seconds() / 2), release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: lockup_end, }, @@ -994,7 +1005,7 @@ fn test_claim_all() { amount_available_to_claim: Uint128::new(10), number_of_available_claims: Uint128::new(1), lockup_end, - release_unit: Milliseconds::from_seconds(12), + release_duration: Milliseconds::from_seconds(12), release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: lockup_end, }, @@ -1005,7 +1016,7 @@ fn test_claim_all() { amount_available_to_claim: Uint128::zero(), number_of_available_claims: Uint128::zero(), lockup_end: lockup_end.plus_seconds(100), - release_unit, + release_duration, release_amount: WithdrawalType::Amount(Uint128::new(10)), last_claimed_release_time: lockup_end.plus_seconds(100), }, @@ -1040,9 +1051,9 @@ fn test_claim_all() { amount: Uint128::new(100), amount_claimed: Uint128::new(20), lockup_end, - release_unit, + release_duration, release_amount: release_amount.clone(), - last_claimed_release_time: lockup_end.plus_seconds(release_unit.seconds() * 2), + last_claimed_release_time: lockup_end.plus_seconds(release_duration.seconds() * 2), }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); @@ -1052,9 +1063,9 @@ fn test_claim_all() { amount: Uint128::new(100), amount_claimed: Uint128::new(40), lockup_end, - release_unit: Milliseconds::from_seconds(release_unit.seconds() / 2), + release_duration: Milliseconds::from_seconds(release_duration.seconds() / 2), release_amount: release_amount.clone(), - last_claimed_release_time: lockup_end.plus_seconds(release_unit.seconds() * 2), + last_claimed_release_time: lockup_end.plus_seconds(release_duration.seconds() * 2), }, batches().load(deps.as_ref().storage, 2u64).unwrap() ); @@ -1064,7 +1075,7 @@ fn test_claim_all() { amount: Uint128::new(100), amount_claimed: Uint128::new(10), lockup_end, - release_unit: Milliseconds::from_seconds(12), + release_duration: Milliseconds::from_seconds(12), release_amount, last_claimed_release_time: lockup_end.plus_seconds(12), }, diff --git a/packages/andromeda-finance/src/vesting.rs b/packages/andromeda-finance/src/vesting.rs index aa5a5480b..4b40c95a5 100644 --- a/packages/andromeda-finance/src/vesting.rs +++ b/packages/andromeda-finance/src/vesting.rs @@ -37,8 +37,8 @@ pub enum ExecuteMsg { /// Specifying None would mean no lock up period and funds start vesting right away. lockup_duration: Option, /// How often releases occur in seconds. - release_unit: Milliseconds, - /// Specifies how much is to be released after each `release_unit`. If + release_duration: Milliseconds, + /// Specifies how much is to be released after each `release_duration`. If /// it is a percentage, it would be the percentage of the original amount. release_amount: WithdrawalType, }, @@ -85,8 +85,8 @@ pub struct BatchResponse { /// When the lockup ends. pub lockup_end: Milliseconds, /// How often releases occur. - pub release_unit: Milliseconds, - /// Specifies how much is to be released after each `release_unit`. If + pub release_duration: Milliseconds, + /// Specifies how much is to be released after each `release_duration`. If /// it is a percentage, it would be the percentage of the original amount. pub release_amount: WithdrawalType, /// The time at which the last claim took place in seconds. From bc881a5dffbfd6345b1fcad6ccd03a27701ce601 Mon Sep 17 00:00:00 2001 From: Dimitrije Dragasevic Date: Wed, 27 Nov 2024 15:30:11 +0100 Subject: [PATCH 3/6] Ci workflow (#673) Co-authored-by: Connor Barr --- .github/workflows/build.yml | 45 +++++++++++++- .github/workflows/deploy.yml | 111 +++++++++++++++++++++++++++++++---- 2 files changed, 145 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af12088cb..002399596 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,9 +1,25 @@ name: Build Contracts & Schemas - on: pull_request: branches: [main, development] workflow_dispatch: + inputs: + network: + description: "Network to deploy to" + required: true + type: string + kernel_address: + description: "Kernel address" + required: false + type: string + deploy_os: + description: "Deploy OS" + required: false + type: boolean + contracts: + description: "Contracts to deploy" + required: false + type: string jobs: build: @@ -51,3 +67,30 @@ jobs: name: schema path: ./schemas/ if-no-files-found: error + + trigger-deploy: + needs: [build, build-schemas] + if: github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + steps: + - name: Trigger Deploy Workflow + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.CI_PAT }} + script: | + try { + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'deploy.yml', + ref: github.ref, + inputs: { + network: '${{ inputs.network }}', + kernel_address: '${{ inputs.kernel_address }}', + deploy_os: '${{ inputs.deploy_os }}', + contracts: '${{ inputs.contracts }}' + } + }); + } catch (error) { + core.setFailed(`Failed to trigger deploy workflow: ${error.message}`); + } \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1445493ee..b0fcb40f9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,5 +1,4 @@ name: Deploy OS - on: workflow_dispatch: inputs: @@ -16,7 +15,7 @@ on: required: false type: boolean contracts: - description: "Contracts to deploy (e.g. splitter, validator-staking)" + description: "Contracts to deploy" required: false type: string @@ -26,9 +25,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable - name: Build Contracts run: | - sudo make version-map + make version-map make build - name: Upload Artifacts uses: actions/upload-artifact@v4 @@ -36,6 +39,31 @@ jobs: name: contracts path: ./artifacts/ if-no-files-found: error + + + build_schemas: + if: contains('["crnbarr93", "SlayerAnsh", "joemonem", "DimitrijeDragasevic", "cowboy0015"]', github.actor) + runs-on: ubuntu-latest + outputs: + schema_url: ${{ steps.upload-schemas.outputs.artifact-url }} + steps: + - uses: actions/checkout@v4 + - name: Build Schemas + run: | + set -eo pipefail + make schemas || { + echo "Schema build failed" + exit 1 + } + - name: Upload Schemas to Temp + id: upload-schemas + uses: actions/upload-artifact@v4 + with: + name: temp-schemas + path: ./schemas/ + retention-days: 1 + if-no-files-found: error + build_deploy_script: if: contains('["crnbarr93", "SlayerAnsh", "joemonem", "DimitrijeDragasevic", "cowboy0015"]', github.actor) runs-on: ubuntu-latest @@ -49,9 +77,10 @@ jobs: name: deploy path: ./target/release/andromeda-deploy if-no-files-found: error + deploy: runs-on: ubuntu-latest - needs: [build_contracts, build_deploy_script] + needs: [build_contracts, build_schemas, build_deploy_script] env: DEPLOYMENT_CHAIN: ${{ inputs.network }} DEPLOYMENT_KERNEL_ADDRESS: ${{ inputs.kernel_address }} @@ -80,9 +109,71 @@ jobs: run: | chmod +x ./andromeda-deploy ./andromeda-deploy - - name: Upload Deployment Report - uses: actions/upload-artifact@v4 - with: - name: deployment-report - path: ./deployment-reports/ - if-no-files-found: error + + trigger-schema-parser: + needs: [deploy, build_schemas] + runs-on: ubuntu-latest + steps: + - name: Set Branch Based on Kernel + id: check-kernel + run: | + KERNEL_ADDRESS="${{ inputs.kernel_address }}" + TESTNET_KERNELS="${{ vars.TESTNET_KERNELS }}" + TESTNET_STAGING_KERNELS="${{ vars.TESTNET_STAGING_KERNELS }}" + + if [[ "${KERNEL_ADDRESS}" == "${TESTNET_KERNELS}" ]]; then + echo "branch=develop" >> $GITHUB_OUTPUT + elif [[ "${KERNEL_ADDRESS}" == "${TESTNET_STAGING_KERNELS}" ]]; then + echo "branch=testnet-staging" >> $GITHUB_OUTPUT + else + echo "Error: Kernel not found in known configurations" + exit 1 + fi + + - name: Checkout Schema Parser + uses: actions/checkout@v4 + with: + repository: andromedaprotocol/schema-parser + ref: ${{ steps.check-kernel.outputs.branch }} + token: ${{ secrets.CI_PAT }} + + - name: Download Schemas + uses: actions/download-artifact@v4 + with: + name: temp-schemas + path: "packages/schema-parser/schema" + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'pnpm' + + - name: Process Schema + working-directory: packages/schema-parser + run: | + set -eo pipefail + echo "Installing dependencies..." + pnpm install + echo "Processing schema..." + npm run start + echo "Flattening schema..." + npm run flatten + echo "Exporting schema..." + npm run export + + - name: Commit and Push Changes + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + + if [[ -n $(git status --porcelain) ]]; then + git add . + git commit -m "chore: Update schema for kernel: ${{ inputs.kernel_address }}" + git push + else + echo "No changes to commit" + fi \ No newline at end of file From 824c60a0260534ec6fcbe5bf187b18972a0da9de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 10:11:50 +0000 Subject: [PATCH 4/6] build(deps): bump pnpm/action-setup from 2 to 4 (#675) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b0fcb40f9..95c1823dd 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -143,7 +143,7 @@ jobs: name: temp-schemas path: "packages/schema-parser/schema" - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 with: version: 8 From cea9f7e75488e1fd2aa684d6ee3a2feb65429656 Mon Sep 17 00:00:00 2001 From: Connor Barr Date: Thu, 28 Nov 2024 10:22:28 +0000 Subject: [PATCH 5/6] Release 3 Changelog and Backport tags (#676) --- .github/mergify.yml | 8 ++++++++ CHANGELOG.md | 13 ++++++++++--- Cargo.lock | 4 ++-- .../finance/andromeda-validator-staking/Cargo.toml | 4 ++-- contracts/finance/andromeda-vesting/Cargo.toml | 2 +- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.github/mergify.yml b/.github/mergify.yml index 6c845f972..960a92ce1 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -13,3 +13,11 @@ pull_request_rules: backport: branches: - v1.1.x + - name: backport to release/3 branch + conditions: + - base=development + - label=backport/release/3 + actions: + backport: + branches: + - release/3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d017bfd9..69bf5162a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added Curve ADO [(#515)](https://github.com/andromedaprotocol/andromeda-core/pull/515) +### Changed + +### Fixed + +## Release 3 + +### Added + - Added IBC Registry ADO [(#566)](https://github.com/andromedaprotocol/andromeda-core/pull/566) - Added Denom Validation in IBC Registry ADO [(#571)](https://github.com/andromedaprotocol/andromeda-core/pull/571) - Added Kernel ICS20 Transfer with Optional ExecuteMsg [(#577)](https://github.com/andromedaprotocol/andromeda-core/pull/577) @@ -17,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added deployment script/CI workflow for OS [(#616)](https://github.com/andromedaprotocol/andromeda-core/pull/616) - Added deployable interfaces to all ADOs [(#620)](https://github.com/andromedaprotocol/andromeda-core/pull/620) - Added MultiSig ADO [(#619)](https://github.com/andromedaprotocol/andromeda-core/pull/619) +- Added Validator Staking ADO [(#330)](https://github.com/andromedaprotocol/andromeda-core/pull/330) +- Added Restake and Redelegate to Validator Staking [(#622)](https://github.com/andromedaprotocol/andromeda-core/pull/622) ### Changed @@ -35,7 +44,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added Validator Staking ADO [(#330)](https://github.com/andromedaprotocol/andromeda-core/pull/330) - Added `Asset` enum [(#415)](https://github.com/andromedaprotocol/andromeda-core/pull/415) - Added `ADOBaseVersion` query to all ADOs [(#416)](https://github.com/andromedaprotocol/andromeda-core/pull/416) - Staking: Added ability to remove/replace reward token [(#418)](https://github.com/andromedaprotocol/andromeda-core/pull/418) @@ -54,7 +62,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added BuyNow option for Auction [(#533)](https://github.com/andromedaprotocol/andromeda-core/pull/533) - Include ADOBase Version in Schema [(#574)](https://github.com/andromedaprotocol/andromeda-core/pull/574) - Added multi-hop support for IBC [(#604)](https://github.com/andromedaprotocol/andromeda-core/pull/604) -- Added Restake and Redelegate to Validator Staking [(#622)](https://github.com/andromedaprotocol/andromeda-core/pull/622) ### Changed diff --git a/Cargo.lock b/Cargo.lock index e7a11fd32..48e0acd2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -926,7 +926,7 @@ dependencies = [ [[package]] name = "andromeda-validator-staking" -version = "0.3.0-b.1" +version = "0.3.0" dependencies = [ "andromeda-finance", "andromeda-std", @@ -958,7 +958,7 @@ dependencies = [ [[package]] name = "andromeda-vesting" -version = "3.0.4-b.2" +version = "3.0.4" dependencies = [ "andromeda-app", "andromeda-finance", diff --git a/contracts/finance/andromeda-validator-staking/Cargo.toml b/contracts/finance/andromeda-validator-staking/Cargo.toml index 7688331a7..bcd89b381 100644 --- a/contracts/finance/andromeda-validator-staking/Cargo.toml +++ b/contracts/finance/andromeda-validator-staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-validator-staking" -version = "0.3.0-b.1" +version = "0.3.0" edition = "2021" rust-version = "1.75.0" @@ -30,4 +30,4 @@ chrono = "0.3" cw-multi-test = { workspace = true, optional = true } andromeda-testing = { workspace = true } cw-orch = { workspace = true } -cw-orch-daemon = "0.24.2" \ No newline at end of file +cw-orch-daemon = "0.24.2" diff --git a/contracts/finance/andromeda-vesting/Cargo.toml b/contracts/finance/andromeda-vesting/Cargo.toml index 1e1326ca3..11e6b2839 100644 --- a/contracts/finance/andromeda-vesting/Cargo.toml +++ b/contracts/finance/andromeda-vesting/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-vesting" -version = "3.0.4-b.2" +version = "3.0.4" edition = "2021" rust-version = "1.75.0" From b7dfe0ffad0006ec102ca6696fc6cc5e8c0aa2d9 Mon Sep 17 00:00:00 2001 From: Connor Barr Date: Thu, 28 Nov 2024 10:23:24 +0000 Subject: [PATCH 6/6] ci: release tagging --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8af8731b2..7e5432980 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ name: Release Contracts on: push: tags: - - "v[0-9]+.[0-9]+.[0-9]+" + - "release/[0-9]+" jobs: optimize: