-
Notifications
You must be signed in to change notification settings - Fork 13
/
Buckets.sol
153 lines (134 loc) · 5.86 KB
/
Buckets.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.14;
import { Bucket, Lender } from '../../interfaces/pool/commons/IPoolState.sol';
import { Maths } from './Maths.sol';
/**
@title Buckets library
@notice Internal library containing common logic for buckets management.
*/
library Buckets {
/**************/
/*** Events ***/
/**************/
// See `IPoolError` for descriptions
error BucketBankruptcyBlock();
/***********************************/
/*** Bucket Management Functions ***/
/***********************************/
/**
* @notice Add collateral to a bucket and updates `LP` for bucket and lender with the amount coresponding to collateral amount added.
* @dev Increment `bucket.collateral` and `bucket.lps` accumulator
* @dev - `addLenderLP`:
* @dev increment `lender.lps` accumulator and `lender.depositTime` state
* @param lender_ Address of the lender.
* @param deposit_ Current bucket deposit (quote tokens). Used to calculate bucket's exchange rate / `LP`.
* @param collateralAmountToAdd_ Additional collateral amount to add to bucket.
* @param bucketPrice_ Bucket price.
* @return addedLP_ Amount of bucket `LP` for the collateral amount added.
*/
function addCollateral(
Bucket storage bucket_,
address lender_,
uint256 deposit_,
uint256 collateralAmountToAdd_,
uint256 bucketPrice_
) internal returns (uint256 addedLP_) {
// cannot deposit in the same block when bucket becomes insolvent
uint256 bankruptcyTime = bucket_.bankruptcyTime;
if (bankruptcyTime == block.timestamp) revert BucketBankruptcyBlock();
// calculate amount of LP to be added for the amount of collateral added to bucket
addedLP_ = collateralToLP(
bucket_.collateral,
bucket_.lps,
deposit_,
collateralAmountToAdd_,
bucketPrice_
);
// update bucket LP balance and collateral
// update bucket collateral
bucket_.collateral += collateralAmountToAdd_;
// update bucket and lender LP balance and deposit timestamp
bucket_.lps += addedLP_;
addLenderLP(bucket_, bankruptcyTime, lender_, addedLP_);
}
/**
* @notice Add amount of `LP` for a given lender in a given bucket.
* @dev Increments lender lps accumulator and updates the deposit time.
* @param bucket_ Bucket to record lender `LP`.
* @param bankruptcyTime_ Time when bucket become insolvent.
* @param lender_ Lender address to add `LP` for in the given bucket.
* @param lpAmount_ Amount of `LP` to be recorded for the given lender.
*/
function addLenderLP(
Bucket storage bucket_,
uint256 bankruptcyTime_,
address lender_,
uint256 lpAmount_
) internal {
if (lpAmount_ != 0) {
Lender storage lender = bucket_.lenders[lender_];
if (bankruptcyTime_ >= lender.depositTime) lender.lps = lpAmount_;
else lender.lps += lpAmount_;
lender.depositTime = block.timestamp;
}
}
/**********************/
/*** View Functions ***/
/**********************/
/**
* @notice Returns the amount of bucket `LP` calculated for the given amount of collateral.
* @param bucketCollateral_ Amount of collateral in bucket.
* @param bucketLP_ Amount of `LP` in bucket.
* @param deposit_ Current bucket deposit (quote tokens). Used to calculate bucket's exchange rate / `LP`.
* @param collateral_ The amount of collateral to calculate bucket LP for.
* @param bucketPrice_ Bucket's price.
* @return lp_ Amount of `LP` calculated for the amount of collateral.
*/
function collateralToLP(
uint256 bucketCollateral_,
uint256 bucketLP_,
uint256 deposit_,
uint256 collateral_,
uint256 bucketPrice_
) internal pure returns (uint256 lp_) {
uint256 rate = getExchangeRate(bucketCollateral_, bucketLP_, deposit_, bucketPrice_);
lp_ = Maths.wdiv(Maths.wmul(collateral_, bucketPrice_), rate);
}
/**
* @notice Returns the amount of `LP` calculated for the given amount of quote tokens.
* @param bucketCollateral_ Amount of collateral in bucket.
* @param bucketLP_ Amount of `LP` in bucket.
* @param deposit_ Current bucket deposit (quote tokens). Used to calculate bucket's exchange rate / `LP`.
* @param quoteTokens_ The amount of quote tokens to calculate `LP` amount for.
* @param bucketPrice_ Bucket's price.
* @return The amount of `LP` coresponding to the given quote tokens in current bucket.
*/
function quoteTokensToLP(
uint256 bucketCollateral_,
uint256 bucketLP_,
uint256 deposit_,
uint256 quoteTokens_,
uint256 bucketPrice_
) internal pure returns (uint256) {
return Maths.wdiv(
quoteTokens_,
getExchangeRate(bucketCollateral_, bucketLP_, deposit_, bucketPrice_)
);
}
/**
* @notice Returns the exchange rate for a given bucket.
* @param bucketCollateral_ Amount of collateral in bucket.
* @param bucketLP_ Amount of `LP` in bucket.
* @param bucketDeposit_ The amount of quote tokens deposited in the given bucket.
* @param bucketPrice_ Bucket's price.
*/
function getExchangeRate(
uint256 bucketCollateral_,
uint256 bucketLP_,
uint256 bucketDeposit_,
uint256 bucketPrice_
) internal pure returns (uint256) {
return bucketLP_ == 0 ? Maths.WAD :
Maths.wdiv(bucketDeposit_ + Maths.wmul(bucketPrice_, bucketCollateral_), bucketLP_);
}
}