Skip to content

Commit

Permalink
TurboSOMM fixes (#232)
Browse files Browse the repository at this point in the history
* version bump to 3.6.1

* TurboSOMM fix updates

* Fix vesting adaptor address
  • Loading branch information
EricBolten authored Nov 10, 2023
1 parent 1f87302 commit 76fd670
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 29 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sommelier_steward"
version = "3.6.0"
version = "3.6.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
20 changes: 18 additions & 2 deletions proto/cellar_v2.proto
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ message CellarV2_2 {
}

/*
* Updates the cellar to use the latest price router in the registry.
* Updates the cellar to use the latest price router in the registry.
*
* Represents function `cachePriceRouter(bool checkTotalAssets, uint16 allowableRange)`
*/
Expand Down Expand Up @@ -457,6 +457,8 @@ message CellarV2_5 {
SetSharePriceOracle set_share_price_oracle = 18;
// Represents function `cachePriceRouter(bool checkTotalAssets, uint16 allowableRange, address expectedPriceRouter)`
CachePriceRouter cache_price_router = 19;
// Represents function `forcePositionOut(uint32 index, uint32 positionId, bool inDebtArray)`
ForcePositionOut force_position_out = 20;
}
}

Expand Down Expand Up @@ -649,7 +651,7 @@ message CellarV2_5 {
}

/*
* Updates the cellar to use the latest price router in the registry.
* Updates the cellar to use the latest price router in the registry.
*
* Represents function `cachePriceRouter(bool checkTotalAssets, uint16 allowableRange, address expectedPriceRouter)`
*/
Expand All @@ -661,6 +663,20 @@ message CellarV2_5 {
// The expected price router address
string expected_price_router = 3;
}

/*
* Forceably remove a position from the cellar without checking its balance is zero.
*
* Represents function `forcePositionOut(uint32 index, uint32 positionId, bool inDebtArray)`
*/
message ForcePositionOut {
// Index of the position.
uint32 index = 1;
// Position ID to force out.
uint32 position_id = 2;
// Whether to switch positions in the debt array, or the credit array.
bool in_debt_array = 3;
}
}

// Represents a call to adaptor an. The cellar must be authorized to call the target adaptor.
Expand Down
2 changes: 1 addition & 1 deletion steward/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "steward"
authors = []
version = "3.6.0"
version = "3.6.1"
edition = "2018"

[dependencies]
Expand Down
125 changes: 108 additions & 17 deletions steward/src/cellars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,33 @@ pub(crate) mod cellar_v2_5;

// oracles

