Skip to content

Commit 95f6b8f

Browse files
chore(multi-collateral): add time tick and apply interest abis
1 parent fcc684e commit 95f6b8f

File tree

1 file changed

+138
-16
lines changed

1 file changed

+138
-16
lines changed

docs/spec.md

Lines changed: 138 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
```
@@ -2314,6 +2313,7 @@ fn process_deposit(
23142313
position_id: PositionId,
23152314
quantized_amount: u64,
23162315
salt: felt252,
2316+
interest_amount: i64,
23172317
)
23182318

23192319
```
@@ -2349,12 +2349,14 @@ We assume that the position is always healthier for deposit
23492349
2. [Pausable check](#pausable)
23502350
3. [Operator Nonce check](#operator-nonce)
23512351
4. [Request approval check on deposit message](#requests)
2352+
5. Interest amount is in range.
23522353

23532354
**Logic:**
23542355

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

23592361
**Errors:**
23602362

@@ -2919,6 +2921,8 @@ struct Storage {
29192921
forced_action_timelock: TimeDelta,
29202922
// Cost for executing forced actions (in quantized units).
29212923
premium_cost: u64,
2924+
// System time from the latest time_tick call.
2925+
system_time: Timestamp,
29222926
}
29232927
```
29242928

@@ -2960,6 +2964,8 @@ pub enum Event {
29602964
WithdrawRequest: events::WithdrawRequest,
29612965
ForcedWithdraw: events::ForcedWithdraw,
29622966
ForcedWithdrawRequest: events::ForcedWithdrawRequest,
2967+
InterestApplied: events::InterestApplied,
2968+
TimeTick: events::TimeTick,
29632969
#[flat]
29642970
FulfillmentEvent: Fulfillement::Event,
29652971
#[flat]
@@ -3288,6 +3294,26 @@ pub struct LiquidatedFromVault {
32883294
}
32893295
```
32903296

3297+
##### InterestApplied
3298+
3299+
```rust
3300+
#[derive(Debug, Drop, PartialEq, starknet::Event)]
3301+
pub struct InterestApplied {
3302+
#[key]
3303+
pub position_id: PositionId,
3304+
pub interest_amount: i64,
3305+
}
3306+
```
3307+
3308+
##### TimeTick
3309+
3310+
```rust
3311+
#[derive(Debug, Drop, PartialEq, starknet::Event)]
3312+
pub struct TimeTick {
3313+
pub timestamp: Timestamp,
3314+
}
3315+
```
3316+
32913317
### Constructor
32923318

32933319
It only runs once when deploying the contract and is used to initialize the state of the contract.
@@ -3330,6 +3356,7 @@ pub fn constructor(
33303356
5. Initialize positions: create fee position with `fee_position_owner_public_key` and insurance fund position with `insurance_fund_position_owner_public_key`.
33313357
6. Initialize forced action timelock with `forced_action_timelock`.
33323358
7. Initialize premium cost with `premium_cost`.
3359+
8. Initialize last system time to current time.
33333360

33343361
### Public Functions
33353362

@@ -3628,6 +3655,7 @@ fn transfer(
36283655
expiration: Timestamp,
36293656
salt: felt252,
36303657
sender_interest_amount: i64,
3658+
reciever_interest_amount: i64,
36313659
)
36323660
```
36333661

@@ -3649,13 +3677,14 @@ Only the Operator can execute.
36493677
6. [Expiration validation](#expiration)
36503678
7. `recipient != position_id`.
36513679
8. [Request approval check on transfer message](#requests-1)
3652-
9. Check interest amount in range.
3680+
9. Check interest amounts in range.
36533681

36543682
**Logic:**
36553683

36563684
1. Run transfer validations
36573685
2. Subtract the amount from the `position_id` collateral balance.
36583686
3. Add sender_interest_amount to sender's collateral balance, including updating timestamp.
3687+
4. Add reciever_interest amount to the reciever's base collateral balance, including updating timestamp.
36593688
4. Add the amount to the recipient `recipient` collateral balance.
36603689
5. [Fundamental validation](#fundamental) for `position_id` in transfer.
36613690

@@ -3677,6 +3706,89 @@ Only the Operator can execute.
36773706
- REQUEST_ALREADY_PROCESSED
36783707
- POSITION_NOT_HEALTHY_NOR_HEALTHIER
36793708

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

36823794
A trade between 2 positions in the system.
@@ -4107,6 +4219,8 @@ fn reduce_asset_position(
41074219
position_id_b: PositionId,
41084220
base_asset_id: AssetId,
41094221
base_amount_a: i64,
4222+
interest_amount_a: i64,
4223+
interest_amount_b: i64,
41104224
)
41114225
```
41124226

@@ -4125,11 +4239,13 @@ Only the Operator can execute.
41254239
7. `base_asset_id` must be a registered inactive synthetic asset.
41264240
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.
41274241
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.
4242+
10. Check interest amounts in range for both positions.
41284243

41294244
**Logic:**
41304245

41314246
1. Run validations
41324247
2. Calculate `quote_amount_a = -1 * price(base_asset_id) * base_amount_a`
4248+
3. Add interest amounts to collateral balances for both positions, including timestamp.
41334249
3. `positions[position_id_a].syntethic_assets[base_asset_id] += base_amount_a`
41344250
4. `positions[position_id_b].syntethic_assets[base_asset_id] -= base_amount_a`
41354251
5. Add `quote_amount_a` to the `position_id_a` collateral.
@@ -4227,8 +4343,9 @@ fn redeem_from_vault(
42274343
vault_signature: Signature,
42284344
actual_shares_user: i64,
42294345
actual_collateral_user: i64,
4230-
interest_amount_investor: i64,
4231-
interest_amount_vault: i64,
4346+
redeeming_interest_amount: i64,
4347+
receiving_interest_amount: i64,
4348+
vault_interest_amount: i64,
42324349
);
42334350
```
42344351

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

42634380
**Logic:**
42644381

@@ -4269,7 +4386,7 @@ Only the Operator can execute.
42694386
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
42704387
6. increase the position_id collateral_id balance by vault_share_execution_price*number_of_shares
42714388
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.
4389+
8. Add interest amounts to collateral balances for all the positions, including timestamp.
42734390

42744391
**Emits:**
42754392

@@ -4289,6 +4406,9 @@ fn liquidate_vault_shares(
42894406
liquidated_asset_id: AssetId,
42904407
actual_shares_user: i64,
42914408
actual_collateral_user: i64,
4409+
redeeming_interest_amount: i64,
4410+
receiving_interest_amount: i64,
4411+
vault_interest_amount: i64,
42924412
);
42934413
```
42944414

@@ -4314,17 +4434,19 @@ Only the Operator can execute.
43144434
10. position id is liquidatable.
43154435
11. vault_share_execution_price is non zero.
43164436
12. Caller is the operator.
4437+
13. Check interest amounts in range for all the positions.
43174438

43184439
**Logic:**
43194440

43204441
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
4442+
2. Add interest amounts for all the positions, and update timestamps.
4443+
3. transfer vault_asset_id: number_of_shares from the perps contract to the vault contract (for burning the vault shares)
4444+
4. reduce the position id vault share balance by number_of_shares
4445+
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)
4446+
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
4447+
7. increase the position_id collateral_id balance by vault_share_execution_price*number_of_shares
4448+
8. reduce the vault_position_id collateral_id balance by vault_share_execution_price*number_of_shares
4449+
9. position id is healthier
43284450

43294451
**Emits:**
43304452

0 commit comments

Comments
 (0)