Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: individual thresholds and reverse dutch auction #17

Merged
merged 17 commits into from
Aug 9, 2024
Merged
153 changes: 83 additions & 70 deletions src/ReservoirPriceOracle.sol

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/libraries/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ library Constants {
uint256 public constant WAD = 1e18;
uint256 public constant MAX_SUPPORTED_PRICE = type(uint128).max;
uint256 public constant MAX_AMOUNT_IN = type(uint128).max;
uint16 public constant BP_SCALE = 1e4;
}
2 changes: 2 additions & 0 deletions src/libraries/OracleErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pragma solidity ^0.8.0;
library OracleErrors {
// config errors
error IncorrectTokensDesignatePair();
error InvalidRewardThreshold();
error InvalidArrayLengthRewardThresholds();
error InvalidRoute();
error InvalidRouteLength();
error InvalidTokensProvided();
Expand Down
31 changes: 21 additions & 10 deletions src/libraries/RoutesLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@ library RoutesLib {
return aData[0] == FLAG_3_HOP_ROUTE;
}

// Positive value indicates that token1 has a greater number of decimals compared to token2
// while a negative value indicates otherwise.
// range of values between -18 and 18
function getDecimalDifference(bytes32 aData) internal pure returns (int256 rDiff) {
rDiff = int8(uint8(aData[1]));
}

// Assumes that aDecimalDifference is between -18 and 18
// Assumes that aPrice is between 1 and 1e36
function packSimplePrice(int256 aDecimalDifference, uint256 aPrice) internal pure returns (bytes32 rPacked) {
// Assumes that aRewardThreshold is <= Constants.BP_SCALE
function packSimplePrice(int256 aDecimalDifference, uint256 aPrice, uint16 aRewardThreshold)
internal
pure
returns (bytes32 rPacked)
{
bytes32 lDecimalDifferenceRaw = bytes1(uint8(int8(aDecimalDifference)));
rPacked = FLAG_SIMPLE_PRICE | lDecimalDifferenceRaw >> 8 | bytes32(aPrice);
bytes32 lRewardThreshold = bytes2(uint16(aRewardThreshold));
rPacked = FLAG_SIMPLE_PRICE | lDecimalDifferenceRaw >> 8 | lRewardThreshold >> 16 | bytes32(aPrice);
}

function pack2HopRoute(address aSecondToken) internal pure returns (bytes32 rPacked) {
Expand All @@ -55,8 +54,20 @@ library RoutesLib {
rSecondWord = bytes20(aThirdToken);
}

// Positive value indicates that token1 has a greater number of decimals compared to token2
// while a negative value indicates otherwise.
// range of values between -18 and 18
xenide marked this conversation as resolved.
Show resolved Hide resolved
function getDecimalDifference(bytes32 aData) internal pure returns (int256 rDiff) {
rDiff = int8(uint8(aData[1]));
}

function getPrice(bytes32 aData) internal pure returns (uint256 rPrice) {
rPrice = uint256(aData & 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
rPrice = uint256(aData & 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
}

function getRewardThreshold(bytes32 aData) internal pure returns (uint16 rRewardThreshold) {
rRewardThreshold =
uint16(uint256((aData & 0x0000ffff00000000000000000000000000000000000000000000000000000000) >> 224));
}

function getTokenFirstWord(bytes32 aData) internal pure returns (address rToken) {
Expand Down
14 changes: 14 additions & 0 deletions src/libraries/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,18 @@ library Utils {
function calculateSlot(address aToken0, address aToken1) internal pure returns (bytes32) {
return keccak256(abi.encode(aToken0, aToken1));
}

/// @dev Assumes that `aOriginal` and `aNew` is less than or equal to
/// `Constants.MAX_SUPPORTED_PRICE`. So multiplication by 1e18 will not overflow.
function calcPercentageDiff(uint256 aOriginal, uint256 aNew) internal pure returns (uint256) {
unchecked {
if (aOriginal == 0) return 0;

if (aOriginal > aNew) {
return (aOriginal - aNew) * 1e18 / aOriginal;
} else {
return (aNew - aOriginal) * 1e18 / aOriginal;
}
}
}
}
4 changes: 3 additions & 1 deletion test/__fixtures/BaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import { ReservoirPriceOracle, PriceType, IPriceOracle } from "src/ReservoirPric
contract BaseTest is Test {
using FactoryStoreLib for GenericFactory;

uint64 internal constant DEFAULT_REWARD_GAS_AMOUNT = 200_000;

GenericFactory internal _factory = new GenericFactory();
ReservoirPair internal _pair;

ReservoirPriceOracle internal _oracle =
new ReservoirPriceOracle(0.02e18, 15 minutes, 500_000, PriceType.CLAMPED_PRICE);
new ReservoirPriceOracle(0.15 minutes, DEFAULT_REWARD_GAS_AMOUNT, PriceType.CLAMPED_PRICE);
xenide marked this conversation as resolved.
Show resolved Hide resolved

MintableERC20 internal _tokenA = MintableERC20(address(0x100));
MintableERC20 internal _tokenB = MintableERC20(address(0x200));
Expand Down
8 changes: 6 additions & 2 deletions test/large/ReservoirPriceOracleLarge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
FixedPointMathLib,
MintableERC20,
ReservoirPair,
IERC20
IERC20,
Constants
} from "test/unit/ReservoirPriceOracle.t.sol";

contract ReservoirPriceOracleLargeTest is ReservoirPriceOracleTest {
Expand Down Expand Up @@ -77,7 +78,10 @@ contract ReservoirPriceOracleLargeTest is ReservoirPriceOracleTest {
lRoute[3] = aTokenAAddress;
}

_oracle.setRoute(lRoute[0], lRoute[3], lRoute);
uint16[] memory lBpDiffForMaxReward = new uint16[](3);
lBpDiffForMaxReward[0] = lBpDiffForMaxReward[1] = lBpDiffForMaxReward[2] = Constants.BP_SCALE;

_oracle.setRoute(lRoute[0], lRoute[3], lRoute, lBpDiffForMaxReward);
_writePriceCache(
lTokenA < lTokenB ? aTokenAAddress : aTokenBAddress,
lTokenA < lTokenB ? aTokenBAddress : aTokenAAddress,
Expand Down
Loading
Loading