Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Akinbola247/satoru
Browse files Browse the repository at this point in the history
  • Loading branch information
Akinbola247 committed Oct 26, 2023
2 parents 9546f56 + 3f22d46 commit c315e80
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

- name: Install Semgrep
run: |
pip install semgrep
pip install semgrep==1.45.0
- name: Run Semgrep
run: semgrep --config https://github.com/avnu-labs/semgrep-cairo-rules/releases/download/v0.0.1/cairo-rules.yaml ./src > semgrep-output.txt
- name: Save Semgrep Output as an Artifact
Expand Down
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ snforge

## 🚀 Deploy

To deploy contracts of the saturo, you first need to setup a smart wallet :
To deploy the contracts of Satoru, you first need to setup a smart wallet :

- Create a signer by following this tutorial : [Signers](https://book.starkli.rs/signers)

Expand All @@ -63,6 +63,21 @@ cd scripts
./deploy_contract.sh
```

## Deployed Contracts

- RoleStore: 0x07eacab18c343f30edfa9336b8eacce9bc56303d43c92609a88e8da25177f5b3
- DataStore: 0x0549539da18f4d574211365b6abd678ef940444b579900efedcb935210c41481
- OrderVault: 0x01f1252d6d02feb14cfa88beff415e1524d1cebb31870056567aae257104b6fd
- Router: 0x00dd0912017ee7c8151555394380acd1012a814916d384b12ca64afa0eae2bc5
- EventEmitter: 0x0284ae712869c0af4f538e9297e6965d3c9ba9110830944047de8d35da7ea447
- MarketToken: 0x044391e9498f440cc41ace136ea317f6bfa2080311085d1846529e421974a1d3
- MarketFactory: 0x05766918626a91ca83f52003eb03bbf1f13174aa22e340c8057d8d5d6affbfcf
- WithdrawalVault: 0x050c83c2bc74cc50676fdd5598b40f9d0d6d5ccf6ea3478a7999e29473da03f1
- SwapHandler: 0x039aa67b479f4870878ec6d3002f9fa9b8e98d4d3d10c1f32b5d394a456aab28
- ReferralStorage: 0x0189463034c24b2cb091dcb515287bea13a4767534f09e52692a4cdc30254001
- DepositVault: 0x07d435e7ab3a5cd4b872e5725b02898833cb9a7c62e2d9a6a9db324d61e2925e


## 📚 Resources

Here are some resources to help you get started:
Expand Down
141 changes: 68 additions & 73 deletions src/deposit/execute_deposit_utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use satoru::pricing::swap_pricing_utils::{
use satoru::swap::swap_utils;
use satoru::swap::error::SwapError;
use satoru::utils::{
calc::{to_unsigned, to_signed}, i128::i128, precision, span32::Span32,
calc::{to_unsigned, to_signed}, i128::{i128, i128_new, i128_neg}, precision, span32::Span32,
starknet_utils::{sn_gasleft, sn_gasprice}
};

Expand Down Expand Up @@ -86,7 +86,7 @@ struct _ExecuteDepositParams {
/// `amount` Amount of token_in.
amount: u128,
/// `price_impact_usd` Price impact in USD.
price_impact_usd: u128
price_impact_usd: i128
}

#[derive(Drop, Default)]
Expand All @@ -102,7 +102,6 @@ struct ExecuteDepositCache {
/// Executes a deposit.
/// # Arguments
/// * `params` - ExecuteDepositParams.
#[inline(always)]
fn execute_deposit(params: ExecuteDepositParams) {
// 63/64 gas is forwarded to external calls, reduce the startingGas to account for this
let starting_gas = params.starting_gas - sn_gasleft(array![]) / 63;
Expand Down Expand Up @@ -180,12 +179,12 @@ fn execute_deposit(params: ExecuteDepositParams) {
price_for_token_a: prices.long_token_price.mid_price(),
price_for_token_b: prices.short_token_price.mid_price(),
usd_delta_for_token_a: to_signed(cache.long_token_usd, true),
usd_delta_for_token_b: to_signed(cache.short_token_usd, false),
usd_delta_for_token_b: to_signed(cache.short_token_usd, true),
}
);

if cache.long_token_amount > 0 {
let _params = _ExecuteDepositParams {
let mut _params = _ExecuteDepositParams {
market: market,
account: deposit.account,
receiver: deposit.receiver,
Expand All @@ -195,16 +194,16 @@ fn execute_deposit(params: ExecuteDepositParams) {
token_in_price: prices.long_token_price,
token_out_price: prices.short_token_price,
amount: cache.long_token_amount,
price_impact_usd: precision::mul_div(
to_unsigned(cache.price_impact_usd),
price_impact_usd: precision::mul_div_ival(
cache.price_impact_usd,
cache.long_token_usd,
cache.long_token_usd + cache.short_token_usd
)
};

cache.received_market_tokens += execute_deposit_helper(@params, @_params);
cache.received_market_tokens += execute_deposit_helper(@params, ref _params);
} else if cache.short_token_amount > 0 {
let _params = _ExecuteDepositParams {
let mut _params = _ExecuteDepositParams {
market: market,
account: deposit.account,
receiver: deposit.receiver,
Expand All @@ -214,23 +213,21 @@ fn execute_deposit(params: ExecuteDepositParams) {
token_in_price: prices.short_token_price,
token_out_price: prices.long_token_price,
amount: cache.short_token_amount,
price_impact_usd: precision::mul_div(
to_unsigned(cache.price_impact_usd),
price_impact_usd: precision::mul_div_ival(
cache.price_impact_usd,
cache.short_token_usd,
cache.long_token_usd + cache.short_token_usd
)
};

cache.received_market_tokens += execute_deposit_helper(@params, @_params);
cache.received_market_tokens += execute_deposit_helper(@params, ref _params);
}

if cache.received_market_tokens < deposit.min_market_tokens {
DepositError::MIN_MARKET_TOKENS(cache.received_market_tokens, deposit.min_market_tokens);
}

market_utils::validate_market_token_balance_with_address(
params.data_store, market.market_token
);
market_utils::validate_market_token_balance_check(params.data_store, market);

(params.event_emitter)
.emit_deposit_executed(
Expand Down Expand Up @@ -261,58 +258,60 @@ fn execute_deposit(params: ExecuteDepositParams) {
/// * `params` - @ExecuteDepositParams.
/// * `_params` - @_ExecuteDepositParams.
#[inline(always)]
fn execute_deposit_helper(params: @ExecuteDepositParams, _params: @_ExecuteDepositParams) -> u128 {
fn execute_deposit_helper(
params: @ExecuteDepositParams, ref _params: _ExecuteDepositParams
) -> u128 {
// for markets where longToken == shortToken, the price impact factor should be set to zero
// in which case, the priceImpactUsd would always equal zero
let fees = get_swap_fees(
*params.data_store,
*_params.market.market_token,
*_params.amount,
*_params.price_impact_usd > 0,
*_params.ui_fee_receiver,
_params.market.market_token,
_params.amount,
_params.price_impact_usd > Zeroable::zero(),
_params.ui_fee_receiver,
);

fee_utils::increment_claimable_fee_amount(
*params.data_store,
*params.event_emitter,
*_params.market.market_token,
*_params.token_in,
_params.market.market_token,
_params.token_in,
fees.fee_receiver_amount,
deposit_fee_type(),
);

fee_utils::increment_claimable_ui_fee_amount(
*params.data_store,
*params.event_emitter,
*_params.ui_fee_receiver,
*_params.market.market_token,
*_params.token_in,
_params.ui_fee_receiver,
_params.market.market_token,
_params.token_in,
fees.ui_fee_amount,
ui_deposit_fee_type(),
);

(*params.event_emitter)
.emit_swap_fees_collected(
*_params.market.market_token,
*_params.token_in,
*_params.token_in_price.min,
_params.market.market_token,
_params.token_in,
_params.token_in_price.min,
'deposit',
fees.clone(),
);

let market_pool_value_info = market_utils::get_pool_value_info(
*params.data_store,
*_params.market,
(*params.oracle).get_primary_price(*_params.market.index_token),
if *_params.token_in == *_params.market.long_token {
*_params.token_in_price
_params.market,
(*params.oracle).get_primary_price(_params.market.index_token),
if _params.token_in == _params.market.long_token {
_params.token_in_price
} else {
*_params.token_out_price
_params.token_out_price
},
if *_params.token_in == *_params.market.short_token {
*_params.token_in_price
if _params.token_in == _params.market.short_token {
_params.token_in_price
} else {
*_params.token_out_price
_params.token_out_price
},
max_pnl_factor_for_deposits(),
true,
Expand All @@ -324,9 +323,9 @@ fn execute_deposit_helper(params: @ExecuteDepositParams, _params: @_ExecuteDepos
);

let mut mint_amount = 0;
let pool_value = market_pool_value_info.pool_value;
let pool_value = to_unsigned(market_pool_value_info.pool_value);
let market_tokens_supply = market_utils::get_market_token_supply(
IMarketTokenDispatcher { contract_address: *_params.market.market_token }
IMarketTokenDispatcher { contract_address: _params.market.market_token }
);

assert(
Expand All @@ -336,7 +335,7 @@ fn execute_deposit_helper(params: @ExecuteDepositParams, _params: @_ExecuteDepos

(*params.event_emitter)
.emit_market_pool_value_info(
*_params.market.market_token, market_pool_value_info, market_tokens_supply,
_params.market.market_token, market_pool_value_info, market_tokens_supply,
);

// the pool_value and market_tokens_supply is cached for the mint_amount calculation below
Expand All @@ -360,15 +359,14 @@ fn execute_deposit_helper(params: @ExecuteDepositParams, _params: @_ExecuteDepos
// and again when calculating the mint_amount
//
// to avoid this, set the price_impact_usd to be zero for this case
let mut price_impact_usd = *_params.price_impact_usd;

if price_impact_usd > 0 && market_tokens_supply == 0 {
price_impact_usd = 0;
if _params.price_impact_usd > Zeroable::zero() && market_tokens_supply == Zeroable::zero() {
_params.price_impact_usd = i128_new(0, false);
}

let mut amount_after_fees = fees.amount_after_fees;

if price_impact_usd > 0 {
if _params.price_impact_usd > Zeroable::zero() {
// when there is a positive price impact factor,
// tokens from the swap impact pool are used to mint additional market tokens for the user
// for example, if 50,000 USDC is deposited and there is a positive price impact
Expand All @@ -383,15 +381,14 @@ fn execute_deposit_helper(params: @ExecuteDepositParams, _params: @_ExecuteDepos
// it is possible that the addition of the positive impact amount of tokens into the pool
// could increase the imbalance of the pool, for most cases this should not be a significant
// change compared to the improvement of balance from the actual deposit
let positive_impact_amount = to_unsigned(
market_utils::apply_swap_impact_with_cap(
*params.data_store,
*params.event_emitter,
*_params.market.market_token,
*_params.token_out,
*_params.token_out_price,
to_signed(price_impact_usd, true),
)

let positive_impact_amount = market_utils::apply_swap_impact_with_cap(
*params.data_store,
*params.event_emitter,
_params.market.market_token,
_params.token_out,
_params.token_out_price,
_params.price_impact_usd,
);

// calculate the usd amount using positiveImpactAmount since it may
Expand All @@ -406,22 +403,22 @@ fn execute_deposit_helper(params: @ExecuteDepositParams, _params: @_ExecuteDepos
// to be zero, in that case, the market token price is also treated as 1 USD
mint_amount =
market_utils::usd_to_market_token_amount(
positive_impact_amount * *_params.token_out_price.max,
to_unsigned(pool_value),
to_unsigned(positive_impact_amount) * _params.token_out_price.max,
pool_value,
market_tokens_supply,
);

market_utils::apply_delta_to_pool_amount(
*params.data_store,
*params.event_emitter,
*_params.market,
*_params.token_out,
to_signed(positive_impact_amount, false),
_params.market,
_params.token_out,
positive_impact_amount
);

market_utils::validate_pool_amount(params.data_store, _params.market, *_params.token_out,);
market_utils::validate_pool_amount(params.data_store, @_params.market, _params.token_out,);

if (price_impact_usd < 0) {
if (_params.price_impact_usd < Zeroable::zero()) {
// when there is a negative price impact factor,
// less of the deposit amount is used to mint market tokens
// for example, if 10 ETH is deposited and there is a negative price impact
Expand All @@ -430,35 +427,33 @@ fn execute_deposit_helper(params: @ExecuteDepositParams, _params: @_ExecuteDepos
let negative_impact_amount = market_utils::apply_swap_impact_with_cap(
*params.data_store,
*params.event_emitter,
*_params.market.market_token,
*_params.token_out,
*_params.token_out_price,
to_signed(price_impact_usd, false),
_params.market.market_token,
_params.token_out,
_params.token_out_price,
_params.price_impact_usd,
);

amount_after_fees -= to_unsigned((-negative_impact_amount));
amount_after_fees -= to_unsigned(i128_neg(negative_impact_amount));
}
}

mint_amount +=
market_utils::usd_to_market_token_amount(
amount_after_fees * *_params.token_in_price.min,
to_unsigned(pool_value),
market_tokens_supply,
amount_after_fees * _params.token_in_price.min, pool_value, market_tokens_supply,
);

market_utils::apply_delta_to_pool_amount(
*params.data_store,
*params.event_emitter,
*_params.market,
*_params.token_out,
to_signed(amount_after_fees + fees.fee_amount_for_pool, false),
_params.market,
_params.token_out,
to_signed(amount_after_fees + fees.fee_amount_for_pool, true),
);

market_utils::validate_pool_amount(params.data_store, _params.market, *_params.token_in);
market_utils::validate_pool_amount(params.data_store, @_params.market, _params.token_in);

IMarketTokenDispatcher { contract_address: *_params.market.market_token }
.mint(*_params.receiver, mint_amount);
IMarketTokenDispatcher { contract_address: _params.market.market_token }
.mint(_params.receiver, mint_amount);

mint_amount
}
Expand Down
1 change: 0 additions & 1 deletion src/market/market_token.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ mod MarketToken {
let mut bank: Bank::ContractState = Bank::unsafe_new_contract_state();
IBank::transfer_out(ref bank, token, receiver, amount);
}
// TODO implement Bank functions
}

#[external(v0)]
Expand Down
10 changes: 5 additions & 5 deletions src/position/decrease_position_utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fn decrease_position(mut params: UpdatePositionParams) -> DecreasePositionResult
estimated_remaining_collateral_usd +=
to_signed(
params.order.initial_collateral_delta_amount * cache.collateral_token_price.min,
false
true
);

params.order.initial_collateral_delta_amount = 0;
Expand All @@ -156,7 +156,7 @@ fn decrease_position(mut params: UpdatePositionParams) -> DecreasePositionResult
if ((estimated_remaining_collateral_usd
+ cache
.estimated_remaining_pnl_usd) < to_signed(
params.contracts.data_store.get_u128(keys::min_collateral_usd()), false
params.contracts.data_store.get_u128(keys::min_collateral_usd()), true
)) {
params
.contracts
Expand Down Expand Up @@ -275,13 +275,13 @@ fn decrease_position(mut params: UpdatePositionParams) -> DecreasePositionResult
params.position.market,
params.position.collateral_token,
params.position.is_long,
to_signed(cache.initial_collateral_amount - params.position.collateral_amount, true)
to_signed(cache.initial_collateral_amount - params.position.collateral_amount, false)
);

position_utils::update_open_interest(
params,
to_signed(params.order.size_delta_usd, true),
to_signed(values.size_delta_in_tokens, true)
to_signed(params.order.size_delta_usd, false),
to_signed(values.size_delta_in_tokens, false)
);

// affiliate rewards are still distributed even if the order is a liquidation order
Expand Down
Loading

0 comments on commit c315e80

Please sign in to comment.