@@ -5,33 +5,41 @@ const BigNum = require('bignumber.js')
5
5
const { call, etherUnsigned, getContract, getContractDefaults, getTestContract } = require ( '../Utils/MochaTruffle' ) ;
6
6
const { getBorrowRate, getSupplyRate } = require ( '../Utils/Compound' ) ;
7
7
8
+ const blocksPerYear = 2102400 ;
8
9
const secondsPerYear = 60 * 60 * 24 * 365 ;
9
10
10
11
function utilizationRate ( cash , borrows , reserves ) {
11
12
return borrows ? borrows / ( cash + borrows - reserves ) : 0 ;
12
13
}
13
14
14
- function baseRoofRateFn ( dsr , duty , mkrBase , kink , jump , cash , borrows , reserves ) {
15
- const stabilityFee = ( duty + mkrBase - 1 ) * 15 ;
15
+ function baseRoofRateFn ( dsr , duty , mkrBase , jump , kink , cash , borrows , reserves ) {
16
+ const assumedOneMinusReserveFactor = 0.95 ;
17
+ const stabilityFeePerBlock = ( duty + mkrBase - 1 ) * 15 ;
16
18
const dsrPerBlock = ( dsr - 1 ) * 15 ;
17
- const base = dsrPerBlock / 0.9 ;
18
- const slope = ( stabilityFee - base ) / kink ;
19
+ const gapPerBlock = 0.0005 / blocksPerYear ;
20
+ const jumpPerBlock = jump / blocksPerYear ;
21
+
22
+ let baseRatePerBlock = dsrPerBlock / assumedOneMinusReserveFactor , multiplierPerBlock ;
23
+ if ( baseRatePerBlock < stabilityFeePerBlock ) {
24
+ multiplierPerBlock = ( stabilityFeePerBlock - baseRatePerBlock + gapPerBlock ) / kink ;
25
+ } else {
26
+ multiplierPerBlock = gapPerBlock / kink ;
27
+ }
19
28
20
29
const ur = utilizationRate ( cash , borrows , reserves ) ;
21
30
22
31
if ( ur <= kink ) {
23
- return ur * slope + base ;
32
+ return ur * multiplierPerBlock + baseRatePerBlock ;
24
33
} else {
25
34
const excessUtil = ur - kink ;
26
- const jumpMultiplier = jump * slope ;
27
- return ( excessUtil * jumpMultiplier ) + ( kink * slope ) + base ;
35
+ return ( excessUtil * jumpPerBlock ) + ( kink * multiplierPerBlock ) + baseRatePerBlock ;
28
36
}
29
37
}
30
38
31
- function daiSupplyRate ( dsr , duty , mkrBase , kink , jump , cash , borrows , reserves , reserveFactor = 0.1 ) {
39
+ function daiSupplyRate ( dsr , duty , mkrBase , jump , kink , cash , borrows , reserves , reserveFactor = 0.1 ) {
32
40
const dsrPerBlock = ( dsr - 1 ) * 15 ;
33
41
const ur = utilizationRate ( cash , borrows , reserves ) ;
34
- const borrowRate = baseRoofRateFn ( dsr , duty , mkrBase , kink , jump , cash , borrows , reserves ) ;
42
+ const borrowRate = baseRoofRateFn ( dsr , duty , mkrBase , jump , kink , cash , borrows , reserves ) ;
35
43
const underlying = cash + borrows - reserves ;
36
44
const lendingSupplyRate = borrowRate * ( 1 - reserveFactor ) * ur ;
37
45
@@ -66,10 +74,10 @@ contract('DAIInterestRateModel', async function (_accounts) {
66
74
67
75
let model = await contract . deploy ( {
68
76
arguments : [
69
- "0xea190dbdc7adf265260ec4da6e9675fd4f5a78bb" ,
70
- "0xcbb7718c9f39d05aeede1c472ca8bf804b2f1ead" ,
77
+ etherUnsigned ( 0.8e18 ) ,
71
78
etherUnsigned ( 0.9e18 ) ,
72
- etherUnsigned ( 5 )
79
+ "0xea190dbdc7adf265260ec4da6e9675fd4f5a78bb" ,
80
+ "0xcbb7718c9f39d05aeede1c472ca8bf804b2f1ead"
73
81
]
74
82
} )
75
83
. send ( { from : root } ) ;
@@ -129,8 +137,8 @@ contract('DAIInterestRateModel', async function (_accounts) {
129
137
[ 0e27 , 0.1e27 , 0.005e27 , 3e18 , 500 ] ,
130
138
131
139
] . map ( vs => vs . map ( Number ) )
132
- . forEach ( ( [ dsr , duty , base , cash , borrows , reserves = 0 , kink = 0.9e18 , jump = 5 ] ) => {
133
- it ( `calculates correct borrow value for dsr=${ ( dsr / 1e25 ) } %, duty=${ ( duty / 1e25 ) } %, base=${ ( base / 1e25 ) } %, cash=${ cash } , borrows=${ borrows } , reserves=${ reserves } ` , async ( ) => {
140
+ . forEach ( ( [ dsr , duty , base , cash , borrows , reserves = 0 , jump = 0.8e18 , kink = 0.9e18 ] ) => {
141
+ it ( `calculates correct borrow value for dsr=${ ( dsr / 1e25 ) } %, duty=${ ( duty / 1e25 ) } %, base=${ ( base / 1e25 ) } %, jump= ${ jump / 1e18 } , cash=${ cash } , borrows=${ borrows } , reserves=${ reserves } ` , async ( ) => {
134
142
const [ root ] = _accounts ;
135
143
136
144
const onePlusPerSecondDsr = 1e27 + ( dsr / secondsPerYear ) ;
@@ -156,14 +164,14 @@ contract('DAIInterestRateModel', async function (_accounts) {
156
164
157
165
const daiIRM = await DAIInterestRateModel . deploy ( {
158
166
arguments : [
159
- pot . options . address ,
160
- jug . options . address ,
167
+ etherUnsigned ( jump ) ,
161
168
etherUnsigned ( kink ) ,
162
- etherUnsigned ( jump )
169
+ pot . options . address ,
170
+ jug . options . address
163
171
]
164
172
} ) . send ( { from : root } ) ;
165
173
166
- const expected = baseRoofRateFn ( onePlusPerSecondDsr / 1e27 , onePlusPerSecondDuty / 1e27 , perSecondBase / 1e27 , kink / 1e18 , jump , cash , borrows , reserves ) ;
174
+ const expected = baseRoofRateFn ( onePlusPerSecondDsr / 1e27 , onePlusPerSecondDuty / 1e27 , perSecondBase / 1e27 , jump / 1e18 , kink / 1e18 , cash , borrows , reserves ) ;
167
175
assert . like (
168
176
await getBorrowRate ( daiIRM , cash , borrows , reserves ) ,
169
177
( x ) => assert . approximately ( Number ( x ) / 1e18 , expected , 1e-8 )
@@ -221,7 +229,7 @@ contract('DAIInterestRateModel', async function (_accounts) {
221
229
[ 0e27 , 0.1e27 , 0.005e27 , 3e18 , 500 ] ,
222
230
223
231
] . map ( vs => vs . map ( Number ) )
224
- . forEach ( ( [ dsr , duty , base , cash , borrows , reserves = 0 , kink = 0.9e18 , jump = 5 , reserveFactor = 0.1e18 ] ) => {
232
+ . forEach ( ( [ dsr , duty , base , cash , borrows , reserves = 0 , jump = 0.8e18 , kink = 0.9e18 , reserveFactor = 0.1e18 ] ) => {
225
233
it ( `calculates correct supply value for dsr=${ ( dsr / 1e25 ) } %, duty=${ ( duty / 1e25 ) } %, base=${ ( base / 1e25 ) } %, cash=${ cash } , borrows=${ borrows } , reserves=${ reserves } ` , async ( ) => {
226
234
const [ root ] = _accounts ;
227
235
@@ -248,14 +256,14 @@ contract('DAIInterestRateModel', async function (_accounts) {
248
256
249
257
const daiIRM = await DAIInterestRateModel . deploy ( {
250
258
arguments : [
251
- pot . options . address ,
252
- jug . options . address ,
259
+ etherUnsigned ( jump ) ,
253
260
etherUnsigned ( kink ) ,
254
- etherUnsigned ( jump )
261
+ pot . options . address ,
262
+ jug . options . address
255
263
]
256
264
} ) . send ( { from : root } ) ;
257
265
258
- const expected = daiSupplyRate ( onePlusPerSecondDsr / 1e27 , onePlusPerSecondDuty / 1e27 , perSecondBase / 1e27 , kink / 1e18 , jump , cash , borrows , reserves , reserveFactor / 1e18 ) ;
266
+ const expected = daiSupplyRate ( onePlusPerSecondDsr / 1e27 , onePlusPerSecondDuty / 1e27 , perSecondBase / 1e27 , jump / 1e18 , kink / 1e18 , cash , borrows , reserves , reserveFactor / 1e18 ) ;
259
267
assert . like (
260
268
await getSupplyRate ( daiIRM , cash , borrows , reserves , reserveFactor ) ,
261
269
( x ) => assert . approximately ( Number ( x ) / 1e18 , expected , 1e-8 )
0 commit comments