Skip to content

Commit

Permalink
fix: underflow problem for price reduction case
Browse files Browse the repository at this point in the history
  • Loading branch information
xenide committed Mar 17, 2024
1 parent 5daf20d commit b9f04bf
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 22 deletions.
8 changes: 4 additions & 4 deletions script/optimized-deployer-meta
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"constant_product_hash": "0x7b0f16c5cf2f4e78c4f697bfefb1365008f8865aaaa942f46ced4e0dea45c42a",
"factory_hash": "0xab6a26d7fb7b6df7e81d9f9354f8b767b5ac11b732f1b3f2e9d6e5b69a7d0754",
"oracle_caller_hash": "0x0d71d4a05b676bfbccd00e8422375c347a056fb93cc502cc962d5e6912213b04",
"stable_hash": "0xc5b9d3031f577510c547b9465241780111ad9d25a80dbe2292d1dc4290d9cd5a"
"constant_product_hash": "0x6bb54a3a2e0eef36a4ee1866eee21dc514fac57496141ce405f9af4e37f34941",
"factory_hash": "0x5d635090575f999ee44232af44309f6053dc93b7844bfdd90ee7a7919a4d363c",
"oracle_caller_hash": "0x529da7083c2ffd40e327dd40a4ae6f796de1561a0191b323d0cbfab827fab3b7",
"stable_hash": "0x51e93a48df3616a3e56c131684d126d7d3ddcd8911d5b807a773aca3a576439e"
}
8 changes: 4 additions & 4 deletions src/ReservoirDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ contract ReservoirDeployer {
uint256 public step = 0;

// Bytecode hashes.
bytes32 public constant FACTORY_HASH = bytes32(0xab6a26d7fb7b6df7e81d9f9354f8b767b5ac11b732f1b3f2e9d6e5b69a7d0754);
bytes32 public constant FACTORY_HASH = bytes32(0x5d635090575f999ee44232af44309f6053dc93b7844bfdd90ee7a7919a4d363c);
bytes32 public constant CONSTANT_PRODUCT_HASH =
bytes32(0x7b0f16c5cf2f4e78c4f697bfefb1365008f8865aaaa942f46ced4e0dea45c42a);
bytes32 public constant STABLE_HASH = bytes32(0xc5b9d3031f577510c547b9465241780111ad9d25a80dbe2292d1dc4290d9cd5a);
bytes32(0x6bb54a3a2e0eef36a4ee1866eee21dc514fac57496141ce405f9af4e37f34941);
bytes32 public constant STABLE_HASH = bytes32(0x51e93a48df3616a3e56c131684d126d7d3ddcd8911d5b807a773aca3a576439e);
bytes32 public constant ORACLE_CALLER_HASH =
bytes32(0x0d71d4a05b676bfbccd00e8422375c347a056fb93cc502cc962d5e6912213b04);
bytes32(0x529da7083c2ffd40e327dd40a4ae6f796de1561a0191b323d0cbfab827fab3b7);

// Deployment addresses.
GenericFactory public factory;
Expand Down
14 changes: 12 additions & 2 deletions src/ReservoirPair.sol
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,8 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {

// 100 basis points per second which is 60% per minute
uint256 internal constant MAX_CHANGE_PER_SEC = 0.01e18;
// 10%
uint256 internal constant MAX_CHANGE_PER_TRADE = 0.1e18;
string internal constant MAX_CHANGE_RATE_NAME = "Shared::maxChangeRate";
string internal constant MAX_CHANGE_PER_TRADE_NAME = "Shared::maxChangePerTrade";
string internal constant ORACLE_CALLER_NAME = "Shared::oracleCaller";
Expand Down Expand Up @@ -547,6 +549,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {

function setClampParams(uint128 aMaxChangeRate, uint128 aMaxChangePerTrade) public onlyFactory {
require(0 < aMaxChangeRate && aMaxChangeRate <= MAX_CHANGE_PER_SEC, "RP: INVALID_CHANGE_PER_SECOND");
require(0 < aMaxChangePerTrade && aMaxChangePerTrade <= MAX_CHANGE_PER_TRADE, "RP: INVALID_CHANGE_PER_TRADE");

emit ClampParamsUpdated(aMaxChangeRate, aMaxChangePerTrade);
maxChangeRate = aMaxChangeRate;
Expand Down Expand Up @@ -582,8 +585,15 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
rClampedPrice = lRateLimitedPrice.min(lPerTradeLimitedPrice);
assert(rClampedPrice < aCurrRawPrice);
} else {
uint256 lRateLimitedPrice = aPrevClampedPrice.fullMulDiv(1e18 - maxChangeRate * aTimeElapsed, 1e18);
uint256 lPerTradeLimitedPrice = aPrevClampedPrice.fullMulDiv(1e18 - maxChangePerTrade , 1e18);
// make sure that the time elapsed is not too long, else the subtraction from 1e18 will underflow
// if the time elapsed is too long, then we only depend on the per trade limited price
uint256 lChangeElapsed = maxChangeRate * aTimeElapsed;
if (lChangeElapsed > 1e18) {
lChangeElapsed = 1e18;
}
uint256 lRateLimitedPrice = aPrevClampedPrice.fullMulDiv(1e18 - lChangeElapsed, 1e18);
// subtraction will not underflow as maxChangePerTrade is limited by MAX_CHANGE_PER_TRADE
uint256 lPerTradeLimitedPrice = aPrevClampedPrice.fullMulDiv(1e18 - maxChangePerTrade, 1e18);
rClampedPrice = lRateLimitedPrice.max(lPerTradeLimitedPrice);
assert(rClampedPrice > aCurrRawPrice);
}
Expand Down
21 changes: 9 additions & 12 deletions test/unit/OracleWriter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -414,28 +414,25 @@ contract OracleWriterTest is BaseTest {
}

function testOracle_OverflowAccPrice(uint32 aNewStartTime) public randomizeStartTime(aNewStartTime) allPairs {
// assume
vm.assume(aNewStartTime >= 1);

// arrange - make the last observation close to overflowing
(,,, uint16 lIndex) = _stablePair.getReserves();
(,,, uint16 lIndex) = _pair.getReserves();

_writeObservation(
_stablePair, lIndex, 1e3, 1e3, type(int88).max, type(int88).max, uint32(block.timestamp % 2 ** 31)
_pair, lIndex, 1e3, 1e3, type(int88).max, type(int88).max, uint32(block.timestamp % 2 ** 31)
);
Observation memory lPrevObs = _oracleCaller.observation(_stablePair, lIndex);
Observation memory lPrevObs = _oracleCaller.observation(_pair, lIndex);

// act
uint256 lAmountToSwap = 5e18;
_tokenB.mint(address(_stablePair), lAmountToSwap);
_stablePair.swap(-int256(lAmountToSwap), true, address(this), "");
_tokenB.mint(address(_pair), lAmountToSwap);
_pair.swap(-int256(lAmountToSwap), true, address(this), "");

_stepTime(5);
_stablePair.sync();
_pair.sync();

// assert - when it overflows it goes from a very positive number to a very negative number
(,,, lIndex) = _stablePair.getReserves();
Observation memory lCurrObs = _oracleCaller.observation(_stablePair, lIndex);
(,,, lIndex) = _pair.getReserves();
Observation memory lCurrObs = _oracleCaller.observation(_pair, lIndex);
assertLt(lCurrObs.logAccRawPrice, lPrevObs.logAccRawPrice);
}

}

0 comments on commit b9f04bf

Please sign in to comment.