generated from PaulRBerg/foundry-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/toknowwhy/theunit-contracts
- Loading branch information
Showing
13 changed files
with
347 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule forge-std
updated
21 files
+48 −6 | .github/workflows/ci.yml | |
+1 −1 | package.json | |
+4 −3 | src/Script.sol | |
+18 −5 | src/StdChains.sol | |
+156 −15 | src/StdCheats.sol | |
+16 −1 | src/StdInvariant.sol | |
+18 −14 | src/StdJson.sol | |
+54 −3 | src/StdStorage.sol | |
+2 −2 | src/StdStyle.sol | |
+1 −1 | src/StdUtils.sol | |
+4 −3 | src/Test.sol | |
+505 −239 | src/Vm.sol | |
+93 −77 | test/StdAssertions.t.sol | |
+93 −37 | test/StdChains.t.sol | |
+167 −64 | test/StdCheats.t.sol | |
+10 −10 | test/StdError.t.sol | |
+27 −12 | test/StdMath.t.sol | |
+66 −34 | test/StdStorage.t.sol | |
+4 −4 | test/StdStyle.t.sol | |
+66 −36 | test/StdUtils.t.sol | |
+15 −0 | test/Vm.t.sol |
Submodule prb-test
updated
6 files
+2 −2 | .github/workflows/sync.yml | |
+37 −0 | CHANGELOG.md | |
+2 −2 | README.md | |
+2 −5 | package.json | |
+5 −1 | pnpm-lock.yaml | |
+155 −47 | src/Vm.sol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
@prb/test/=lib/prb-test/src/ | ||
forge-std/=lib/forge-std/src/ | ||
@openzeppelin/=lib/openzeppelin-contracts/ | ||
@uniswap/=lib/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.21; | ||
|
||
|
||
interface IFastPriceFeed { | ||
function lastUpdatedAt() external view returns (uint256); | ||
function lastUpdatedBlock() external view returns (uint256); | ||
// function setSigner(address _account, bool _isActive) external; | ||
// function setUpdater(address _account, bool _isActive) external; | ||
// function setPriceDuration(uint256 _priceDuration) external; | ||
// function setMaxPriceUpdateDelay(uint256 _maxPriceUpdateDelay) external; | ||
// function setSpreadBasisPointsIfInactive(uint256 _spreadBasisPointsIfInactive) external; | ||
// function setSpreadBasisPointsIfChainError(uint256 _spreadBasisPointsIfChainError) external; | ||
// function setMinBlockInterval(uint256 _minBlockInterval) external; | ||
// function setIsSpreadEnabled(bool _isSpreadEnabled) external; | ||
// function setMaxDeviationBasisPoints(uint256 _maxDeviationBasisPoints) external; | ||
// function setMaxCumulativeDeltaDiffs(address[] memory _tokens, uint256[] memory _maxCumulativeDeltaDiffs) external; | ||
// function setPriceDataInterval(uint256 _priceDataInterval) external; | ||
// function setVaultPriceFeed(address _vaultPriceFeed) external; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.21; | ||
|
||
import "../interfaces/IFastPriceFeed.sol"; | ||
import "../interfaces/IVaultPriceFeed.sol"; | ||
|
||
contract FastPriceFeed is IFastPriceFeed { | ||
// fit data in a uint256 slot to save gas costs | ||
struct PriceDataItem { | ||
uint160 refPrice; // Chainlink price | ||
uint32 refTime; // last updated at time | ||
uint32 cumulativeRefDelta; // cumulative Chainlink price delta | ||
uint32 cumulativeFastDelta; // cumulative fast price delta | ||
} | ||
|
||
address public fastPriceEvents; | ||
address public vaultPriceFeed; | ||
uint256 constant public BITMASK_32 = ~uint256(0) >> (256 - 32); | ||
uint256 public constant MAX_REF_PRICE = type(uint160).max; | ||
uint256 public constant MAX_CUMULATIVE_REF_DELTA = type(uint32).max; | ||
uint256 public constant MAX_CUMULATIVE_FAST_DELTA = type(uint32).max; | ||
uint256 public constant PRICE_PRECISION = 10 ** 30; | ||
uint256 public constant CUMULATIVE_DELTA_PRECISION = 10 * 1000 * 1000; | ||
|
||
// array of tokens used in setCompactedPrices, saves L1 calldata gas costs | ||
address[] public tokens; | ||
// array of tokenPrecisions used in setCompactedPrices, saves L1 calldata gas costs | ||
// if the token price will be sent with 3 decimals, then tokenPrecision for that token | ||
// should be 10 ** 3 | ||
uint256[] public tokenPrecisions; | ||
|
||
|
||
uint256 public priceDuration; | ||
uint256 public maxPriceUpdateDelay; | ||
uint256 public spreadBasisPointsIfInactive; | ||
uint256 public spreadBasisPointsIfChainError; | ||
uint256 public minBlockInterval; | ||
uint256 public maxTimeDeviation; | ||
|
||
uint256 public override lastUpdatedAt; | ||
uint256 public override lastUpdatedBlock; | ||
|
||
uint256 public priceDataInterval; | ||
|
||
mapping (address => uint256) public prices; | ||
|
||
mapping (address => bool) public isUpdater; | ||
|
||
mapping (address => PriceDataItem) public priceData; | ||
mapping (address => uint256) public maxCumulativeDeltaDiffs; | ||
|
||
event DisableFastPrice(address signer); | ||
event EnableFastPrice(address signer); | ||
event PriceData(address token, uint256 refPrice, uint256 fastPrice, uint256 cumulativeRefDelta, uint256 cumulativeFastDelta); | ||
event MaxCumulativeDeltaDiffExceeded(address token, uint256 refPrice, uint256 fastPrice, uint256 cumulativeRefDelta, uint256 cumulativeFastDelta); | ||
|
||
modifier onlyUpdater() { | ||
require(isUpdater[msg.sender], "FastPriceFeed: forbidden"); | ||
_; | ||
} | ||
|
||
function setPricesWithBits(uint256 _priceBits, uint256 _timestamp) external onlyUpdater { | ||
_setPricesWithBits(_priceBits, _timestamp); | ||
} | ||
|
||
function _setPricesWithBits(uint256 _priceBits, uint256 _timestamp) private { | ||
bool shouldUpdate = _setLastUpdatedValues(_timestamp); | ||
|
||
if (shouldUpdate) { | ||
address _fastPriceEvents = fastPriceEvents; | ||
address _vaultPriceFeed = vaultPriceFeed; | ||
|
||
for (uint256 j = 0; j < 8; j++) { | ||
uint256 index = j; | ||
if (index >= tokens.length) { return; } | ||
uint256 startBit = 32 * j; | ||
uint256 price = (_priceBits >> startBit) & BITMASK_32; | ||
|
||
address token = tokens[j]; | ||
uint256 tokenPrecision = tokenPrecisions[j]; | ||
// uint256 adjustedPrice = price.mul(PRICE_PRECISION).div(tokenPrecision); | ||
uint256 adjustedPrice = price * PRICE_PRECISION / tokenPrecision; | ||
_setPrice(token, adjustedPrice, _vaultPriceFeed, _fastPriceEvents); | ||
} | ||
} | ||
} | ||
|
||
function _setLastUpdatedValues(uint256 _timestamp) private returns (bool) { | ||
if (minBlockInterval > 0) { | ||
// require(block.number.sub(lastUpdatedBlock) >= minBlockInterval, "FastPriceFeed: minBlockInterval not yet passed"); | ||
require(block.number - lastUpdatedBlock >= minBlockInterval, "FastPriceFeed: minBlockInterval not yet passed"); | ||
} | ||
|
||
uint256 _maxTimeDeviation = maxTimeDeviation; | ||
require(_timestamp > block.timestamp - _maxTimeDeviation, "FastPriceFeed: _timestamp below allowed range"); | ||
require(_timestamp < block.timestamp + _maxTimeDeviation, "FastPriceFeed: _timestamp exceeds allowed range"); | ||
|
||
// do not update prices if _timestamp is before the current lastUpdatedAt value | ||
if (_timestamp < lastUpdatedAt) { | ||
return false; | ||
} | ||
|
||
lastUpdatedAt = _timestamp; | ||
lastUpdatedBlock = block.number; | ||
|
||
return true; | ||
} | ||
|
||
function _setPrice(address _token, uint256 _price, address _vaultPriceFeed, address _fastPriceEvents) private { | ||
// if (_vaultPriceFeed != address(0)) { | ||
// uint256 refPrice = IVaultPriceFeed(_vaultPriceFeed).getLatestPrimaryPrice(_token); | ||
// uint256 fastPrice = prices[_token]; | ||
|
||
// (uint256 prevRefPrice, uint256 refTime, uint256 cumulativeRefDelta, uint256 cumulativeFastDelta) = getPriceData(_token); | ||
|
||
// if (prevRefPrice > 0) { | ||
// uint256 refDeltaAmount = refPrice > prevRefPrice ? refPrice.sub(prevRefPrice) : prevRefPrice.sub(refPrice); | ||
// uint256 fastDeltaAmount = fastPrice > _price ? fastPrice.sub(_price) : _price.sub(fastPrice); | ||
|
||
// if (refTime.div(priceDataInterval) != block.timestamp.div(priceDataInterval)) { | ||
// cumulativeRefDelta = 0; | ||
// cumulativeFastDelta = 0; | ||
// } | ||
|
||
// cumulativeRefDelta = cumulativeRefDelta.add(refDeltaAmount.mul(CUMULATIVE_DELTA_PRECISION).div(prevRefPrice)); | ||
// cumulativeFastDelta = cumulativeFastDelta.add(fastDeltaAmount.mul(CUMULATIVE_DELTA_PRECISION).div(fastPrice)); | ||
// } | ||
|
||
// if (cumulativeFastDelta > cumulativeRefDelta && cumulativeFastDelta.sub(cumulativeRefDelta) > maxCumulativeDeltaDiffs[_token]) { | ||
// emit MaxCumulativeDeltaDiffExceeded(_token, refPrice, fastPrice, cumulativeRefDelta, cumulativeFastDelta); | ||
// } | ||
|
||
// _setPriceData(_token, refPrice, cumulativeRefDelta, cumulativeFastDelta); | ||
// emit PriceData(_token, refPrice, fastPrice, cumulativeRefDelta, cumulativeFastDelta); | ||
// } | ||
|
||
// prices[_token] = _price; | ||
// _emitPriceEvent(_fastPriceEvents, _token, _price); | ||
} | ||
function _setPriceData(address _token, uint256 _refPrice, uint256 _cumulativeRefDelta, uint256 _cumulativeFastDelta) private { | ||
require(_refPrice < MAX_REF_PRICE, "FastPriceFeed: invalid refPrice"); | ||
// skip validation of block.timestamp, it should only be out of range after the year 2100 | ||
require(_cumulativeRefDelta < MAX_CUMULATIVE_REF_DELTA, "FastPriceFeed: invalid cumulativeRefDelta"); | ||
require(_cumulativeFastDelta < MAX_CUMULATIVE_FAST_DELTA, "FastPriceFeed: invalid cumulativeFastDelta"); | ||
|
||
priceData[_token] = PriceDataItem( | ||
uint160(_refPrice), | ||
uint32(block.timestamp), | ||
uint32(_cumulativeRefDelta), | ||
uint32(_cumulativeFastDelta) | ||
); | ||
} | ||
|
||
function getPriceData(address _token) public view returns (uint256, uint256, uint256, uint256) { | ||
PriceDataItem memory data = priceData[_token]; | ||
return (uint256(data.refPrice), uint256(data.refTime), uint256(data.cumulativeRefDelta), uint256(data.cumulativeFastDelta)); | ||
} | ||
|
||
function _emitPriceEvent(address _fastPriceEvents, address _token, uint256 _price) private { | ||
if (_fastPriceEvents == address(0)) { | ||
return; | ||
} | ||
// IFastPriceEvents(_fastPriceEvents).emitPriceEvent(_token, _price); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.