Skip to content

Commit 352a40c

Browse files
committed
Merge remote-tracking branch 'origin/master' into rebase-upgrade
2 parents 3c12f47 + 852c7a1 commit 352a40c

File tree

11 files changed

+647
-194
lines changed

11 files changed

+647
-194
lines changed

.github/workflows/nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
run: yarn coverage
3737

3838
- name: spot-contracts report coverage
39-
uses: coverallsapp/[email protected].0
39+
uses: coverallsapp/[email protected].4
4040
with:
4141
github-token: ${{ secrets.GITHUB_TOKEN }}
4242
path-to-lcov: "./coverage/lcov.info"

.openzeppelin/mainnet.json

Lines changed: 205 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,23 +258,23 @@
258258
"label": "uFrags",
259259
"offset": 0,
260260
"slot": "102",
261-
"type": "t_contract(IUFragments)2591",
261+
"type": "t_contract(IUFragments)20",
262262
"contract": "UFragmentsPolicy",
263263
"src": "contracts/UFragmentsPolicy.sol:48"
264264
},
265265
{
266266
"label": "cpiOracle",
267267
"offset": 0,
268268
"slot": "103",
269-
"type": "t_contract(IOracle)2599",
269+
"type": "t_contract(IOracle)28",
270270
"contract": "UFragmentsPolicy",
271271
"src": "contracts/UFragmentsPolicy.sol:51"
272272
},
273273
{
274274
"label": "marketOracle",
275275
"offset": 0,
276276
"slot": "104",
277-
"type": "t_contract(IOracle)2599",
277+
"type": "t_contract(IOracle)28",
278278
"contract": "UFragmentsPolicy",
279279
"src": "contracts/UFragmentsPolicy.sol:55"
280280
},
@@ -389,11 +389,211 @@
389389
"label": "bool",
390390
"numberOfBytes": "1"
391391
},
392-
"t_contract(IOracle)2599": {
392+
"t_contract(IOracle)28": {
393393
"label": "contract IOracle",
394394
"numberOfBytes": "20"
395395
},
396-
"t_contract(IUFragments)2591": {
396+
"t_contract(IUFragments)20": {
397+
"label": "contract IUFragments",
398+
"numberOfBytes": "20"
399+
},
400+
"t_int256": {
401+
"label": "int256",
402+
"numberOfBytes": "32"
403+
},
404+
"t_uint256": {
405+
"label": "uint256",
406+
"numberOfBytes": "32"
407+
}
408+
}
409+
}
410+
},
411+
"c7369a7d61d189dc4ac496f58ed60273c5ce42a3d8df698d7398067ab9e28815": {
412+
"address": "0x671f768157f6C8A33aDA9b864C8DfaF5b13f1e9F",
413+
"txHash": "0x867d84cd156cf4afee08a44ed6c96cbddbd3c75269e50f8c015edda7628c713f",
414+
"layout": {
415+
"solcVersion": "0.8.4",
416+
"storage": [
417+
{
418+
"label": "initialized",
419+
"offset": 0,
420+
"slot": "0",
421+
"type": "t_bool",
422+
"contract": "Initializable",
423+
"src": "contracts/_external/Initializable.sol:19"
424+
},
425+
{
426+
"label": "initializing",
427+
"offset": 1,
428+
"slot": "0",
429+
"type": "t_bool",
430+
"contract": "Initializable",
431+
"src": "contracts/_external/Initializable.sol:24"
432+
},
433+
{
434+
"label": "______gap",
435+
"offset": 0,
436+
"slot": "1",
437+
"type": "t_array(t_uint256)50_storage",
438+
"contract": "Initializable",
439+
"src": "contracts/_external/Initializable.sol:69"
440+
},
441+
{
442+
"label": "_owner",
443+
"offset": 0,
444+
"slot": "51",
445+
"type": "t_address",
446+
"contract": "Ownable",
447+
"src": "contracts/_external/Ownable.sol:11"
448+
},
449+
{
450+
"label": "______gap",
451+
"offset": 0,
452+
"slot": "52",
453+
"type": "t_array(t_uint256)50_storage",
454+
"contract": "Ownable",
455+
"src": "contracts/_external/Ownable.sol:75"
456+
},
457+
{
458+
"label": "uFrags",
459+
"offset": 0,
460+
"slot": "102",
461+
"type": "t_contract(IUFragments)20",
462+
"contract": "UFragmentsPolicy",
463+
"src": "contracts/UFragmentsPolicy.sol:48"
464+
},
465+
{
466+
"label": "cpiOracle",
467+
"offset": 0,
468+
"slot": "103",
469+
"type": "t_contract(IOracle)28",
470+
"contract": "UFragmentsPolicy",
471+
"src": "contracts/UFragmentsPolicy.sol:51"
472+
},
473+
{
474+
"label": "marketOracle",
475+
"offset": 0,
476+
"slot": "104",
477+
"type": "t_contract(IOracle)28",
478+
"contract": "UFragmentsPolicy",
479+
"src": "contracts/UFragmentsPolicy.sol:55"
480+
},
481+
{
482+
"label": "baseCpi_DEPRECATED",
483+
"offset": 0,
484+
"slot": "105",
485+
"type": "t_uint256",
486+
"contract": "UFragmentsPolicy",
487+
"src": "contracts/UFragmentsPolicy.sol:58",
488+
"renamedFrom": "baseCpi"
489+
},
490+
{
491+
"label": "deviationThreshold",
492+
"offset": 0,
493+
"slot": "106",
494+
"type": "t_uint256",
495+
"contract": "UFragmentsPolicy",
496+
"src": "contracts/UFragmentsPolicy.sol:64"
497+
},
498+
{
499+
"label": "rebaseLagDeprecated",
500+
"offset": 0,
501+
"slot": "107",
502+
"type": "t_uint256",
503+
"contract": "UFragmentsPolicy",
504+
"src": "contracts/UFragmentsPolicy.sol:66"
505+
},
506+
{
507+
"label": "minRebaseTimeIntervalSec",
508+
"offset": 0,
509+
"slot": "108",
510+
"type": "t_uint256",
511+
"contract": "UFragmentsPolicy",
512+
"src": "contracts/UFragmentsPolicy.sol:69"
513+
},
514+
{
515+
"label": "lastRebaseTimestampSec",
516+
"offset": 0,
517+
"slot": "109",
518+
"type": "t_uint256",
519+
"contract": "UFragmentsPolicy",
520+
"src": "contracts/UFragmentsPolicy.sol:72"
521+
},
522+
{
523+
"label": "rebaseWindowOffsetSec",
524+
"offset": 0,
525+
"slot": "110",
526+
"type": "t_uint256",
527+
"contract": "UFragmentsPolicy",
528+
"src": "contracts/UFragmentsPolicy.sol:76"
529+
},
530+
{
531+
"label": "rebaseWindowLengthSec",
532+
"offset": 0,
533+
"slot": "111",
534+
"type": "t_uint256",
535+
"contract": "UFragmentsPolicy",
536+
"src": "contracts/UFragmentsPolicy.sol:79"
537+
},
538+
{
539+
"label": "epoch",
540+
"offset": 0,
541+
"slot": "112",
542+
"type": "t_uint256",
543+
"contract": "UFragmentsPolicy",
544+
"src": "contracts/UFragmentsPolicy.sol:82"
545+
},
546+
{
547+
"label": "orchestrator",
548+
"offset": 0,
549+
"slot": "113",
550+
"type": "t_address",
551+
"contract": "UFragmentsPolicy",
552+
"src": "contracts/UFragmentsPolicy.sol:93"
553+
},
554+
{
555+
"label": "rebaseFunctionLowerPercentage",
556+
"offset": 0,
557+
"slot": "114",
558+
"type": "t_int256",
559+
"contract": "UFragmentsPolicy",
560+
"src": "contracts/UFragmentsPolicy.sol:97"
561+
},
562+
{
563+
"label": "rebaseFunctionUpperPercentage",
564+
"offset": 0,
565+
"slot": "115",
566+
"type": "t_int256",
567+
"contract": "UFragmentsPolicy",
568+
"src": "contracts/UFragmentsPolicy.sol:98"
569+
},
570+
{
571+
"label": "rebaseFunctionGrowth",
572+
"offset": 0,
573+
"slot": "116",
574+
"type": "t_int256",
575+
"contract": "UFragmentsPolicy",
576+
"src": "contracts/UFragmentsPolicy.sol:99"
577+
}
578+
],
579+
"types": {
580+
"t_address": {
581+
"label": "address",
582+
"numberOfBytes": "20"
583+
},
584+
"t_array(t_uint256)50_storage": {
585+
"label": "uint256[50]",
586+
"numberOfBytes": "1600"
587+
},
588+
"t_bool": {
589+
"label": "bool",
590+
"numberOfBytes": "1"
591+
},
592+
"t_contract(IOracle)28": {
593+
"label": "contract IOracle",
594+
"numberOfBytes": "20"
595+
},
596+
"t_contract(IUFragments)20": {
397597
"label": "contract IUFragments",
398598
"numberOfBytes": "20"
399599
},

contracts/OracleSimple.sol

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
pragma solidity ^0.8.4;
2+
3+
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
4+
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
5+
// import '@uniswap/lib/contracts/libraries/FixedPoint.sol';
6+
// import '@uniswap/v2-periphery/contracts/libraries/UniswapV2OracleLibrary.sol';
7+
8+
import './_external/UniswapV2OracleLibrary.sol';
9+
10+
// import '../libraries/UniswapV2Library.sol';
11+
// import '../interfaces/IERC20.sol';
12+
import "./_external/IERC20.sol";
13+
import "./_external/SafeMath.sol";
14+
import "hardhat/console.sol";
15+
16+
// fixed window oracle that recomputes the average price for the entire period once every period
17+
// note that the price average is only guaranteed to be over at least 1 period, but may be over a longer period
18+
contract OracleSimple {
19+
using SafeMath for uint256;
20+
21+
IUniswapV2Pair immutable public pair;
22+
23+
// using FixedPoint for *;
24+
uint public period = 22 hours;
25+
26+
uint256 public decimalsFactor;
27+
28+
uint256 public price0CumulativeLast;
29+
uint32 public blockTimestampLast;
30+
31+
uint256 public constant OUTPUT_DECIMALS = 18;
32+
33+
uint256 public price0Average;
34+
35+
constructor(address pool) {
36+
IUniswapV2Pair _pair = IUniswapV2Pair(pool);
37+
pair = _pair;
38+
decimalsFactor = uint256(10)**(OUTPUT_DECIMALS.add(IERC20(_pair.token0()).decimals()).sub(IERC20(_pair.token1()).decimals()));
39+
price0CumulativeLast = _pair.price0CumulativeLast();
40+
blockTimestampLast = 0;
41+
}
42+
43+
function update() external {
44+
(uint256 price0Cumulativeuq112x112, , uint32 blockTimestamp) =
45+
UniswapV2OracleLibrary.currentCumulativePrices(address(pair));
46+
uint256 price0Cumulative = price0Cumulativeuq112x112.mul(decimalsFactor) >> 112;
47+
uint32 timeElapsed = blockTimestamp - blockTimestampLast;
48+
// ensure that at least one full period has passed since the last update
49+
require(timeElapsed >= period, 'OracleSimple: PERIOD_NOT_ELAPSED');
50+
51+
price0Average = (price0Cumulative - price0CumulativeLast).div(timeElapsed);
52+
53+
price0CumulativeLast = price0Cumulative;
54+
blockTimestampLast = blockTimestamp;
55+
}
56+
57+
function consult() external view returns (uint256) {
58+
require(blockTimestampLast > 0, 'OracleSimple: UPDATE_NEVER_CALLED');
59+
(uint256 price0Cumulativeuq112x112, , uint32 blockTimestamp) =
60+
UniswapV2OracleLibrary.currentCumulativePrices(address(pair));
61+
62+
uint256 price0Cumulative = price0Cumulativeuq112x112.mul(decimalsFactor) >> 112;
63+
uint32 timeElapsed = blockTimestamp - blockTimestampLast;
64+
65+
uint256 memPrice0Average = (price0Cumulative - price0CumulativeLast).div(timeElapsed);
66+
return memPrice0Average;
67+
}
68+
}

contracts/UFragmentsPolicy.sol

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,15 @@ contract UFragmentsPolicy is Ownable {
124124

125125
epoch = epoch.add(1);
126126

127-
uint256 targetRate;
128-
bool targetRateValid;
129-
(targetRate, targetRateValid) = cpiOracle.getData();
130-
require(targetRateValid);
131-
132-
uint256 exchangeRate;
133-
bool rateValid;
134-
(exchangeRate, rateValid) = marketOracle.getData();
135-
require(rateValid);
136-
127+
(uint256 targetRate, bool targetRateValid) = getTargetRate();
128+
(uint256 exchangeRate, bool rateValid) = getExchangeRate();
137129
if (exchangeRate > MAX_RATE) {
138130
exchangeRate = MAX_RATE;
139131
}
140132

141-
int256 supplyDelta = computeSupplyDelta(exchangeRate, targetRate);
142-
133+
int256 supplyDelta = (targetRateValid && rateValid)
134+
? computeSupplyDelta(exchangeRate, targetRate)
135+
: int256(0);
143136
if (supplyDelta > 0 && uFrags.totalSupply().add(uint256(supplyDelta)) > MAX_SUPPLY) {
144137
supplyDelta = (MAX_SUPPLY.sub(uFrags.totalSupply())).toInt256Safe();
145138
}
@@ -267,6 +260,20 @@ contract UFragmentsPolicy is Ownable {
267260
uFrags = uFrags_;
268261
}
269262

263+
/**
264+
* @return The current price target and validity from the cpi oracle.
265+
*/
266+
function getTargetRate() public returns (uint256, bool) {
267+
return cpiOracle.getData();
268+
}
269+
270+
/**
271+
* @return The current exchange rate and validity from the market oracle.
272+
*/
273+
function getExchangeRate() public returns (uint256, bool) {
274+
return marketOracle.getData();
275+
}
276+
270277
/**
271278
* @return If the latest block timestamp is within the rebase time window it, returns true.
272279
* Otherwise, returns false.
@@ -333,7 +340,6 @@ contract UFragmentsPolicy is Ownable {
333340
rebaseFunctionUpperPercentage,
334341
rebaseFunctionGrowth
335342
);
336-
337343
return uFrags.totalSupply().toInt256Safe().mul(rebasePercentage).div(ONE);
338344
}
339345

0 commit comments

Comments
 (0)