pub const ORACLE1: (U256, &str) = (
pub const TURBOSWETH_ORACLE1: (U256, &str) = (
U256([3, 0, 0, 0]),
"72249f0199eacf6230def33a31e80cf76de78f67",
);
pub const ORACLE2: (U256, &str) = (
pub const TURBOSWETH_ORACLE2: (U256, &str) = (
U256([5, 0, 0, 0]),
"c47278b65443ce71cf47e8455bb343f2db11b70e",
);
pub const ORACLE3: (U256, &str) = (
pub const TURBOSWETH_ORACLE3: (U256, &str) = (
U256([5, 0, 0, 0]),
"26cde3f5db92ea91c84c838e664fe42dec1b6747",
);

pub const ALLOWED_PRICE_ORACLES: [(U256, &str); 3] = [ORACLE1, ORACLE2, ORACLE3];
pub const ALLOWED_TURBOSWETH_PRICE_ORACLES: [(U256, &str); 3] =
[TURBOSWETH_ORACLE1, TURBOSWETH_ORACLE2, TURBOSWETH_ORACLE3];

pub const TURBOSOMM_ORACLE1: (U256, &str) = (
U256([8, 0, 0, 0]),
"30510876b377941f23d7322845de0ca734da59e0",
);
pub const TURBOSOMM_ORACLE2: (U256, &str) = (
U256([8, 0, 0, 0]),
"84785287f0c9c282462da7927aaed9773b32d9cb",
);

pub const ALLOWED_TURBOSOMM_PRICE_ORACLES: [(U256, &str); 2] =
[TURBOSOMM_ORACLE1, TURBOSOMM_ORACLE2];

// price routers

Expand All @@ -62,7 +75,8 @@ lazy_static! {

pub const ALLOWED_V2_0_SETUP_ADAPTORS: [(&str, &str); 0] = [];
pub const ALLOWED_V2_2_CATALOGUE_ADAPTORS: [(&str, &str); 0] = [];
pub const ALLOWED_V2_5_CATALOGUE_ADAPTORS: [(&str, &str); 0] = [];
pub const ALLOWED_V2_5_CATALOGUE_ADAPTORS: [(&str, &str); 1] =
[(CELLAR_TURBO_SOMM, ADAPTOR_VESTING_SIMPLE_V1_1_DEPLOYMENT2)];

// due to position size limits in v2.0, positions must be added and removed from the limited list
// and thus approved positions need to be allowed to be re-added, hence this large list
Expand All @@ -89,7 +103,7 @@ pub const ALLOWED_V2_0_POSITIONS: [(&str, u32); 20] = [
(CELLAR_RYUSD, 29),
];
pub const ALLOWED_V2_2_CATALOGUE_POSITIONS: [(&str, u32); 0] = [];
pub const ALLOWED_V2_5_CATALOGUE_POSITIONS: [(&str, u32); 0] = [];
pub const ALLOWED_V2_5_CATALOGUE_POSITIONS: [(&str, u32); 1] = [(CELLAR_TURBO_SOMM, 100000005)];

pub const BLOCKED_ADAPTORS: [&str; 3] = [
ADAPTOR_UNIV3_V1,
Expand Down Expand Up @@ -136,6 +150,7 @@ pub const CELLAR_RYBTC: &str = "0274a704a6d9129f90a62ddc6f6024b33ecdad36";
pub const CELLAR_TURBO_SWETH: &str = "d33dad974b938744dac81fe00ac67cb5aa13958e";
pub const CELLAR_TURBO_GHO: &str = "0c190ded9be5f512bd72827bdad4003e9cc7975c";
pub const CELLAR_TURBO_STETH: &str = "fd6db5011b171b05e1ea3b92f9eacaeeb055e971";
pub const CELLAR_TURBO_SOMM: &str = "5195222f69c5821f8095ec565e71e18ab6a2298f";

// deprecated adaptors

Expand All @@ -157,7 +172,10 @@ pub const ADAPTOR_MORPHO_AAVE_V3_A_TOKEN_COLLATERAL_V1: &str =
pub const ADAPTOR_MORPHO_AAVE_V3_DEBT_TOKEN_V1: &str = "25a61f771af9a38c10ddd93c2bbab39a88926fa9";
pub const ADAPTOR_MORPHO_AAVE_V3_P2P_V1: &str = "4fe068caad05b82bf3f86e1f7d1a7b8bbf516111";
pub const ADAPTOR_UNIV3_V3: &str = "92611574ec9bc13c6137917481dab7bb7b173c9b";
pub const ADAPTOR_VESTING_SIMPLE_V2: &str = "3b98ba00f981342664969e609fb88280704ac479";
pub const ADAPTOR_VESTING_SIMPLE_V1_1_DEPLOYMENT1: &str =
"3b98ba00f981342664969e609fb88280704ac479";
pub const ADAPTOR_VESTING_SIMPLE_V1_1_DEPLOYMENT2: &str =
"8a95bbabb0039480f6dd90fe856c1e0c3d575aa1";

// utils

Expand Down Expand Up @@ -229,13 +247,18 @@ pub fn validate_oracle(
let cellar_id_normalized = normalize_address(cellar_id.to_string());
let oracle_in = normalize_address(oracle_in.to_string());
let registry_id_in = string_to_u256(registry_id_in.to_string())?;
if !cellar_id_normalized.eq(CELLAR_TURBO_SWETH)
|| !ALLOWED_PRICE_ORACLES.contains(&(registry_id_in, oracle_in.as_str()))
if cellar_id_normalized.eq(CELLAR_TURBO_SWETH)
&& ALLOWED_TURBOSWETH_PRICE_ORACLES.contains(&(registry_id_in, oracle_in.as_str()))
{
return Ok(());
}
if cellar_id_normalized.eq(CELLAR_TURBO_SOMM)
&& ALLOWED_TURBOSOMM_PRICE_ORACLES.contains(&(registry_id_in, oracle_in.as_str()))
{
return Err(sp_call_error("unauthorized oracle update".to_string()));
return Ok(());
}

Ok(())
Err(sp_call_error("unauthorized oracle update".to_string()))
}

pub fn validate_cache_price_router(
Expand All @@ -262,6 +285,26 @@ pub fn validate_cache_price_router(
Ok(())
}

pub fn validate_force_position_out(
cellar_id: &str,
index: u32,
position_id: u32,
in_debt_array: bool,
) -> Result<(), Error> {
let cellar_id_normalized = normalize_address(cellar_id.to_string());
if cellar_id_normalized.eq(CELLAR_TURBO_SOMM)
&& index > 0 // we expect it to be present
&& position_id == 100000004
&& !in_debt_array
{
return Ok(());
}

Err(sp_call_error(
"force position out not authorized for cellar".to_string(),
))
}

pub fn check_blocked_adaptor(adaptor_id: &str) -> Result<(), Error> {
let adaptor_id = normalize_address(adaptor_id.to_string());
if BLOCKED_ADAPTORS.contains(&adaptor_id.as_str()) {
Expand Down Expand Up @@ -457,12 +500,60 @@ mod tests {

#[test]
fn test_validate_oracle() {
assert!(validate_oracle(CELLAR_RYBTC, &ORACLE1.0.to_string(), ORACLE1.1).is_err());
assert!(
validate_oracle(CELLAR_TURBO_SWETH, &U256::from(6).to_string(), ORACLE2.1).is_err()
);
assert!(validate_oracle(CELLAR_TURBO_SWETH, &ORACLE1.0.to_string(), ORACLE1.1).is_ok());
assert!(validate_oracle(CELLAR_TURBO_SWETH, &ORACLE2.0.to_string(), ORACLE2.1).is_ok());
assert!(validate_oracle(
CELLAR_RYBTC,
&TURBOSWETH_ORACLE1.0.to_string(),
TURBOSWETH_ORACLE1.1
)
.is_err());
assert!(validate_oracle(
CELLAR_RYBTC,
&TURBOSOMM_ORACLE1.0.to_string(),
TURBOSOMM_ORACLE1.1
)
.is_err());
assert!(validate_oracle(
CELLAR_TURBO_SWETH,
&U256::from(6).to_string(),
TURBOSWETH_ORACLE2.1
)
.is_err());
assert!(validate_oracle(
CELLAR_TURBO_SOMM,
&U256::from(6).to_string(),
TURBOSOMM_ORACLE2.1
)
.is_err());
assert!(validate_oracle(
CELLAR_TURBO_SWETH,
&TURBOSWETH_ORACLE1.0.to_string(),
TURBOSWETH_ORACLE1.1
)
.is_ok());
assert!(validate_oracle(
CELLAR_TURBO_SWETH,
&TURBOSWETH_ORACLE2.0.to_string(),
TURBOSWETH_ORACLE2.1
)
.is_ok());
assert!(validate_oracle(
CELLAR_TURBO_SWETH,
&TURBOSWETH_ORACLE3.0.to_string(),
TURBOSWETH_ORACLE3.1
)
.is_ok());
assert!(validate_oracle(
CELLAR_TURBO_SOMM,
&TURBOSOMM_ORACLE1.0.to_string(),
TURBOSOMM_ORACLE1.1
)
.is_ok());
assert!(validate_oracle(
CELLAR_TURBO_SOMM,
&TURBOSOMM_ORACLE2.0.to_string(),
TURBOSOMM_ORACLE2.1
)
.is_ok());
}

#[test]
Expand Down
23 changes: 22 additions & 1 deletion steward/src/cellars/cellar_v2_5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ use crate::{

use super::{
check_blocked_adaptor, check_blocked_position, log_cellar_call, validate_cache_price_router,
validate_new_adaptor, validate_new_position, validate_oracle, V2_5_PERMISSIONS,
validate_force_position_out, validate_new_adaptor, validate_new_position, validate_oracle,
V2_5_PERMISSIONS,
};

const CELLAR_NAME: &str = "CellarV2.5";
Expand Down Expand Up @@ -294,6 +295,26 @@ pub fn get_encoded_function(call: FunctionCall, cellar_id: String) -> Result<Vec

Ok(CellarV2_5Calls::CachePriceRouter(call).encode())
}
Function::ForcePositionOut(params) => {
validate_force_position_out(
&cellar_id,
params.index,
params.position_id,
params.in_debt_array,
)?;
log_cellar_call(
CELLAR_NAME,
&ForcePositionOutCall::function_name(),
&cellar_id,
);
let call = ForcePositionOutCall {
index: params.index,
position_id: params.position_id,
in_debt_array: params.in_debt_array,
};

Ok(CellarV2_5Calls::ForcePositionOut(call).encode())
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion steward_abi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "steward_abi"
version = "3.6.0"
version = "3.6.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
2 changes: 1 addition & 1 deletion steward_proto_rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "steward_proto"
version = "3.6.0"
version = "3.6.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
Binary file modified steward_proto_rust/src/prost/descriptor.bin
Binary file not shown.
21 changes: 20 additions & 1 deletion steward_proto_rust/src/prost/steward.v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3083,7 +3083,7 @@ pub mod cellar_v2_5 {
pub struct FunctionCall {
#[prost(
oneof = "function_call::Function",
tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19"
tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20"
)]
pub function: ::core::option::Option<function_call::Function>,
}
Expand Down Expand Up @@ -3148,6 +3148,9 @@ pub mod cellar_v2_5 {
/// Represents function `cachePriceRouter(bool checkTotalAssets, uint16 allowableRange, address expectedPriceRouter)`
#[prost(message, tag = "19")]
CachePriceRouter(super::CachePriceRouter),
/// Represents function `forcePositionOut(uint32 index, uint32 positionId, bool inDebtArray)`
#[prost(message, tag = "20")]
ForcePositionOut(super::ForcePositionOut),
}
}
///
Expand Down Expand Up @@ -3359,6 +3362,22 @@ pub mod cellar_v2_5 {
#[prost(string, tag = "3")]
pub expected_price_router: ::prost::alloc::string::String,
}
///
/// Forceably remove a position from the cellar without checking its balance is zero.
///
/// Represents function `forcePositionOut(uint32 index, uint32 positionId, bool inDebtArray)`
#[derive(serde::Deserialize, serde::Serialize, Clone, PartialEq, ::prost::Message)]
pub struct ForcePositionOut {
/// Index of the position.
#[prost(uint32, tag = "1")]
pub index: u32,
/// Position ID to force out.
#[prost(uint32, tag = "2")]
pub position_id: u32,
/// Whether to switch positions in the debt array, or the credit array.
#[prost(bool, tag = "3")]
pub in_debt_array: bool,
}
#[derive(serde::Deserialize, serde::Serialize, Clone, PartialEq, ::prost::Oneof)]
pub enum CallType {
/// Represents a single function call
Expand Down

0 comments on commit 76fd670

Please sign in to comment.