Skip to content

Commit

Permalink
Merge pull request #141 from eq-lab/audit-fixes
Browse files Browse the repository at this point in the history
Slender security audit (Certora)
  • Loading branch information
mn13 authored Jul 29, 2024
2 parents 153327f + 993fea5 commit c23e43e
Show file tree
Hide file tree
Showing 105 changed files with 4,795 additions and 2,336 deletions.
16 changes: 8 additions & 8 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ inherits = "release"
debug-assertions = true

[workspace.dependencies.soroban-sdk]
version = "20.4.0"
version = "20.5.0"

[workspace.dependencies.soroban-token-sdk]
version = "20.4.0"
version = "20.5.0"

[workspace.dependencies.soroban-fixed-point-math]
version = "1.0.0"
version = "1.1.0"
37 changes: 27 additions & 10 deletions contracts/common/src/fixedi128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,6 @@ impl FixedI128 {
.map(FixedI128)
}

pub fn to_precision(self, precision: u32) -> Option<i128> {
let prec_denom = 10i128.checked_pow(precision)?;

self.0
.checked_mul(prec_denom)?
.checked_div(Self::DENOMINATOR)
}

/// Multiplication of two fixed values
pub fn checked_mul(self, value: FixedI128) -> Option<FixedI128> {
self.0
Expand Down Expand Up @@ -82,6 +74,27 @@ impl FixedI128 {
.checked_div(Self::DENOMINATOR)
}

pub fn mul_int_ceil<T: Into<i128>>(self, other: T) -> Option<i128> {
let other = other.into();
if other == 0 {
return Some(0);
}

let mb_res = self.0.checked_mul(other)?.checked_div(Self::DENOMINATOR);

mb_res.map(|res| {
let res_1 = res.abs();

if res_1 == 0 {
1
} else if res_1 % Self::DENOMINATOR == 0 {
res
} else {
res + 1
}
})
}

/// Calculates division of non fixed int value and fixed value, e.g. other / self.
/// Result is int value
pub fn recip_mul_int<T: Into<i128>>(self, other: T) -> Option<i128> {
Expand All @@ -99,9 +112,13 @@ impl FixedI128 {
}
let mb_res = Self::DENOMINATOR.checked_mul(other)?.checked_div(self.0);
mb_res.map(|res| {
if res == 0 {
let res_1 = res.abs();
let other_1 = other.abs();
let self_1 = self.0.abs();

if res_1 == 0 {
1
} else if other >= self.0 && other % self.0 == 0 {
} else if other_1 % self_1 == 0 {
res
} else {
res + 1
Expand Down
3 changes: 3 additions & 0 deletions contracts/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ pub const PERCENTAGE_FACTOR: u32 = 10_000;

///Seconds in year. Equal 365.25 * 24 * 60 * 60
pub const ONE_YEAR: u64 = 31_557_600;

///Seconds in day. Equal 24 * 60 * 60
pub const ONE_DAY: u64 = 86_400;
16 changes: 3 additions & 13 deletions contracts/deployer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![deny(warnings)]
#![no_std]

use pool_interface::types::ir_params::IRParams;
use pool_interface::types::pool_config::PoolConfig;
use soroban_sdk::{
contract, contractimpl, vec, Address, BytesN, Env, IntoVal, String, Symbol, Val,
};
Expand All @@ -20,21 +20,11 @@ impl Deployer {
salt: BytesN<32>,
wasm_hash: BytesN<32>,
admin: Address,
treasury: Address,
flash_loan_fee: u32,
initial_health: u32,
ir_params: IRParams,
pool_config: PoolConfig,
) -> (Address, Val) {
let id = env.deployer().with_current_contract(salt).deploy(wasm_hash);
let init_fn = Symbol::new(&env, "initialize");
let init_args = vec![
&env,
admin.into_val(&env),
treasury.into_val(&env),
flash_loan_fee.into_val(&env),
initial_health.into_val(&env),
ir_params.into_val(&env),
];
let init_args = vec![&env, admin.into_val(&env), pool_config.into_val(&env)];
let res: Val = env.invoke_contract(&id, &init_fn, init_args);
(id, res)
}
Expand Down
59 changes: 35 additions & 24 deletions contracts/deployer/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
extern crate std;

use crate::{Deployer, DeployerClient};
use pool_interface::types::ir_params::IRParams;
use pool_interface::types::pool_config::PoolConfig;
use soroban_sdk::{
testutils::Address as _, token::Client as TokenClient, Address, BytesN, Env, String,
};
Expand All @@ -26,33 +26,38 @@ fn deploy_pool_and_s_token() {
let env = Env::default();
let client = DeployerClient::new(&env, &env.register_contract(None, Deployer));

// Deploy pool
let pool_ir_params = IRParams {
alpha: 143,
initial_rate: 200,
max_rate: 50_000,
scaling_coeff: 9_000,
};
let flash_loan_fee = 5;
let initial_health = 2_500;
let grace_period = 60 * 60 * 24;

// Deploy pool
let pool_config = PoolConfig {
base_asset_address: Address::generate(&env),
base_asset_decimals: 7,
flash_loan_fee: flash_loan_fee,
initial_health: initial_health,
timestamp_window: 20,
grace_period: grace_period,
user_assets_limit: 4,
min_collat_amount: 0,
min_debt_amount: 0,
liquidation_protocol_fee: 0,
ir_alpha: 143,
ir_initial_rate: 200,
ir_max_rate: 50_000,
ir_scaling_coeff: 9_000,
};

let pool_contract_id = {
// Install the WASM code to be deployed from the deployer contract.
let pool_wasm_hash = env.deployer().upload_contract_wasm(pool::WASM);

// Deploy contract using deployer, and include an init function to call.
let salt = BytesN::from_array(&env, &[0; 32]);
let pool_admin = Address::generate(&env);
let treasury = Address::generate(&env);

let (contract_id, init_result) = client.deploy_pool(
&salt,
&pool_wasm_hash,
&pool_admin,
&treasury,
&flash_loan_fee,
&initial_health,
&pool_ir_params,
);

let (contract_id, init_result) =
client.deploy_pool(&salt, &pool_wasm_hash, &pool_admin, &pool_config);
assert!(init_result.is_void());

contract_id
Expand Down Expand Up @@ -111,10 +116,16 @@ fn deploy_pool_and_s_token() {
};

let _debt_token_client = debt_token::Client::new(&env, &debt_token_contract_id);
let ir_params = pool_client.ir_params().unwrap();
let onchain_pool_config = pool_client.pool_configuration();

assert_eq!(pool_ir_params.alpha, ir_params.alpha);
assert_eq!(pool_ir_params.initial_rate, ir_params.initial_rate);
assert_eq!(pool_ir_params.max_rate, ir_params.max_rate);
assert_eq!(pool_ir_params.scaling_coeff, ir_params.scaling_coeff);
assert_eq!(pool_config.ir_alpha, onchain_pool_config.ir_alpha);
assert_eq!(
pool_config.ir_initial_rate,
onchain_pool_config.ir_initial_rate
);
assert_eq!(pool_config.ir_max_rate, onchain_pool_config.ir_max_rate);
assert_eq!(
pool_config.ir_scaling_coeff,
onchain_pool_config.ir_scaling_coeff
);
}
44 changes: 27 additions & 17 deletions contracts/pool/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
use pool_interface::types::collateral_params_input::CollateralParamsInput;
use pool_interface::types::ir_params::IRParams;
use pool_interface::types::{
collateral_params_input::CollateralParamsInput, pool_config::PoolConfig,
};
use soroban_sdk::{symbol_short, Address, Env, Symbol};

pub(crate) fn initialized(e: &Env, admin: &Address, treasury: &Address, params: &IRParams) {
let topics = (Symbol::new(e, "initialize"), admin, treasury);
pub(crate) fn initialized(e: &Env, admin: &Address, pool_config: &PoolConfig) {
let topics = (
Symbol::new(e, "initialize"),
admin,
pool_config.base_asset_address.clone(),
);
e.events().publish(
topics,
(
params.alpha,
params.initial_rate,
params.max_rate,
params.scaling_coeff,
pool_config.ir_alpha,
pool_config.ir_initial_rate,
pool_config.ir_max_rate,
pool_config.ir_scaling_coeff,
pool_config.base_asset_decimals,
pool_config.initial_health,
pool_config.grace_period,
pool_config.timestamp_window,
pool_config.flash_loan_fee,
pool_config.user_assets_limit,
pool_config.min_collat_amount,
pool_config.min_debt_amount,
pool_config.liquidation_protocol_fee,
),
);
}
Expand Down Expand Up @@ -68,14 +82,9 @@ pub(crate) fn borrowing_disabled(e: &Env, asset: &Address) {
e.events().publish(topics, ());
}

pub(crate) fn reserve_activated(e: &Env, asset: &Address) {
let topics = (Symbol::new(e, "reserve_activated"), asset.clone());
e.events().publish(topics, ());
}

pub(crate) fn reserve_deactivated(e: &Env, asset: &Address) {
let topics = (Symbol::new(e, "reserve_deactivated"), asset.clone());
e.events().publish(topics, ());
pub(crate) fn reserve_status_changed(e: &Env, asset: &Address, activated: bool) {
let topics = (asset.clone(),);
e.events().publish(topics, activated);
}

pub(crate) fn liquidation(e: &Env, who: &Address, covered_debt: i128, liquidated_collateral: i128) {
Expand All @@ -91,7 +100,8 @@ pub(crate) fn flash_loan(
asset: &Address,
amount: i128,
premium: i128,
borrow: bool,
) {
let topics = (Symbol::new(e, "flash_loan"), who, receiver, asset);
e.events().publish(topics, (amount, premium));
e.events().publish(topics, (amount, premium, borrow));
}
Loading

0 comments on commit c23e43e

Please sign in to comment.