Skip to content

Commit e833948

Browse files
chore(multi-collateral): add time tick and apply interest abis
1 parent 3a581fc commit e833948

File tree

1 file changed

+142
-16
lines changed

1 file changed

+142
-16
lines changed

docs/spec.md

Lines changed: 142 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,7 @@ pub struct Position {
358358
pub collateral_balance: Balance,
359359
pub asset_balances: IterableMap<AssetId, AssetBalance>,
360360
pub owner_protection_enabled: bool,
361-
// TODO(Mohammad): need to think about the initial value (if last_updated == 0 )
362-
// Possible solution: in first update `interest_amount` should be zero.
361+
// In first update, when `last_interest_amount_applied_time` is zero, `interest_amount` should be zero.
363362
pub last_interest_amount_applied_time: Timestamp,
364363
}
365364
```
@@ -2205,6 +2204,7 @@ pub struct DepositProcessed {
22052204
#[key]
22062205
pub deposit_request_hash: felt252,
22072206
pub salt: felt252,
2207+
pub interest_amount: i64,
22082208
}
22092209
```
22102210

@@ -2314,6 +2314,7 @@ fn process_deposit(
23142314
position_id: PositionId,
23152315
quantized_amount: u64,
23162316
salt: felt252,
2317+
interest_amount: i64,
23172318
)
23182319

23192320
```
@@ -2349,12 +2350,14 @@ We assume that the position is always healthier for deposit
23492350
2. [Pausable check](#pausable)
23502351
3. [Operator Nonce check](#operator-nonce)
23512352
4. [Request approval check on deposit message](#requests)
2353+
5. Interest amount is in range.
23522354

23532355
**Logic:**
23542356

23552357
1. Run deposit validations.
2356-
2. Add the amount to the collateral balance in the position.
2357-
3. Mark deposit request as `DepositStatus::PROCESSED`.
2358+
2. Add interest amount to the base collateral balance, including updating timestamp.
2359+
3. Add the amount to the collateral balance in the position.
2360+
4. Mark deposit request as `DepositStatus::PROCESSED`.
23582361

23592362
**Errors:**
23602363

@@ -2919,6 +2922,8 @@ struct Storage {
29192922
forced_action_timelock: TimeDelta,
29202923
// Cost for executing forced actions (in quantized units).
29212924
premium_cost: u64,
2925+
// System time from the latest system_time call.
2926+
system_time: Timestamp,
29222927
}
29232928
```
29242929

