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

Rebalancer fixes 0.1.7 #107

Merged
merged 30 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
74d49fd
check account code id on rebalancing
Art3miX Jul 12, 2024
c6bef78
add min_balance trade to the trades list as well
Art3miX Jul 12, 2024
1bbcd13
schema
Art3miX Jul 12, 2024
d467cc5
revert readme
Art3miX Jul 12, 2024
439f3e0
fix typo
Art3miX Jul 12, 2024
70239ac
typo
Art3miX Jul 12, 2024
b2f727e
add resume and update tests
Art3miX Jul 12, 2024
ad59972
make a helper
Art3miX Jul 12, 2024
bd107a5
bump version
Art3miX Jul 12, 2024
3ed0999
continue if account is not whitelisted
Art3miX Jul 13, 2024
73a9f60
update schema
Art3miX Jul 13, 2024
08657f1
create the pid package
Art3miX Jul 18, 2024
073b1af
add serde
Art3miX Jul 18, 2024
d545416
change input
Art3miX Jul 18, 2024
c54b679
add testnet data
Art3miX Jul 24, 2024
50f9562
make rebalancer compatiable with workflow accounts
Art3miX Oct 31, 2024
8ef4d83
fix test
Art3miX Oct 31, 2024
49f47a6
add default to chain halt config
Art3miX Oct 31, 2024
6aa417a
add default for PriceFreshnessStrategy
Art3miX Oct 31, 2024
55fa820
merge main
Art3miX Nov 26, 2024
4d0d139
rename workflow to program
Art3miX Nov 26, 2024
7f26884
bump version
Art3miX Nov 26, 2024
8cbc7d1
get prices daily from auction or astroport, save prices locally, and …
Art3miX Nov 26, 2024
4f88640
readme
Art3miX Dec 2, 2024
4bee20d
add avg to manual price update as well
Art3miX Dec 2, 2024
463d162
add query in oracle and update testnet data
Art3miX Dec 2, 2024
388601c
merge
Art3miX Dec 2, 2024
13c1a94
fmt
Art3miX Dec 2, 2024
6739521
fix and add tests
Art3miX Dec 2, 2024
bc02679
add schemas
Art3miX Dec 3, 2024
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
File renamed without changes.
237 changes: 149 additions & 88 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ members = [
[workspace.package]
edition = "2021"
license = "BSL"
version = "0.1.6"
version = "0.1.7"
repository = "https://github.com/timewave-computer/valence-services"

rust-version = "1.66"
Expand Down
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,33 @@ The Rebalancer sends funds to be auctioned daily. If you are a market maker inte
- [untrn, newt] - `neutron1zvw9l8c82hnvwsntpuy89p86ztfmmudd9usfmnpa2tnqws74zsxq56sczm`
- [uusdc, newt] - `neutron1vu04szc78ae0nplwpuxjr6j592hn2d60zqtuts7w3ah6kajtxd2q2vfv59`

## Audits
## Neutron Testnet Contracts

Valence Services have been rigorously tested and audited. Find audits [here](./audits/)
[![Check Set-Up & Build](https://github.com/timewave-computer/valence-services/actions/workflows/check.yml/badge.svg)](https://github.com/timewave-computer/valence-services/actions/workflows/check.yml)

### Code ids

- auctions-manager - `5673`
- auction - `5679`
- services-manager - `5674`
- rebalancer - `8367`
- oracle - `8371`
- account - `5677`

### Addresses

- Services manager - `neutron13ncggwefau3xla04vlugy20meap7g7a9lf2d2sxwgwvgr9mnn3yqkpjzs6`
- Auctions manager - `neutron1669ftav8rv4hjuak89w04k7f0f7m9qq9564s00ld4m8dvhsr5hfsxy3x46`
- Rebalancer - `neutron1y9aurkegmqlqwhsnwctee4w4aja7n64yuat800p8yys509pyl0fsvrmydm`
- Oracle - `neutron1g4qcmk65nw57hmqlzk6cejnftg20zmctky0l2epdfz3npw3x2cmqprul6f`
- Account - `neutron1gc3tt3edg3drsc3aa22du9pa9f9s2gx6reu2hvq7s6yrdmy8zqjssfj52p`

### Auctions addresses

denom - `factory/neutron1phx0sz708k3t6xdnyc98hgkyhra4tp44et5s68/rebalancer-test`

- [untrn, test] - `neutron10p7d4ca0a5a3plx0d3dw0qmrnldfxwgq8q48205za6pgyhmqqzasg58fg4`
- [test, untrn] - `neutron1s859kh0cgte55fmgtksylw5khv8yxvhslpxmpqdy46fv8q7wxj8qtplru4`

## Security

Expand Down
2 changes: 1 addition & 1 deletion contracts/account/schema/valence-account.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"contract_name": "valence-account",
"contract_version": "0.1.5",
"contract_version": "0.1.7",
"idl_version": "1.0.0",
"instantiate": {
"$schema": "http://json-schema.org/draft-07/schema#",
Expand Down
2 changes: 1 addition & 1 deletion contracts/auction/auction/schema/auction.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"contract_name": "auction",
"contract_version": "0.1.5",
"contract_version": "0.1.7",
"idl_version": "1.0.0",
"instantiate": {
"$schema": "http://json-schema.org/draft-07/schema#",
Expand Down
21 changes: 14 additions & 7 deletions contracts/auction/auctions_manager/schema/auctions-manager.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"contract_name": "auctions-manager",
"contract_version": "0.1.5",
"contract_version": "0.1.7",
"idl_version": "1.0.0",
"instantiate": {
"$schema": "http://json-schema.org/draft-07/schema#",
Expand Down Expand Up @@ -185,12 +185,6 @@
"definitions": {
"AdminMsgs": {
"oneOf": [
{
"type": "string",
"enum": [
"cancel_admin_change"
]
},
{
"type": "object",
"required": [
Expand Down Expand Up @@ -488,6 +482,19 @@
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"cancel_admin_change"
],
"properties": {
"cancel_admin_change": {
"type": "object",
"additionalProperties": false
}
},
"additionalProperties": false
}
]
},
Expand Down
65 changes: 64 additions & 1 deletion contracts/auction/price_oracle/schema/price-oracle.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"contract_name": "price-oracle",
"contract_version": "0.1.5",
"contract_version": "0.1.7",
"idl_version": "1.0.0",
"instantiate": {
"$schema": "http://json-schema.org/draft-07/schema#",
Expand Down Expand Up @@ -359,6 +359,27 @@
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"get_local_price"
],
"properties": {
"get_local_price": {
"type": "object",
"required": [
"pair"
],
"properties": {
"pair": {
"$ref": "#/definitions/Pair"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
Expand Down Expand Up @@ -522,6 +543,48 @@
}
}
},
"get_local_price": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Array_of_Price",
"type": "array",
"items": {
"$ref": "#/definitions/Price"
},
"definitions": {
"Decimal": {
"description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)",
"type": "string"
},
"Price": {
"type": "object",
"required": [
"price",
"time"
],
"properties": {
"price": {
"$ref": "#/definitions/Decimal"
},
"time": {
"$ref": "#/definitions/Timestamp"
}
},
"additionalProperties": false
},
"Timestamp": {
"description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```",
"allOf": [
{
"$ref": "#/definitions/Uint64"
}
]
},
"Uint64": {
"description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```",
"type": "string"
}
}
},
"get_price": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Price",
Expand Down
76 changes: 58 additions & 18 deletions contracts/auction/price_oracle/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ use valence_package::event_indexing::{ValenceEvent, ValenceGenericEvent};

use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use crate::state::{Config, PriceStep, ASTRO_PRICE_PATHS, CONFIG};
use crate::state::{Config, PriceStep, ASTRO_PRICE_PATHS, CONFIG, LOCAL_PRICES};

const CONTRACT_NAME: &str = "crates.io:oracle";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

const TWAP_PRICE_MAX_LEN: usize = 10;

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
Expand All @@ -47,7 +49,7 @@ pub fn instantiate(

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
mut deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
Expand All @@ -58,20 +60,22 @@ pub fn execute(

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

// We get the prices from the auction
let auction_addr = PAIRS
.query(
&deps.querier,
config.auction_manager_addr.clone(),
pair.clone(),
)?
.ok_or(ContractError::PairAuctionNotFound)?;
let twap_prices = TWAP_PRICES.query(&deps.querier, auction_addr)?;
let auction_twap_prices = TWAP_PRICES.query(&deps.querier, auction_addr)?;

let source;

let price = if can_update_price_from_auction(&config, &env, &twap_prices) {
// We get last price either form auction or astroport
let last_price = if can_update_price_from_auction(&config, &env, &auction_twap_prices) {
source = "auction";
get_avg_price(twap_prices)
auction_twap_prices[0].clone()
} else {
let steps = ASTRO_PRICE_PATHS
.load(deps.storage, pair.clone())
Expand All @@ -80,12 +84,17 @@ pub fn execute(
get_price_from_astroport(deps.as_ref(), &env, steps)?
};

let local_prices = update_local_price(deps.branch(), pair.clone(), last_price.clone())?;

// Calculate the average price
let avg_price = get_avg_price(local_prices);

// Save price
PRICES.save(deps.storage, pair.clone(), &price)?;
PRICES.save(deps.storage, pair.clone(), &avg_price)?;

let event = ValenceEvent::OracleUpdatePrice {
pair: pair.clone(),
price: price.price,
price: avg_price.price,
source: source.to_string(),
};

Expand Down Expand Up @@ -120,19 +129,21 @@ pub fn execute(
Err(_) => Ok(()),
}?;

let price = Price {
price,
time: env.block.time,
};
let local_prices = update_local_price(deps.branch(), pair.clone(), price.clone())?;

// Calculate the average price
let avg_price = get_avg_price(local_prices);

// Save price
PRICES.save(
deps.storage,
pair.clone(),
&Price {
price,
time: env.block.time,
},
)?;
PRICES.save(deps.storage, pair.clone(), &avg_price)?;

let event = ValenceEvent::OracleUpdatePrice {
pair,
price,
price: price.price,
source: "manual".to_string(),
};

Expand Down Expand Up @@ -248,6 +259,30 @@ fn can_update_price_from_auction(
true
}

fn update_local_price(
deps: DepsMut,
pair: Pair,
price: Price,
) -> Result<VecDeque<Price>, cosmwasm_std::StdError> {
// Update the oracle local prices and add last price
let mut local_prices = match LOCAL_PRICES.load(deps.storage, pair.clone()) {
Ok(prices) => prices,
Err(_) => VecDeque::new(),
};

// if we have the max amount of prices already, remove the last one first
if local_prices.len() >= TWAP_PRICE_MAX_LEN {
local_prices.pop_back();
}

// Push the last price into the vector
local_prices.push_front(price.clone());

// Save the new list of prices
LOCAL_PRICES.save(deps.storage, pair.clone(), &local_prices)?;
Ok(local_prices)
}

fn get_avg_price(vec: VecDeque<Price>) -> Price {
let (total_count, prices_sum) = vec.iter().fold(
(Decimal::zero(), Decimal::zero()),
Expand Down Expand Up @@ -288,8 +323,8 @@ fn get_price_from_astroport(
.checked_add(res.spread_amount)?,
0,
)?;
deps.api.debug(format!("res: {:?}", res).as_str());
deps.api.debug(format!("Price step: {:?}", price).as_str());
// deps.api.debug(format!("res: {:?}", res).as_str());
// deps.api.debug(format!("Price step: {:?}", price).as_str());

Ok(price)
},
Expand All @@ -314,6 +349,11 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<Binary, ContractErr

Ok(to_json_binary(&price)?)
}
QueryMsg::GetLocalPrice { pair } => {
let price: Vec<Price> = LOCAL_PRICES.load(deps.storage, pair)?.into();

Ok(to_json_binary(&price)?)
}
QueryMsg::GetAllPrices { from, limit } => {
let from = from.map(Bound::<Pair>::exclusive);
let prices = PRICES
Expand Down
2 changes: 2 additions & 0 deletions contracts/auction/price_oracle/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use auction_package::{Pair, Price};

Check warning on line 1 in contracts/auction/price_oracle/src/msg.rs

View workflow job for this annotation

GitHub Actions / test

unused import: `Price`
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, Decimal};
use cw_utils::Expiration;
Expand Down Expand Up @@ -48,6 +48,8 @@
/// Get the minimum amount users can auction
#[returns(Price)]
GetPrice { pair: Pair },
#[returns(Vec<Price>)]
GetLocalPrice { pair: Pair },
#[returns(Vec<(Pair, Price)>)]
GetAllPrices {
from: Option<Pair>,
Expand Down
6 changes: 5 additions & 1 deletion contracts/auction/price_oracle/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use auction_package::Pair;
use std::collections::VecDeque;

use auction_package::{Pair, Price};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use cw_storage_plus::{Item, Map};

pub const CONFIG: Item<Config> = Item::new("config");
pub const ASTRO_PRICE_PATHS: Map<Pair, Vec<PriceStep>> = Map::new("astro_price_paths");
/// Local last 10 prices to be calculated for the average
pub const LOCAL_PRICES: Map<Pair, VecDeque<Price>> = Map::new("local_prices");

#[cw_serde]
pub struct Config {
Expand Down
Loading
Loading