diff --git a/.gitignore b/.gitignore index 317b4a12..f6095ed5 100644 --- a/.gitignore +++ b/.gitignore @@ -81,7 +81,6 @@ node_modules #Buidler files cache artifacts -.openzeppelin # env .env diff --git a/.openzeppelin/.gitignore b/.openzeppelin/.gitignore new file mode 100644 index 00000000..3ed34ad9 --- /dev/null +++ b/.openzeppelin/.gitignore @@ -0,0 +1 @@ +unknown-*.json \ No newline at end of file diff --git a/.openzeppelin/mainnet.json b/.openzeppelin/mainnet.json new file mode 100644 index 00000000..bc5fee91 --- /dev/null +++ b/.openzeppelin/mainnet.json @@ -0,0 +1,412 @@ +{ + "manifestVersion": "3.2", + "admin": { + "address": "0x6c8a3A2CC9b9831d550433626b262fB9365b5f63" + }, + "proxies": [ + { + "address": "0x1B228a749077b8e307C5856cE62Ef35d96Dca2ea", + "kind": "transparent" + } + ], + "impls": { + "d8137c437d1dafc6dfc1b99b02500b756f9493029b926adccf16480f7a8e55eb": { + "address": "0xE345465b36CC55275250f30bd32127d3bfe45d53", + "layout": { + "solcVersion": "0.8.4", + "storage": [ + { + "label": "initialized", + "offset": 0, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "contracts/_external/Initializable.sol:19" + }, + { + "label": "initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "contracts/_external/Initializable.sol:24" + }, + { + "label": "______gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "Initializable", + "src": "contracts/_external/Initializable.sol:69" + }, + { + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address", + "contract": "Ownable", + "src": "contracts/_external/Ownable.sol:11" + }, + { + "label": "______gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)50_storage", + "contract": "Ownable", + "src": "contracts/_external/Ownable.sol:75" + }, + { + "label": "uFrags", + "offset": 0, + "slot": "102", + "type": "t_contract(IUFragments)4306", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:40" + }, + { + "label": "cpiOracle", + "offset": 0, + "slot": "103", + "type": "t_contract(IOracle)4314", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:43" + }, + { + "label": "marketOracle", + "offset": 0, + "slot": "104", + "type": "t_contract(IOracle)4314", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:47" + }, + { + "label": "baseCpi", + "offset": 0, + "slot": "105", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:50" + }, + { + "label": "deviationThreshold", + "offset": 0, + "slot": "106", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:56" + }, + { + "label": "rebaseLagDeprecated", + "offset": 0, + "slot": "107", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:58" + }, + { + "label": "minRebaseTimeIntervalSec", + "offset": 0, + "slot": "108", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:61" + }, + { + "label": "lastRebaseTimestampSec", + "offset": 0, + "slot": "109", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:64" + }, + { + "label": "rebaseWindowOffsetSec", + "offset": 0, + "slot": "110", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:68" + }, + { + "label": "rebaseWindowLengthSec", + "offset": 0, + "slot": "111", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:71" + }, + { + "label": "epoch", + "offset": 0, + "slot": "112", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:74" + }, + { + "label": "orchestrator", + "offset": 0, + "slot": "113", + "type": "t_address", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:85" + }, + { + "label": "rebaseFunctionLowerPercentage", + "offset": 0, + "slot": "114", + "type": "t_int256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:89" + }, + { + "label": "rebaseFunctionUpperPercentage", + "offset": 0, + "slot": "115", + "type": "t_int256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:90" + }, + { + "label": "rebaseFunctionGrowth", + "offset": 0, + "slot": "116", + "type": "t_int256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:91" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IOracle)4314": { + "label": "contract IOracle", + "numberOfBytes": "20" + }, + "t_contract(IUFragments)4306": { + "label": "contract IUFragments", + "numberOfBytes": "20" + }, + "t_int256": { + "label": "int256", + "numberOfBytes": "32" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + } + } + } + }, + "48a1e26da957363514647440ab4b33a0cf48bd6fa95acee2a194faceb2076760": { + "address": "0x2C628463de226433820DD479Be27360Deb4592d1", + "txHash": "0x2a444748f3c63ad130a3cd16258c709d0abf0508bc807c2396239299c1fe4f0f", + "layout": { + "solcVersion": "0.8.4", + "storage": [ + { + "label": "initialized", + "offset": 0, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "contracts/_external/Initializable.sol:19" + }, + { + "label": "initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "contracts/_external/Initializable.sol:24" + }, + { + "label": "______gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "Initializable", + "src": "contracts/_external/Initializable.sol:69" + }, + { + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address", + "contract": "Ownable", + "src": "contracts/_external/Ownable.sol:11" + }, + { + "label": "______gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)50_storage", + "contract": "Ownable", + "src": "contracts/_external/Ownable.sol:75" + }, + { + "label": "uFrags", + "offset": 0, + "slot": "102", + "type": "t_contract(IUFragments)2591", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:48" + }, + { + "label": "cpiOracle", + "offset": 0, + "slot": "103", + "type": "t_contract(IOracle)2599", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:51" + }, + { + "label": "marketOracle", + "offset": 0, + "slot": "104", + "type": "t_contract(IOracle)2599", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:55" + }, + { + "label": "baseCpi_DEPRECATED", + "offset": 0, + "slot": "105", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:58", + "renamedFrom": "baseCpi" + }, + { + "label": "deviationThreshold", + "offset": 0, + "slot": "106", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:64" + }, + { + "label": "rebaseLagDeprecated", + "offset": 0, + "slot": "107", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:66" + }, + { + "label": "minRebaseTimeIntervalSec", + "offset": 0, + "slot": "108", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:69" + }, + { + "label": "lastRebaseTimestampSec", + "offset": 0, + "slot": "109", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:72" + }, + { + "label": "rebaseWindowOffsetSec", + "offset": 0, + "slot": "110", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:76" + }, + { + "label": "rebaseWindowLengthSec", + "offset": 0, + "slot": "111", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:79" + }, + { + "label": "epoch", + "offset": 0, + "slot": "112", + "type": "t_uint256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:82" + }, + { + "label": "orchestrator", + "offset": 0, + "slot": "113", + "type": "t_address", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:93" + }, + { + "label": "rebaseFunctionLowerPercentage", + "offset": 0, + "slot": "114", + "type": "t_int256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:97" + }, + { + "label": "rebaseFunctionUpperPercentage", + "offset": 0, + "slot": "115", + "type": "t_int256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:98" + }, + { + "label": "rebaseFunctionGrowth", + "offset": 0, + "slot": "116", + "type": "t_int256", + "contract": "UFragmentsPolicy", + "src": "contracts/UFragmentsPolicy.sol:99" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IOracle)2599": { + "label": "contract IOracle", + "numberOfBytes": "20" + }, + "t_contract(IUFragments)2591": { + "label": "contract IUFragments", + "numberOfBytes": "20" + }, + "t_int256": { + "label": "int256", + "numberOfBytes": "32" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + } + } + } + } + } +} diff --git a/contracts/MedianOracle.sol b/contracts/MedianOracle.sol index 069f36c6..2d514cd0 100644 --- a/contracts/MedianOracle.sol +++ b/contracts/MedianOracle.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.4; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {MathUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; import "./lib/Select.sol"; interface IOracle { @@ -15,6 +16,10 @@ interface IOracle { * providers. */ contract MedianOracle is OwnableUpgradeable, IOracle { + using MathUpgradeable for uint256; + + uint8 public constant DECIMALS = 18; + struct Report { uint256 timestamp; uint256 payload; @@ -47,6 +52,9 @@ contract MedianOracle is OwnableUpgradeable, IOracle { // This is needed so that timestamp of 1 is always considered expired. uint256 private constant MAX_REPORT_EXPIRATION_TIME = 520 weeks; + // The final median value is scaled by multiplying by this factor. + uint256 public scalar; + /** * @notice Contract state initialization. * @@ -56,17 +64,20 @@ contract MedianOracle is OwnableUpgradeable, IOracle { * pass before a report is usable * @param minimumProviders_ The minimum number of providers with valid * reports to consider the aggregate report valid. + * @param scalar_ The scaling factor applied on the result. */ function init( uint256 reportExpirationTimeSec_, uint256 reportDelaySec_, - uint256 minimumProviders_ + uint256 minimumProviders_, + uint256 scalar_ ) public initializer { require(reportExpirationTimeSec_ <= MAX_REPORT_EXPIRATION_TIME); require(minimumProviders_ > 0); reportExpirationTimeSec = reportExpirationTimeSec_; reportDelaySec = reportDelaySec_; minimumProviders = minimumProviders_; + scalar = scalar_; __Ownable_init(); } @@ -99,9 +110,17 @@ contract MedianOracle is OwnableUpgradeable, IOracle { minimumProviders = minimumProviders_; } + /** + * @notice Sets the scaling factor. + * @param scalar_ The scaling factor. + */ + function setScalar(uint256 scalar_) external onlyOwner { + scalar = scalar_; + } + /** * @notice Pushes a report for the calling provider. - * @param payload is expected to be 18 decimal fixed point number. + * @param payload is expected to be a fixed point number with `DECIMALS` decimals. */ function pushReport(uint256 payload) external { address providerAddress = msg.sender; @@ -191,7 +210,9 @@ contract MedianOracle is OwnableUpgradeable, IOracle { return (0, false); } - return (Select.computeMedian(validReports, size), true); + uint256 result = Select.computeMedian(validReports, size); + result = result.mulDiv(scalar, 10**DECIMALS); + return (result, true); } /** diff --git a/contracts/UFragmentsPolicy.sol b/contracts/UFragmentsPolicy.sol index ada79390..88278f21 100644 --- a/contracts/UFragmentsPolicy.sol +++ b/contracts/UFragmentsPolicy.sol @@ -29,6 +29,7 @@ contract UFragmentsPolicy is Ownable { using SafeMathInt for int256; using UInt256Lib for uint256; + /// @notice DEPRECATED. event LogRebase( uint256 indexed epoch, uint256 exchangeRate, @@ -37,17 +38,24 @@ contract UFragmentsPolicy is Ownable { uint256 timestampSec ); + event LogRebaseV2( + uint256 indexed epoch, + uint256 exchangeRate, + uint256 targetRate, + int256 requestedSupplyAdjustment + ); + IUFragments public uFrags; - // Provides the current CPI, as an 18 decimal fixed point number. + // Provides the cpi adjusted price target, as an 18 decimal fixed point number. IOracle public cpiOracle; // Market oracle provides the token/USD exchange rate as an 18 decimal fixed point number. // (eg) An oracle value of 1.5e18 it would mean 1 Ample is trading for $1.50. IOracle public marketOracle; - // CPI value at the time of launch, as an 18 decimal fixed point number. - uint256 private baseCpi; + /// @custom:oz-renamed-from baseCpi + uint256 private baseCpi_DEPRECATED; // If the current exchange rate is within this fractional distance from the target, no supply // update is performed. Fixed point number--same format as the rate. @@ -116,12 +124,10 @@ contract UFragmentsPolicy is Ownable { epoch = epoch.add(1); - uint256 cpi; - bool cpiValid; - (cpi, cpiValid) = cpiOracle.getData(); - require(cpiValid); - - uint256 targetRate = cpi.mul(10**DECIMALS).div(baseCpi); + uint256 targetRate; + bool targetRateValid; + (targetRate, targetRateValid) = cpiOracle.getData(); + require(targetRateValid); uint256 exchangeRate; bool rateValid; @@ -140,7 +146,7 @@ contract UFragmentsPolicy is Ownable { uint256 supplyAfterRebase = uFrags.rebase(epoch, supplyDelta); assert(supplyAfterRebase <= MAX_SUPPLY); - emit LogRebase(epoch, exchangeRate, cpi, supplyDelta, block.timestamp); + emit LogRebaseV2(epoch, exchangeRate, targetRate, supplyDelta); } /** @@ -241,11 +247,7 @@ contract UFragmentsPolicy is Ownable { * It is called at the time of contract creation to invoke parent class initializers and * initialize the contract's state variables. */ - function initialize( - address owner_, - IUFragments uFrags_, - uint256 baseCpi_ - ) public initializer { + function initialize(address owner_, IUFragments uFrags_) public initializer { Ownable.initialize(owner_); // deviationThreshold = 0.05e18 = 5e16 @@ -263,7 +265,6 @@ contract UFragmentsPolicy is Ownable { epoch = 0; uFrags = uFrags_; - baseCpi = baseCpi_; } /** diff --git a/external-artifacts/UFragmentsPolicy_v1.2.1.json b/external-artifacts/UFragmentsPolicy_v1.2.1.json new file mode 100644 index 00000000..9fb2f205 --- /dev/null +++ b/external-artifacts/UFragmentsPolicy_v1.2.1.json @@ -0,0 +1,530 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "UFragmentsPolicy", + "sourceName": "contracts/UFragmentsPolicy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cpi", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "requestedSupplyAdjustment", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestampSec", + "type": "uint256" + } + ], + "name": "LogRebase", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + } + ], + "name": "OwnershipRenounced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "normalizedRate", + "type": "int256" + }, + { + "internalType": "int256", + "name": "lower", + "type": "int256" + }, + { + "internalType": "int256", + "name": "upper", + "type": "int256" + }, + { + "internalType": "int256", + "name": "growth", + "type": "int256" + } + ], + "name": "computeRebasePercentage", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "cpiOracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deviationThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalAmpleforthEpochAndAMPLSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inRebaseWindow", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "contract IUFragments", + "name": "uFrags_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseCpi_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRebaseTimestampSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "marketOracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minRebaseTimeIntervalSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "orchestrator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseFunctionGrowth", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseFunctionLowerPercentage", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseFunctionUpperPercentage", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseLag", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseWindowLengthSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseWindowOffsetSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IOracle", + "name": "cpiOracle_", + "type": "address" + } + ], + "name": "setCpiOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deviationThreshold_", + "type": "uint256" + } + ], + "name": "setDeviationThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IOracle", + "name": "marketOracle_", + "type": "address" + } + ], + "name": "setMarketOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "orchestrator_", + "type": "address" + } + ], + "name": "setOrchestrator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "rebaseFunctionGrowth_", + "type": "int256" + } + ], + "name": "setRebaseFunctionGrowth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "rebaseFunctionLowerPercentage_", + "type": "int256" + } + ], + "name": "setRebaseFunctionLowerPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "rebaseFunctionUpperPercentage_", + "type": "int256" + } + ], + "name": "setRebaseFunctionUpperPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minRebaseTimeIntervalSec_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rebaseWindowOffsetSec_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rebaseWindowLengthSec_", + "type": "uint256" + } + ], + "name": "setRebaseTimingParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "uFrags", + "outputs": [ + { + "internalType": "contract IUFragments", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5061189d806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063b74795d9116100a2578063d94ad83711610071578063d94ad837146103d1578063e9fa88a4146103da578063f2fde38b146103ed578063f4fefa491461040057600080fd5b8063b74795d914610385578063c4d66de814610398578063cd28ef0d146103ab578063d3d55d51146103be57600080fd5b80639db59b2f116100de5780639db59b2f1461034e5780639e30bac514610357578063ab33c5ca1461036a578063af14052c1461037d57600080fd5b80638da5cb5b146103185780638f32d59b14610329578063900cf0cf1461033c5780639466120f1461034557600080fd5b806353a15edc116101875780637052b902116101565780637052b902146102eb578063715018a6146102f45780637486cdea146102fc5780638001066d1461030557600080fd5b806353a15edc1461029d5780635ee01540146102b057806360961528146102b957806363f6d4c8146102e457600080fd5b80631794bb3c116101c35780631794bb3c1461025b5780633a785af11461026e5780633a93069b146102815780633d6a46e51461028a57600080fd5b806302101899146101f5578063105bad4f14610211578063111d04981461022e57806316250fd414610246575b600080fd5b6101fe606c5481565b6040519081526020015b60405180910390f35b610219610413565b60408051928352602083019190915201610208565b6102366104a7565b6040519015158152602001610208565b6102596102543660046114e6565b6104ee565b005b610259610269366004611412565b61052c565b6101fe61027c36600461146a565b61067d565b6101fe606d5481565b6102596102983660046113f6565b6107de565b6102596102ab366004611452565b610817565b6101fe60725481565b6068546102cc906001600160a01b031681565b6040516001600160a01b039091168152602001610208565b60016101fe565b6101fe606e5481565b610259610833565b6101fe60745481565b610259610313366004611452565b610894565b6033546001600160a01b03166102cc565b6033546001600160a01b03163314610236565b6101fe60705481565b6101fe606f5481565b6101fe60735481565b6102596103653660046113f6565b6108be565b6067546102cc906001600160a01b031681565b6102596108f7565b6071546102cc906001600160a01b031681565b6102596103a63660046113f6565b610dbb565b6102596103b93660046113f6565b610e3f565b6066546102cc906001600160a01b031681565b6101fe606a5481565b6102596103e8366004611452565b610e78565b6102596103fb3660046113f6565b610ea2565b61025961040e366004611452565b610ec5565b600080607054606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561046757600080fd5b505afa15801561047b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049f919061149b565b915091509091565b6000606e546104c1606c5442610eef90919063ffffffff16565b101580156104e95750606f54606e546104d991610f0e565b606c546104e7904290610eef565b105b905090565b6033546001600160a01b0316331461050557600080fd5b6000831161051257600080fd5b82821061051e57600080fd5b606c92909255606e55606f55565b600054610100900460ff16806105415750303b155b8061054f575060005460ff16155b6105745760405162461bcd60e51b815260040161056b90611511565b60405180910390fd5b6000805461ffff19811661010117909155610100900460ff1661059684610dbb565b6105a2600260126117c6565b6105ad90600a61163d565b6105b8906005611768565b606a556105c76012600a61163d565b6105d2906003611768565b6074556105e1600260126117c6565b6105ec90600a61163d565b6105f790600a611768565b607355610606600260126117c6565b61061190600a61163d565b61061d906009196116e5565b60725562015180606c55611c20606e556104b0606f556000606d8190556070819055606680546001600160a01b039095166001600160a01b03199095169490941790935560699190915581549015156101000261ff001990911617905550565b60008061069661068f6012600a61163d565b8790610f2a565b905060006106b96106a96012600a61163d565b6106b38685610f68565b90610fb9565b90506106d260646106cc6012600a61163d565b90610f68565b8113156106ed576106ea60646106cc6012600a61163d565b90505b6106ff6063196106cc6012600a61163d565b81121561071b576107186063196106cc6012600a61163d565b90505b60006107328261072d6012600a61163d565b610fe3565b905080610744578693505050506107d6565b60006107508789610f2a565b9050600061076e896106b36107676012600a61163d565b8b90610f68565b905061078a836106b36107836012600a61163d565b8490610f68565b905060006107a48261079e6012600a61163d565b90610f2a565b905060006107cc8b6107c6846106b36107bf6012600a61163d565b8990610f68565b90611149565b9750505050505050505b949350505050565b6033546001600160a01b031633146107f557600080fd5b606780546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b0316331461082e57600080fd5b606a55565b6033546001600160a01b0316331461084a57600080fd5b6033546040516001600160a01b03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2603380546001600160a01b0319169055565b6033546001600160a01b031633146108ab57600080fd5b60008112156108b957600080fd5b607455565b6033546001600160a01b031633146108d557600080fd5b606880546001600160a01b0319166001600160a01b0392909216919091179055565b6071546001600160a01b0316331461090e57600080fd5b6109166104a7565b61091f57600080fd5b42610937606c54606d54610f0e90919063ffffffff16565b1061094157600080fd5b61096c606e5461096661095f606c5442610eef90919063ffffffff16565b4290611186565b90610f0e565b606d5560705461097d906001610f0e565b607055606754604080516303bc5de360e41b8152815160009384936001600160a01b0390911692633bc5de30926004808301939282900301818787803b1580156109c657600080fd5b505af11580156109da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fe91906114b3565b909250905080610a0d57600080fd5b6000610a33606954610a2d6012600a610a26919061163d565b86906111a1565b906111c9565b606854604080516303bc5de360e41b8152815193945060009384936001600160a01b031692633bc5de30926004808201939182900301818787803b158015610a7a57600080fd5b505af1158015610a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab291906114b3565b909250905080610ac157600080fd5b610acd6012600a61163d565b610ada90620f4240611768565b821115610afd57610aed6012600a61163d565b610afa90620f4240611768565b91505b6000610b0983856111e3565b9050600081138015610bcc5750610b226012600a61163d565b610b2f90620f4240611768565b610b40906001600160ff1b036115e6565b610bca82606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9257600080fd5b505afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610966919061149b565b115b15610c9557610c92610c8d606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c2557600080fd5b505afa158015610c39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5d919061149b565b610c696012600a61163d565b610c7690620f4240611768565b610c87906001600160ff1b036115e6565b90611186565b6112e5565b90505b606654607054604051637a43e23f60e01b81526004810191909152602481018390526000916001600160a01b031690637a43e23f90604401602060405180830381600087803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1f919061149b565b9050610d2d6012600a61163d565b610d3a90620f4240611768565b610d4b906001600160ff1b036115e6565b811115610d6857634e487b7160e01b600052600160045260246000fd5b60705460408051868152602081018a90529081018490524260608201527f41d948a7f29cc695f5d4b3ec147f766bffa165ddd317470fbe05c86d0a9c3e049060800160405180910390a250505050505050565b600054610100900460ff1680610dd05750303b155b80610dde575060005460ff16155b610dfa5760405162461bcd60e51b815260040161056b90611511565b60008054603380546001600160a01b0319166001600160a01b03949094169390931790925561ffff1982166101009283900460ff161515909202919091176001179055565b6033546001600160a01b03163314610e5657600080fd5b607180546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b03163314610e8f57600080fd5b6000811315610e9d57600080fd5b607255565b6033546001600160a01b03163314610eb957600080fd5b610ec2816112ff565b50565b6033546001600160a01b03163314610edc57600080fd5b6000811215610eea57600080fd5b607355565b600081610efb57600080fd5b610f0582846117f8565b90505b92915050565b600080610f1b83856115a0565b905083811015610f0557600080fd5b600080610f378385611787565b905060008312158015610f4a5750838113155b80610f5f5750600083128015610f5f57508381135b610f0557600080fd5b600080610f7583856116e5565b9050600160ff1b81141580610f935750600160ff1b84811690841614155b610f9c57600080fd5b821580610f5f575083610faf84836115b8565b14610f0557600080fd5b600081600019141580610fd05750600160ff1b8314155b610fd957600080fd5b610f0582846115b8565b60008080841215610ffd57506001610ffa8461136e565b93505b6040805160a0810182526713a04bbdfdc9be898152671080e992061ab32b6020820152670f2243014e544ebb91810191909152670e7e0178e9d6ed506060820152670e2e820ade835f46608082015260006110588686610fb9565b9050606481131561106857600080fd5b60006110776001831b87610f68565b9050600061108e88611089858a610f68565b610f2a565b9050600061109d886002610fb9565b905060005b600581101561111f57818312611100576110bc8383610f2a565b92506110fd6110ef858884600581106110e557634e487b7160e01b600052603260045260246000fd5b6020020151610f68565b670de0b6b3a7640000610fb9565b93505b61110b826002610fb9565b915080611117816117dd565b9150506110a2565b50851561113c57611139611133898a610f68565b84610fb9565b92505b5090979650505050505050565b600080611156838561155f565b9050600083121580156111695750838112155b80610f5f5750600083128015610f5f5750838112610f0557600080fd5b60008282111561119557600080fd5b60006107d683856117c6565b6000826111b057506000610f08565b60006111bc8385611768565b905082610faf85836115e6565b60008082116111d757600080fd5b60006107d683856115e6565b60006111ef8383611398565b156111fc57506000610f08565b6000611207836112e5565b90506000611227826106b361121e6012600a61163d565b6106cc896112e5565b9050600061123d8260725460735460745461067d565b90506112db61124e6012600a61163d565b6106b3836106cc606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112a357600080fd5b505afa1580156112b7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d919061149b565b9695505050505050565b60006001600160ff1b038211156112fb57600080fd5b5090565b6001600160a01b03811661131257600080fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6000600160ff1b82141561138157600080fd5b6000821261138f5781610f08565b610f088261180c565b6000806113b86113aa6012600a61163d565b606a54610a2d9086906111a1565b90508284101580156113d25750806113d08585611186565b105b806107d6575082841080156107d65750806113ed8486611186565b10949350505050565b600060208284031215611407578081fd5b8135610f0581611852565b600080600060608486031215611426578182fd5b833561143181611852565b9250602084013561144181611852565b929592945050506040919091013590565b600060208284031215611463578081fd5b5035919050565b6000806000806080858703121561147f578081fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156114ac578081fd5b5051919050565b600080604083850312156114c5578182fd5b82519150602083015180151581146114db578182fd5b809150509250929050565b6000806000606084860312156114fa578283fd5b505081359360208301359350604090920135919050565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b600080821280156001600160ff1b038490038513161561158157611581611826565b600160ff1b839003841281161561159a5761159a611826565b50500190565b600082198211156115b3576115b3611826565b500190565b6000826115c7576115c761183c565b600160ff1b8214600019841416156115e1576115e1611826565b500590565b6000826115f5576115f561183c565b500490565b600181815b8085111561163557816000190482111561161b5761161b611826565b8085161561162857918102915b93841c93908002906115ff565b509250929050565b6000610f05838360008261165357506001610f08565b8161166057506000610f08565b816001811461167657600281146116805761169c565b6001915050610f08565b60ff84111561169157611691611826565b50506001821b610f08565b5060208310610133831016604e8410600b84101617156116bf575081810a610f08565b6116c983836115fa565b80600019048211156116dd576116dd611826565b029392505050565b60006001600160ff1b038184138284138082168684048611161561170b5761170b611826565b600160ff1b8487128281168783058912161561172957611729611826565b85871292508782058712848416161561174457611744611826565b8785058712818416161561175a5761175a611826565b505050929093029392505050565b600081600019048311821515161561178257611782611826565b500290565b60008083128015600160ff1b8501841216156117a5576117a5611826565b6001600160ff1b03840183138116156117c0576117c0611826565b50500390565b6000828210156117d8576117d8611826565b500390565b60006000198214156117f1576117f1611826565b5060010190565b6000826118075761180761183c565b500690565b6000600160ff1b82141561182257611822611826565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0381168114610ec257600080fdfea2646970667358221220b357ef0d32b2703a5583db62cbbc00074063843793cd65ea8df244ff9c18763864736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063b74795d9116100a2578063d94ad83711610071578063d94ad837146103d1578063e9fa88a4146103da578063f2fde38b146103ed578063f4fefa491461040057600080fd5b8063b74795d914610385578063c4d66de814610398578063cd28ef0d146103ab578063d3d55d51146103be57600080fd5b80639db59b2f116100de5780639db59b2f1461034e5780639e30bac514610357578063ab33c5ca1461036a578063af14052c1461037d57600080fd5b80638da5cb5b146103185780638f32d59b14610329578063900cf0cf1461033c5780639466120f1461034557600080fd5b806353a15edc116101875780637052b902116101565780637052b902146102eb578063715018a6146102f45780637486cdea146102fc5780638001066d1461030557600080fd5b806353a15edc1461029d5780635ee01540146102b057806360961528146102b957806363f6d4c8146102e457600080fd5b80631794bb3c116101c35780631794bb3c1461025b5780633a785af11461026e5780633a93069b146102815780633d6a46e51461028a57600080fd5b806302101899146101f5578063105bad4f14610211578063111d04981461022e57806316250fd414610246575b600080fd5b6101fe606c5481565b6040519081526020015b60405180910390f35b610219610413565b60408051928352602083019190915201610208565b6102366104a7565b6040519015158152602001610208565b6102596102543660046114e6565b6104ee565b005b610259610269366004611412565b61052c565b6101fe61027c36600461146a565b61067d565b6101fe606d5481565b6102596102983660046113f6565b6107de565b6102596102ab366004611452565b610817565b6101fe60725481565b6068546102cc906001600160a01b031681565b6040516001600160a01b039091168152602001610208565b60016101fe565b6101fe606e5481565b610259610833565b6101fe60745481565b610259610313366004611452565b610894565b6033546001600160a01b03166102cc565b6033546001600160a01b03163314610236565b6101fe60705481565b6101fe606f5481565b6101fe60735481565b6102596103653660046113f6565b6108be565b6067546102cc906001600160a01b031681565b6102596108f7565b6071546102cc906001600160a01b031681565b6102596103a63660046113f6565b610dbb565b6102596103b93660046113f6565b610e3f565b6066546102cc906001600160a01b031681565b6101fe606a5481565b6102596103e8366004611452565b610e78565b6102596103fb3660046113f6565b610ea2565b61025961040e366004611452565b610ec5565b600080607054606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561046757600080fd5b505afa15801561047b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049f919061149b565b915091509091565b6000606e546104c1606c5442610eef90919063ffffffff16565b101580156104e95750606f54606e546104d991610f0e565b606c546104e7904290610eef565b105b905090565b6033546001600160a01b0316331461050557600080fd5b6000831161051257600080fd5b82821061051e57600080fd5b606c92909255606e55606f55565b600054610100900460ff16806105415750303b155b8061054f575060005460ff16155b6105745760405162461bcd60e51b815260040161056b90611511565b60405180910390fd5b6000805461ffff19811661010117909155610100900460ff1661059684610dbb565b6105a2600260126117c6565b6105ad90600a61163d565b6105b8906005611768565b606a556105c76012600a61163d565b6105d2906003611768565b6074556105e1600260126117c6565b6105ec90600a61163d565b6105f790600a611768565b607355610606600260126117c6565b61061190600a61163d565b61061d906009196116e5565b60725562015180606c55611c20606e556104b0606f556000606d8190556070819055606680546001600160a01b039095166001600160a01b03199095169490941790935560699190915581549015156101000261ff001990911617905550565b60008061069661068f6012600a61163d565b8790610f2a565b905060006106b96106a96012600a61163d565b6106b38685610f68565b90610fb9565b90506106d260646106cc6012600a61163d565b90610f68565b8113156106ed576106ea60646106cc6012600a61163d565b90505b6106ff6063196106cc6012600a61163d565b81121561071b576107186063196106cc6012600a61163d565b90505b60006107328261072d6012600a61163d565b610fe3565b905080610744578693505050506107d6565b60006107508789610f2a565b9050600061076e896106b36107676012600a61163d565b8b90610f68565b905061078a836106b36107836012600a61163d565b8490610f68565b905060006107a48261079e6012600a61163d565b90610f2a565b905060006107cc8b6107c6846106b36107bf6012600a61163d565b8990610f68565b90611149565b9750505050505050505b949350505050565b6033546001600160a01b031633146107f557600080fd5b606780546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b0316331461082e57600080fd5b606a55565b6033546001600160a01b0316331461084a57600080fd5b6033546040516001600160a01b03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2603380546001600160a01b0319169055565b6033546001600160a01b031633146108ab57600080fd5b60008112156108b957600080fd5b607455565b6033546001600160a01b031633146108d557600080fd5b606880546001600160a01b0319166001600160a01b0392909216919091179055565b6071546001600160a01b0316331461090e57600080fd5b6109166104a7565b61091f57600080fd5b42610937606c54606d54610f0e90919063ffffffff16565b1061094157600080fd5b61096c606e5461096661095f606c5442610eef90919063ffffffff16565b4290611186565b90610f0e565b606d5560705461097d906001610f0e565b607055606754604080516303bc5de360e41b8152815160009384936001600160a01b0390911692633bc5de30926004808301939282900301818787803b1580156109c657600080fd5b505af11580156109da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fe91906114b3565b909250905080610a0d57600080fd5b6000610a33606954610a2d6012600a610a26919061163d565b86906111a1565b906111c9565b606854604080516303bc5de360e41b8152815193945060009384936001600160a01b031692633bc5de30926004808201939182900301818787803b158015610a7a57600080fd5b505af1158015610a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab291906114b3565b909250905080610ac157600080fd5b610acd6012600a61163d565b610ada90620f4240611768565b821115610afd57610aed6012600a61163d565b610afa90620f4240611768565b91505b6000610b0983856111e3565b9050600081138015610bcc5750610b226012600a61163d565b610b2f90620f4240611768565b610b40906001600160ff1b036115e6565b610bca82606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9257600080fd5b505afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610966919061149b565b115b15610c9557610c92610c8d606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c2557600080fd5b505afa158015610c39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5d919061149b565b610c696012600a61163d565b610c7690620f4240611768565b610c87906001600160ff1b036115e6565b90611186565b6112e5565b90505b606654607054604051637a43e23f60e01b81526004810191909152602481018390526000916001600160a01b031690637a43e23f90604401602060405180830381600087803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1f919061149b565b9050610d2d6012600a61163d565b610d3a90620f4240611768565b610d4b906001600160ff1b036115e6565b811115610d6857634e487b7160e01b600052600160045260246000fd5b60705460408051868152602081018a90529081018490524260608201527f41d948a7f29cc695f5d4b3ec147f766bffa165ddd317470fbe05c86d0a9c3e049060800160405180910390a250505050505050565b600054610100900460ff1680610dd05750303b155b80610dde575060005460ff16155b610dfa5760405162461bcd60e51b815260040161056b90611511565b60008054603380546001600160a01b0319166001600160a01b03949094169390931790925561ffff1982166101009283900460ff161515909202919091176001179055565b6033546001600160a01b03163314610e5657600080fd5b607180546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b03163314610e8f57600080fd5b6000811315610e9d57600080fd5b607255565b6033546001600160a01b03163314610eb957600080fd5b610ec2816112ff565b50565b6033546001600160a01b03163314610edc57600080fd5b6000811215610eea57600080fd5b607355565b600081610efb57600080fd5b610f0582846117f8565b90505b92915050565b600080610f1b83856115a0565b905083811015610f0557600080fd5b600080610f378385611787565b905060008312158015610f4a5750838113155b80610f5f5750600083128015610f5f57508381135b610f0557600080fd5b600080610f7583856116e5565b9050600160ff1b81141580610f935750600160ff1b84811690841614155b610f9c57600080fd5b821580610f5f575083610faf84836115b8565b14610f0557600080fd5b600081600019141580610fd05750600160ff1b8314155b610fd957600080fd5b610f0582846115b8565b60008080841215610ffd57506001610ffa8461136e565b93505b6040805160a0810182526713a04bbdfdc9be898152671080e992061ab32b6020820152670f2243014e544ebb91810191909152670e7e0178e9d6ed506060820152670e2e820ade835f46608082015260006110588686610fb9565b9050606481131561106857600080fd5b60006110776001831b87610f68565b9050600061108e88611089858a610f68565b610f2a565b9050600061109d886002610fb9565b905060005b600581101561111f57818312611100576110bc8383610f2a565b92506110fd6110ef858884600581106110e557634e487b7160e01b600052603260045260246000fd5b6020020151610f68565b670de0b6b3a7640000610fb9565b93505b61110b826002610fb9565b915080611117816117dd565b9150506110a2565b50851561113c57611139611133898a610f68565b84610fb9565b92505b5090979650505050505050565b600080611156838561155f565b9050600083121580156111695750838112155b80610f5f5750600083128015610f5f5750838112610f0557600080fd5b60008282111561119557600080fd5b60006107d683856117c6565b6000826111b057506000610f08565b60006111bc8385611768565b905082610faf85836115e6565b60008082116111d757600080fd5b60006107d683856115e6565b60006111ef8383611398565b156111fc57506000610f08565b6000611207836112e5565b90506000611227826106b361121e6012600a61163d565b6106cc896112e5565b9050600061123d8260725460735460745461067d565b90506112db61124e6012600a61163d565b6106b3836106cc606660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112a357600080fd5b505afa1580156112b7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d919061149b565b9695505050505050565b60006001600160ff1b038211156112fb57600080fd5b5090565b6001600160a01b03811661131257600080fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6000600160ff1b82141561138157600080fd5b6000821261138f5781610f08565b610f088261180c565b6000806113b86113aa6012600a61163d565b606a54610a2d9086906111a1565b90508284101580156113d25750806113d08585611186565b105b806107d6575082841080156107d65750806113ed8486611186565b10949350505050565b600060208284031215611407578081fd5b8135610f0581611852565b600080600060608486031215611426578182fd5b833561143181611852565b9250602084013561144181611852565b929592945050506040919091013590565b600060208284031215611463578081fd5b5035919050565b6000806000806080858703121561147f578081fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156114ac578081fd5b5051919050565b600080604083850312156114c5578182fd5b82519150602083015180151581146114db578182fd5b809150509250929050565b6000806000606084860312156114fa578283fd5b505081359360208301359350604090920135919050565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b600080821280156001600160ff1b038490038513161561158157611581611826565b600160ff1b839003841281161561159a5761159a611826565b50500190565b600082198211156115b3576115b3611826565b500190565b6000826115c7576115c761183c565b600160ff1b8214600019841416156115e1576115e1611826565b500590565b6000826115f5576115f561183c565b500490565b600181815b8085111561163557816000190482111561161b5761161b611826565b8085161561162857918102915b93841c93908002906115ff565b509250929050565b6000610f05838360008261165357506001610f08565b8161166057506000610f08565b816001811461167657600281146116805761169c565b6001915050610f08565b60ff84111561169157611691611826565b50506001821b610f08565b5060208310610133831016604e8410600b84101617156116bf575081810a610f08565b6116c983836115fa565b80600019048211156116dd576116dd611826565b029392505050565b60006001600160ff1b038184138284138082168684048611161561170b5761170b611826565b600160ff1b8487128281168783058912161561172957611729611826565b85871292508782058712848416161561174457611744611826565b8785058712818416161561175a5761175a611826565b505050929093029392505050565b600081600019048311821515161561178257611782611826565b500290565b60008083128015600160ff1b8501841216156117a5576117a5611826565b6001600160ff1b03840183138116156117c0576117c0611826565b50500390565b6000828210156117d8576117d8611826565b500390565b60006000198214156117f1576117f1611826565b5060010190565b6000826118075761180761183c565b500690565b6000600160ff1b82141561182257611822611826565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0381168114610ec257600080fdfea2646970667358221220b357ef0d32b2703a5583db62cbbc00074063843793cd65ea8df244ff9c18763864736f6c63430008040033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 2f2f235e..8c5f982b 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -64,11 +64,7 @@ task('deploy:amplforce:testnet', 'Deploy ampleforth contract suite for testnet') console.log('Implementation:', amplImpl) // deploy market oracle - const marketOracle = await deployContract( - hre, - 'MedianOracle', - deployer, - ) + const marketOracle = await deployContract(hre, 'MedianOracle', deployer) await marketOracle.init( RATE_REPORT_EXPIRATION_SEC, RATE_REPORT_DELAY_SEC, @@ -77,11 +73,7 @@ task('deploy:amplforce:testnet', 'Deploy ampleforth contract suite for testnet') console.log('Market oracle to:', marketOracle.address) // deploy cpi oracle - const cpiOracle = await deployContract( - hre, - 'MedianOracle', - deployer, - ) + const cpiOracle = await deployContract(hre, 'MedianOracle', deployer) await cpiOracle.init( CPI_REPORT_EXPIRATION_SEC, CPI_REPORT_DELAY_SEC, @@ -206,3 +198,30 @@ task('deploy:wampl', 'Deploy wampl contract') await wampl.deployTransaction.wait(5) await verify(hre, wampl.address, [args.ampl]) }) + + +task('deploy:oracle', 'Deploy the median oracle contract') + .addParam('expiry', 'The report expiry') + .addParam('delay', 'The report delay') + .addParam('scalar', 'The scaling factor') + .setAction(async (args, hre) => { + console.log(args) + + // get signers + const deployer = (await hre.ethers.getSigners())[0] + console.log('Deployer', await deployer.getAddress()) + + // deploy contract + const oracle = await deployContract(hre, 'MedianOracle', deployer, []) + await oracle.init( + args.expiry, + args.delay, + 1, + args.scalar + ) + console.log('Oracle deployed to:', oracle.address) + + // wait and verify + await oracle.deployTransaction.wait(5) + await verify(hre, oracle.address, []) + }) diff --git a/scripts/helpers.ts b/scripts/helpers.ts index a0dd5ff9..1a92fdc0 100644 --- a/scripts/helpers.ts +++ b/scripts/helpers.ts @@ -16,6 +16,10 @@ export async function getContractFactoryFromExternalArtifacts( return hre.ethers.getContractFactoryFromArtifact(artifact) } +export async function sleep(sleepSec: number) { + await new Promise((resolve) => setTimeout(resolve, sleepSec)) +} + export async function waitFor(tx: TransactionResponse) { return (await tx).wait() } diff --git a/scripts/upgrade.ts b/scripts/upgrade.ts index 473a34c1..3d0f3c0e 100644 --- a/scripts/upgrade.ts +++ b/scripts/upgrade.ts @@ -1,10 +1,17 @@ +import { readFileSync } from 'fs' +import * as path from 'path' + import { task } from 'hardhat/config' import { getAdminAddress } from '@openzeppelin/upgrades-core' import { Interface } from '@ethersproject/abi' import { TransactionReceipt } from '@ethersproject/providers' import ProxyAdmin from '@openzeppelin/upgrades-core/artifacts/ProxyAdmin.json' -import { getContractFactoryFromExternalArtifacts } from './helpers' +import { + getContractFactoryFromExternalArtifacts, + verify, + sleep, +} from './helpers' const parseEvents = ( receipt: TransactionReceipt, @@ -93,3 +100,42 @@ task('upgrade:ampl', 'Upgrade ampleforth contracts') console.log(args.contract, 'upgraded') } }) + +task('prep:upgrade:policy') + .addParam('address', 'which proxy address to upgrade') + .addParam('prevVersion', 'the version tag of the previous implementation') + .setAction(async function (args: TaskArguments, hre) { + console.log(args) + const upgrades = hre.upgrades as any + + const signer = (await hre.ethers.getSigners())[0] + const signerAddress = await signer.getAddress() + console.log('Signer', signerAddress) + + const prevFactory = await ethers.getContractFactoryFromArtifact( + JSON.parse( + readFileSync( + path.join( + __dirname, + `/../external-artifacts/UFragmentsPolicy_${args.prevVersion}.json`, + ), + ).toString(), + ), + ) + const newFactory = await hre.ethers.getContractFactory('UFragmentsPolicy') + + // const prevImpl = await upgrades.forceImport(args.address, prevFactory) + await upgrades.validateUpgrade(args.address, newFactory) + const newImpl = await upgrades.prepareUpgrade(args.address, newFactory) + console.log('New implementation at:', newImpl) + + console.log('Update implementation by executing the following') + console.log( + 'Proxy Admin', + await getAdminAddress(hre.ethers.provider, args.address), + ) + console.log(`proxyAdmin.upgrade(${args.address}, ${newImpl})`) + + await sleep(15) + await verify(hre, newImpl, []) + }) diff --git a/test/unit/MedianOracle.ts b/test/unit/MedianOracle.ts index d705cef2..ea4ff409 100644 --- a/test/unit/MedianOracle.ts +++ b/test/unit/MedianOracle.ts @@ -23,7 +23,7 @@ async function setupContractsAndAccounts() { D = accounts[4] factory = await ethers.getContractFactory('MedianOracle') oracle = await factory.deploy() - await oracle.init(60, 10, 1) + await oracle.init(60, 10, 1, ethers.utils.parseUnits('1', 18)) await oracle.deployed() } @@ -262,6 +262,21 @@ describe('MedianOracle:removeProvider:accessControl', async function () { }) }) +describe('MedianOracle:setScalar:accessControl', async function () { + beforeEach(async function () { + await setupContractsAndAccounts() + }) + + it('should be callable by owner', async function () { + await oracle.setScalar(ethers.utils.parseUnits('1', 18)) + }) + + it('should NOT be callable by non-owner', async function () { + await expect(oracle.connect(A).setScalar(ethers.utils.parseUnits('1', 18))) + .to.be.reverted + }) +}) + describe('MedianOracle:getData', async function () { before(async function () { await setupContractsAndAccounts() @@ -542,6 +557,35 @@ describe('MedianOracle:getData', async function () { }) }) +describe('MedianOracle:getData', async function () { + before(async function () { + await setupContractsAndAccounts() + await setupCallerContract() + + await oracle.setScalar(BigNumber.from('900000000000000000')) + + await oracle.addProvider(await A.getAddress()) + await oracle.addProvider(await B.getAddress()) + await oracle.addProvider(await C.getAddress()) + await oracle.addProvider(await D.getAddress()) + + await oracle.connect(D).pushReport(BigNumber.from('1000000000000000000')) + await oracle.connect(B).pushReport(BigNumber.from('1041000000000000000')) + await oracle.connect(A).pushReport(BigNumber.from('1053200000000000000')) + await oracle.connect(C).pushReport(BigNumber.from('2041000000000000000')) + + await increaseTime(40) + }) + + describe('when a scalar is set', function () { + it('should scale the median', async function () { + await expect(callerContract.getData()) + .to.emit(callerContract, 'ReturnValueUInt256Bool') + .withArgs(BigNumber.from('942390000000000000'), true) + }) + }) +}) + describe('MedianOracle:PurgeReports', async function () { before(async function () { await setupContractsAndAccounts() diff --git a/test/unit/UFragmentsPolicy.ts b/test/unit/UFragmentsPolicy.ts index fd7054fb..d335235c 100644 --- a/test/unit/UFragmentsPolicy.ts +++ b/test/unit/UFragmentsPolicy.ts @@ -14,12 +14,10 @@ let deployer: Signer, user: Signer, orchestrator: Signer const MAX_RATE = ethers.utils.parseUnits('1', 24) const MAX_SUPPLY = ethers.BigNumber.from(2).pow(255).sub(1).div(MAX_RATE) -const BASE_CPI = ethers.utils.parseUnits('1', 20) -const INITIAL_CPI = ethers.utils.parseUnits('251.712', 18) - -const INITIAL_CPI_25P_MORE = imul(INITIAL_CPI, '1.25', 1) -const INITIAL_CPI_25P_LESS = imul(INITIAL_CPI, '0.75', 1) -const INITIAL_RATE = imul(INITIAL_CPI, 1e18, BASE_CPI) +const INITIAL_TARGET_RATE = ethers.utils.parseUnits('1.05', 18) +const INITIAL_TARGET_RATE_25P_MORE = imul(INITIAL_TARGET_RATE, '1.25', 1) +const INITIAL_TARGET_RATE_25P_LESS = imul(INITIAL_TARGET_RATE, '0.75', 1) +const INITIAL_RATE = ethers.utils.parseUnits('1.05', 18) const INITIAL_RATE_30P_MORE = imul(INITIAL_RATE, '1.3', 1) const INITIAL_RATE_30P_LESS = imul(INITIAL_RATE, '0.7', 1) const INITIAL_RATE_5P_MORE = imul(INITIAL_RATE, '1.05', 1) @@ -46,9 +44,9 @@ async function mockedUpgradablePolicy() { // deploy upgradable contract const uFragmentsPolicy = await upgrades.deployProxy( (await ethers.getContractFactory('UFragmentsPolicy')).connect(deployer), - [await deployer.getAddress(), mockUFragments.address, BASE_CPI.toString()], + [await deployer.getAddress(), mockUFragments.address], { - initializer: 'initialize(address,address,uint256)', + initializer: 'initialize(address,address)', }, ) // setup oracles @@ -94,23 +92,23 @@ async function mockedUpgradablePolicyWithOpenRebaseWindow() { } async function mockExternalData( - rate: BigNumberish, - cpi: BigNumberish, + currentRate: BigNumberish, + targetRate: BigNumberish, uFragSupply: BigNumberish, - rateValidity = true, - cpiValidity = true, + currentRateValidity = true, + targetRateValidity = true, ) { - await mockMarketOracle.connect(deployer).storeData(rate) - await mockMarketOracle.connect(deployer).storeValidity(rateValidity) - await mockCpiOracle.connect(deployer).storeData(cpi) - await mockCpiOracle.connect(deployer).storeValidity(cpiValidity) + await mockMarketOracle.connect(deployer).storeData(currentRate) + await mockMarketOracle.connect(deployer).storeValidity(currentRateValidity) + await mockCpiOracle.connect(deployer).storeData(targetRate) + await mockCpiOracle.connect(deployer).storeValidity(targetRateValidity) await mockUFragments.connect(deployer).storeSupply(uFragSupply) } -async function parseRebaseLog(response: Promise) { +async function parseRebaseEvent(response: Promise) { const receipt = (await (await response).wait()) as any const logs = receipt.events.filter( - (event: Event) => event.event === 'LogRebase', + (event: Event) => event.event === 'LogRebaseV2', ) return logs[0].args } @@ -610,7 +608,12 @@ describe('UFragmentsPolicy:Rebase:accessControl', async function () { uFragmentsPolicy, } = await waffle.loadFixture(mockedUpgradablePolicyWithOpenRebaseWindow)) // await setupContractsWithOpenRebaseWindow() - await mockExternalData(INITIAL_RATE_30P_MORE, INITIAL_CPI, 1000, true) + await mockExternalData( + INITIAL_RATE_30P_MORE, + INITIAL_TARGET_RATE, + 1000, + true, + ) await increaseTime(60) }) @@ -643,7 +646,7 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('when minRebaseTimeIntervalSec has NOT passed since the previous rebase', function () { before(async function () { - await mockExternalData(INITIAL_RATE_30P_MORE, INITIAL_CPI, 1010) + await mockExternalData(INITIAL_RATE_30P_MORE, INITIAL_TARGET_RATE, 1010) await increaseTime(60) await uFragmentsPolicy.connect(orchestrator).rebase() }) @@ -677,32 +680,52 @@ describe('UFragmentsPolicy:Rebase', async function () { }) it('should return 0', async function () { - await mockExternalData(INITIAL_RATE.sub(1), INITIAL_CPI, 1000) + await mockExternalData(INITIAL_RATE.sub(1), INITIAL_TARGET_RATE, 1000) await increaseTime(60) expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(0) await increaseTime(60) - await mockExternalData(INITIAL_RATE.add(1), INITIAL_CPI, 1000) + await mockExternalData(INITIAL_RATE.add(1), INITIAL_TARGET_RATE, 1000) expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(0) await increaseTime(60) - await mockExternalData(INITIAL_RATE_5P_MORE.sub(2), INITIAL_CPI, 1000) + await mockExternalData( + INITIAL_RATE_5P_MORE.sub(2), + INITIAL_TARGET_RATE, + 1000, + ) expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(0) await increaseTime(60) - await mockExternalData(INITIAL_RATE_5P_LESS.add(2), INITIAL_CPI, 1000) + await mockExternalData( + INITIAL_RATE_5P_LESS.add(2), + INITIAL_TARGET_RATE, + 1000, + ) expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(0) await increaseTime(60) }) @@ -725,31 +748,37 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('when rate is more than MAX_RATE', function () { it('should return same supply delta as delta for MAX_RATE', async function () { // Any exchangeRate >= (MAX_RATE=100x) would result in the same supply increase - await mockExternalData(MAX_RATE, INITIAL_CPI, 1000) + await mockExternalData(MAX_RATE, INITIAL_TARGET_RATE, 1000) await increaseTime(60) const supplyChange = ( - await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase()) + await parseRebaseEvent(uFragmentsPolicy.connect(orchestrator).rebase()) ).requestedSupplyAdjustment await increaseTime(60) await mockExternalData( MAX_RATE.add(ethers.utils.parseUnits('1', 17)), - INITIAL_CPI, + INITIAL_TARGET_RATE, 1000, ) expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(supplyChange) await increaseTime(60) - await mockExternalData(MAX_RATE.mul(2), INITIAL_CPI, 1000) + await mockExternalData(MAX_RATE.mul(2), INITIAL_TARGET_RATE, 1000) expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(supplyChange) }) }) @@ -770,7 +799,11 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('when uFragments grows beyond MAX_SUPPLY', function () { before(async function () { - await mockExternalData(INITIAL_RATE_2X, INITIAL_CPI, MAX_SUPPLY.sub(1)) + await mockExternalData( + INITIAL_RATE_2X, + INITIAL_TARGET_RATE, + MAX_SUPPLY.sub(1), + ) await increaseTime(60) }) @@ -778,8 +811,11 @@ describe('UFragmentsPolicy:Rebase', async function () { // Supply is MAX_SUPPLY-1, exchangeRate is 2x; resulting in a new supply more than MAX_SUPPLY // However, supply is ONLY increased by 1 to MAX_SUPPLY expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(1) }) }) @@ -800,14 +836,17 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('when uFragments supply equals MAX_SUPPLY and rebase attempts to grow', function () { before(async function () { - await mockExternalData(INITIAL_RATE_2X, INITIAL_CPI, MAX_SUPPLY) + await mockExternalData(INITIAL_RATE_2X, INITIAL_TARGET_RATE, MAX_SUPPLY) await increaseTime(60) }) it('should not grow', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(0) }) }) @@ -828,7 +867,12 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('when the market oracle returns invalid data', function () { it('should fail', async function () { - await mockExternalData(INITIAL_RATE_30P_MORE, INITIAL_CPI, 1000, false) + await mockExternalData( + INITIAL_RATE_30P_MORE, + INITIAL_TARGET_RATE, + 1000, + false, + ) await increaseTime(60) await expect(uFragmentsPolicy.connect(orchestrator).rebase()).to.be .reverted @@ -837,7 +881,12 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('when the market oracle returns valid data', function () { it('should NOT fail', async function () { - await mockExternalData(INITIAL_RATE_30P_MORE, INITIAL_CPI, 1000, true) + await mockExternalData( + INITIAL_RATE_30P_MORE, + INITIAL_TARGET_RATE, + 1000, + true, + ) await increaseTime(60) await expect(uFragmentsPolicy.connect(orchestrator).rebase()).to.not.be .reverted @@ -862,7 +911,7 @@ describe('UFragmentsPolicy:Rebase', async function () { it('should fail', async function () { await mockExternalData( INITIAL_RATE_30P_MORE, - INITIAL_CPI, + INITIAL_TARGET_RATE, 1000, true, false, @@ -877,7 +926,7 @@ describe('UFragmentsPolicy:Rebase', async function () { it('should NOT fail', async function () { await mockExternalData( INITIAL_RATE_30P_MORE, - INITIAL_CPI, + INITIAL_TARGET_RATE, 1000, true, true, @@ -902,9 +951,9 @@ describe('UFragmentsPolicy:Rebase', async function () { } = await waffle.loadFixture(mockedUpgradablePolicyWithOpenRebaseWindow)) }) - describe('positive rate and no change CPI', function () { + describe('positive rate and no change target', function () { beforeEach(async function () { - await mockExternalData(INITIAL_RATE_30P_MORE, INITIAL_CPI, 1000) + await mockExternalData(INITIAL_RATE_30P_MORE, INITIAL_TARGET_RATE, 1000) await uFragmentsPolicy .connect(deployer) .setRebaseTimingParameters(60, 0, 60) @@ -912,7 +961,7 @@ describe('UFragmentsPolicy:Rebase', async function () { await uFragmentsPolicy.connect(orchestrator).rebase() prevEpoch = await uFragmentsPolicy.epoch() prevTime = await uFragmentsPolicy.lastRebaseTimestampSec() - await mockExternalData(INITIAL_RATE_60P_MORE, INITIAL_CPI, 1010) + await mockExternalData(INITIAL_RATE_60P_MORE, INITIAL_TARGET_RATE, 1010) await increaseTime(60) }) @@ -937,15 +986,12 @@ describe('UFragmentsPolicy:Rebase', async function () { it('should emit Rebase with positive requestedSupplyAdjustment', async function () { const r = uFragmentsPolicy.connect(orchestrator).rebase() await expect(r) - .to.emit(uFragmentsPolicy, 'LogRebase') + .to.emit(uFragmentsPolicy, 'LogRebaseV2') .withArgs( prevEpoch.add(1), INITIAL_RATE_60P_MORE, - INITIAL_CPI, + INITIAL_TARGET_RATE, 55, - ( - await parseRebaseLog(r) - ).timestampSec, ) }) @@ -988,21 +1034,24 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('negative rate', function () { before(async function () { - await mockExternalData(INITIAL_RATE_30P_LESS, INITIAL_CPI, 1000) + await mockExternalData(INITIAL_RATE_30P_LESS, INITIAL_TARGET_RATE, 1000) await increaseTime(60) }) it('should emit Rebase with negative requestedSupplyAdjustment', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(-29) }) }) describe('max positive rebase', function () { before(async function () { - await mockExternalData(INITIAL_RATE_2X, INITIAL_CPI, 1000) + await mockExternalData(INITIAL_RATE_2X, INITIAL_TARGET_RATE, 1000) await uFragmentsPolicy .connect(deployer) .setRebaseFunctionGrowth('100' + '000000000000000000') @@ -1011,15 +1060,18 @@ describe('UFragmentsPolicy:Rebase', async function () { it('should emit Rebase with positive requestedSupplyAdjustment', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(100) }) }) describe('max negative rebase', function () { before(async function () { - await mockExternalData(0, INITIAL_CPI, 1000) + await mockExternalData(0, INITIAL_TARGET_RATE, 1000) await uFragmentsPolicy .connect(deployer) .setRebaseFunctionGrowth('75' + '000000000000000000') @@ -1028,15 +1080,18 @@ describe('UFragmentsPolicy:Rebase', async function () { it('should emit Rebase with negative requestedSupplyAdjustment', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(-100) }) }) describe('exponent less than -100', function () { before(async function () { - await mockExternalData(0, INITIAL_CPI, 1000) + await mockExternalData(0, INITIAL_TARGET_RATE, 1000) await uFragmentsPolicy .connect(deployer) .setRebaseFunctionGrowth('150' + '000000000000000000') @@ -1045,8 +1100,11 @@ describe('UFragmentsPolicy:Rebase', async function () { it('should emit Rebase with negative requestedSupplyAdjustment', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(-100) }) }) @@ -1065,17 +1123,20 @@ describe('UFragmentsPolicy:Rebase', async function () { } = await waffle.loadFixture(mockedUpgradablePolicyWithOpenRebaseWindow)) }) - describe('when cpi increases', function () { + describe('when target increases', function () { before(async function () { - await mockExternalData(INITIAL_RATE, INITIAL_CPI_25P_MORE, 1000) + await mockExternalData(INITIAL_RATE, INITIAL_TARGET_RATE_25P_MORE, 1000) await increaseTime(60) await uFragmentsPolicy.connect(deployer).setDeviationThreshold(0) }) it('should emit Rebase with negative requestedSupplyAdjustment', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(-20) }) }) @@ -1094,17 +1155,20 @@ describe('UFragmentsPolicy:Rebase', async function () { } = await waffle.loadFixture(mockedUpgradablePolicyWithOpenRebaseWindow)) }) - describe('when cpi decreases', function () { + describe('when target decreases', function () { before(async function () { - await mockExternalData(INITIAL_RATE, INITIAL_CPI_25P_LESS, 1000) + await mockExternalData(INITIAL_RATE, INITIAL_TARGET_RATE_25P_LESS, 1000) await increaseTime(60) await uFragmentsPolicy.connect(deployer).setDeviationThreshold(0) }) it('should emit Rebase with positive requestedSupplyAdjustment', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(32) }) }) @@ -1125,15 +1189,18 @@ describe('UFragmentsPolicy:Rebase', async function () { describe('rate=TARGET_RATE', function () { before(async function () { - await mockExternalData(INITIAL_RATE, INITIAL_CPI, 1000) + await mockExternalData(INITIAL_RATE, INITIAL_TARGET_RATE, 1000) await uFragmentsPolicy.connect(deployer).setDeviationThreshold(0) await increaseTime(60) }) it('should emit Rebase with 0 requestedSupplyAdjustment', async function () { expect( - (await parseRebaseLog(uFragmentsPolicy.connect(orchestrator).rebase())) - .requestedSupplyAdjustment, + ( + await parseRebaseEvent( + uFragmentsPolicy.connect(orchestrator).rebase(), + ) + ).requestedSupplyAdjustment, ).to.eq(0) }) }) @@ -1161,7 +1228,7 @@ describe('UFragmentsPolicy:Rebase', async function () { await uFragmentsPolicy .connect(deployer) .setRebaseTimingParameters(86400, 72000, 900) - await mockExternalData(INITIAL_RATE, INITIAL_CPI, 1000) + await mockExternalData(INITIAL_RATE, INITIAL_TARGET_RATE, 1000) rbTime = await uFragmentsPolicy.rebaseWindowOffsetSec() rbWindow = await uFragmentsPolicy.rebaseWindowLengthSec() minRebaseTimeIntervalSec = await uFragmentsPolicy.minRebaseTimeIntervalSec()