@@ -2960,6 +2965,8 @@ pub enum Event {
29602965
WithdrawRequest: events::WithdrawRequest,
29612966
ForcedWithdraw: events::ForcedWithdraw,
29622967
ForcedWithdrawRequest: events::ForcedWithdrawRequest,
2968+
InterestApplied: events::InterestApplied,
2969+
TimeTick: events::TimeTick,
29632970
#[flat]
29642971
FulfillmentEvent: Fulfillement::Event,
29652972
#[flat]
@@ -3164,6 +3171,8 @@ pub struct Transfer {
31643171
pub expiration: Timestamp,
31653172
#[key]
31663173
pub transfer_request_hash: felt252,
3174+
pub sender_interest_amount: i64,
3175+
pub receiver_interest_amount: i64,
31673176
}
31683177
```
31693178

@@ -3225,6 +3234,8 @@ pub struct AssetPositionReduced {
32253234
pub base_amount_a: i64,
32263235
pub quote_asset_id: AssetId,
32273236
pub quote_amount_a: i64,
3237+
pub interest_amount_a: i64,
3238+
pub interest_amount_b: i64,
32283239
}
32293240
```
32303241

@@ -3288,6 +3299,26 @@ pub struct LiquidatedFromVault {
32883299
}
32893300
```
32903301

3302+
##### InterestApplied
3303+
3304+
```rust
3305+
#[derive(Debug, Drop, PartialEq, starknet::Event)]
3306+
pub struct InterestApplied {
3307+
#[key]
3308+
pub position_id: PositionId,
3309+
pub interest_amount: i64,
3310+
}
3311+
```
3312+
3313+
##### TimeTick
3314+
3315+
```rust
3316+
#[derive(Debug, Drop, PartialEq, starknet::Event)]
3317+
pub struct TimeTick {
3318+
pub timestamp: Timestamp,
3319+
}
3320+
```
3321+
32913322
### Constructor
32923323

32933324
It only runs once when deploying the contract and is used to initialize the state of the contract.
@@ -3330,6 +3361,7 @@ pub fn constructor(
33303361
5. Initialize positions: create fee position with `fee_position_owner_public_key` and insurance fund position with `insurance_fund_position_owner_public_key`.
33313362
6. Initialize forced action timelock with `forced_action_timelock`.
33323363
7. Initialize premium cost with `premium_cost`.
3364+
8. Initialize last system time to current time.
33333365

33343366
### Public Functions
33353367

@@ -3628,6 +3660,7 @@ fn transfer(
36283660
expiration: Timestamp,
36293661
salt: felt252,
36303662
sender_interest_amount: i64,
3663+
reciever_interest_amount: i64,
36313664
)
36323665
```
36333666

@@ -3649,13 +3682,14 @@ Only the Operator can execute.
36493682
6. [Expiration validation](#expiration)
36503683
7. `recipient != position_id`.
36513684
8. [Request approval check on transfer message](#requests-1)
3652-
9. Check interest amount in range.
3685+
9. Check interest amounts in range.
36533686

36543687
**Logic:**
36553688

36563689
1. Run transfer validations
36573690
2. Subtract the amount from the `position_id` collateral balance.
36583691
3. Add sender_interest_amount to sender's collateral balance, including updating timestamp.
3692+
4. Add reciever_interest amount to the reciever's base collateral balance, including updating timestamp.
36593693
4. Add the amount to the recipient `recipient` collateral balance.
36603694
5. [Fundamental validation](#fundamental) for `position_id` in transfer.
36613695

@@ -3677,6 +3711,89 @@ Only the Operator can execute.
36773711
- REQUEST_ALREADY_PROCESSED
36783712
- POSITION_NOT_HEALTHY_NOR_HEALTHIER
36793713

3714+
#### Apply Interest
3715+
3716+
Applies interest to the positions collateral balances.
3717+
3718+
```rust
3719+
fn apply_interests(
3720+
ref self: ContractState,
3721+
operator_nonce: u64,
3722+
position_ids: Span<PositionId>,
3723+
interest_amounts: Span<i64>,
3724+
)
3725+
```
3726+
3727+
**Access Control:**
3728+
3729+
Only the Operator can execute.
3730+
3731+
**Validations:**
3732+
3733+
1. [Pausable check](#pausable)
3734+
2. [Operator Nonce check](#operator-nonce)
3735+
3. position_ids.len() equals interest_amounts.len(), and both are non-empty.
3736+
4. [Position check](#position) for `position_id`s.
3737+
5. Interest amounts are in range.
3738+
3739+
**Logic:**
3740+
3741+
1. Run validations
3742+
2. Add interest amounts to the base collateral balances, including updating timestamp.
3743+
// TODO(Mohammad): Check if health validation is needed.
3744+
3745+
**Errors:**
3746+
3747+
- PAUSED
3748+
- ONLY\_OPERATOR
3749+
- LEN\_MISMATCH
3750+
- INVALID\_NONCE
3751+
- INVALID\_POSITION
3752+
3753+
**Emits:**
3754+
3755+
[InterestApplied](#interestapplied)
3756+
3757+
#### Time Tick
3758+
3759+
Updates the system time. This function allows the operator to set the current system time, which must be monotonically increasing and not exceed the current block timestamp.
3760+
3761+
```rust
3762+
fn update_system_time(
3763+
ref self: ContractState,
3764+
operator_nonce: u64,
3765+
new_timestamp: Timestamp,
3766+
)
3767+
```
3768+
3769+
**Access Control:**
3770+
3771+
Only the Operator can execute.
3772+
3773+
**Validations:**
3774+
3775+
1. [Pausable check](#pausable)
3776+
2. [Operator Nonce check](#operator-nonce)
3777+
3. `new_timestamp <= now`
3778+
4. `new_timestamp > system_time`
3779+
3780+
**Logic:**
3781+
3782+
1. Run validations
3783+
2. Update `system_time` to `new_timestamp`
3784+
3785+
**Errors:**
3786+
3787+
- PAUSED
3788+
- ONLY\_OPERATOR
3789+
- INVALID\_NONCE
3790+
- INVALID_TIMESTAMP
3791+
- TIMESTAMP_NOT_MONOTONIC
3792+
3793+
**Emits:**
3794+
3795+
[TimeTick](#timetick)
3796+
36803797
#### Trade
36813798

36823799
A trade between 2 positions in the system.
@@ -4107,6 +4224,8 @@ fn reduce_asset_position(
41074224
position_id_b: PositionId,
41084225
base_asset_id: AssetId,
41094226
base_amount_a: i64,
4227+
interest_amount_a: i64,
4228+
interest_amount_b: i64,
41104229
)
41114230
```
41124231

@@ -4125,11 +4244,13 @@ Only the Operator can execute.
41254244
7. `base_asset_id` must be a registered inactive synthetic asset.
41264245
8. `position_id_a.balance` decreases in magnitude after the change: `|base_amount_a|` must not exceed `|position_id_a.balance|`, and both should have the same sign.
41274246
9. `position_id_b.balance` decreases in magnitude after the change: `|base_amount_a|` must not exceed `|position_id_b.balance|`, and both should have opposite sign.
4247+
10. Check interest amounts in range for both positions.
41284248

41294249
**Logic:**
41304250

41314251
1. Run validations
41324252
2. Calculate `quote_amount_a = -1 * price(base_asset_id) * base_amount_a`
4253+
3. Add interest amounts to collateral balances for both positions, including timestamp.
41334254
3. `positions[position_id_a].syntethic_assets[base_asset_id] += base_amount_a`
41344255
4. `positions[position_id_b].syntethic_assets[base_asset_id] -= base_amount_a`
41354256
5. Add `quote_amount_a` to the `position_id_a` collateral.
@@ -4227,8 +4348,9 @@ fn redeem_from_vault(
42274348
vault_signature: Signature,
42284349
actual_shares_user: i64,
42294350
actual_collateral_user: i64,
4230-
interest_amount_investor: i64,
4231-
interest_amount_vault: i64,
4351+
redeeming_interest_amount: i64,
4352+
receiving_interest_amount: i64,
4353+
vault_interest_amount: i64,
42324354
);
42334355
```
42344356

@@ -4258,7 +4380,7 @@ Only the Operator can execute.
42584380
12. Caller is the operator.
42594381
13. Request is new (check user payload hash not exists in the fulfillment map).
42604382
14. `number_of_shares * vault_share_execution_price >= minimum_quantized_amount`
4261-
15. Check interest amount in range for both positions.
4383+
15. Check interest amount in range for all the positions.
42624384

42634385
**Logic:**
42644386

@@ -4269,7 +4391,7 @@ Only the Operator can execute.
42694391
5. call the new redeem function of the vault contract (a version where the price of a vault share is dicateded by the operator) which burns the vault shares and transfers the assets from the vault contract to the perps contract
42704392
6. increase the position_id collateral_id balance by vault_share_execution_price*number_of_shares
42714393
7. reduce the vault_position_id collateral_id balance by vault_share_execution_price*number_of_shares
4272-
8. Add interest amounts to collateral balances for both positions, including timestamp.
4394+
8. Add interest amounts to collateral balances for all the positions, including timestamp.
42734395

42744396
**Emits:**
42754397

@@ -4289,6 +4411,8 @@ fn liquidate_vault_shares(
42894411
liquidated_asset_id: AssetId,
42904412
actual_shares_user: i64,
42914413
actual_collateral_user: i64,
4414+
liquidated_interest_amount: i64,
4415+
vault_interest_amount: i64,
42924416
);
42934417
```
42944418

@@ -4314,17 +4438,19 @@ Only the Operator can execute.
43144438
10. position id is liquidatable.
43154439
11. vault_share_execution_price is non zero.
43164440
12. Caller is the operator.
4441+
13. Check interest amounts in range for both positions.
43174442

43184443
**Logic:**
43194444

43204445
1. Run validations
4321-
2. transfer vault_asset_id: number_of_shares from the perps contract to the vault contract (for burning the vault shares)
4322-
3. reduce the position id vault share balance by number_of_shares
4323-
4. transfer collateral_id: vault_share_execution_price*number_of_shares from the perps contract to the vault contract (for transferring back the shares value)
4324-
5. call the new redeem function of the vault contract (a version where the price of a vault share is dicateded by the operator) which burns the vault shares and transfers the assets from the vault contract to the perps contract
4325-
6. increase the position_id collateral_id balance by vault_share_execution_price*number_of_shares
4326-
7. reduce the vault_position_id collateral_id balance by vault_share_execution_price*number_of_shares
4327-
8. position id is healthier
4446+
2. Add interest amounts for both positions, and update timestamps.
4447+
3. transfer vault_asset_id: number_of_shares from the perps contract to the vault contract (for burning the vault shares)
4448+
4. reduce the position id vault share balance by number_of_shares
4449+
5. transfer collateral_id: vault_share_execution_price*number_of_shares from the perps contract to the vault contract (for transferring back the shares value)
4450+
6. call the new redeem function of the vault contract (a version where the price of a vault share is dicateded by the operator) which burns the vault shares and transfers the assets from the vault contract to the perps contract
4451+
7. increase the position_id collateral_id balance by vault_share_execution_price*number_of_shares
4452+
8. reduce the vault_position_id collateral_id balance by vault_share_execution_price*number_of_shares
4453+
9. position id is healthier
43284454

43294455
**Emits:**
43304456

0 commit comments

Comments
 (0)