Skip to content

Commit

Permalink
Merge branch 'fix/oracle-struct' into feat/max-clamp-per-trade
Browse files Browse the repository at this point in the history
  • Loading branch information
xenide authored Nov 18, 2024
2 parents 18bd916 + 4100d42 commit 99a8c67
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 12 deletions.
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ solc = "0.8.23"
#via_ir = true
bytecode_hash = "ipfs"
optimizer_runs = 1_000_000
gas_limit = "18446744073709551615"
libs = ['lib']
remappings = [
"@openzeppelin/=lib/openzeppelin-contracts/contracts/",
Expand Down
8 changes: 4 additions & 4 deletions script/unoptimized-deployer-meta
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"constant_product_hash": "0xadeb5412c0cc65b7731f7190a28411dee2e89236f5e304ae49d1f90501134e06",
"factory_hash": "0x4e6ccdb29abe10d6374353935f08b1c008defaddab9aab32c6531161a3ed7826",
"oracle_caller_hash": "0xf31d810e0940d59eb76303615744d1837449efb8575274db894f243eddb2c304",
"stable_hash": "0xca90854439397b4f6bbaac64acdaaa1538802c2bc6c9951ac4a161e7c60a4528"
"constant_product_hash": "0x5c457dc7ab8cc4db0c7088c12fb2c35971517bc18be0788a37a31551f3acfb3c",
"factory_hash": "0xef85bf001813a3ca09b7d4c95f39f3d733812fcf381a373bd5beb89a748ddc5b",
"oracle_caller_hash": "0xb747bec5b4d21e05eff52d57f42c366b975aa81f8626d91205c6a3b31b853dc7",
"stable_hash": "0xe466a25862b9f9c9c3183f4c99f73af1e647bdd2feea892aff546338cccba39e"
}
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(0x84e232ec0f6ea2ec4c9e4cfa7e5469dab805cb65ffaab4a7ee9c7c602f91345a);
bytes32 public constant FACTORY_HASH = bytes32(0xae59efa1baf1113957e748f189c8eb9271c4a0d919c8af03d26ae4fbddb51e81);
bytes32 public constant CONSTANT_PRODUCT_HASH =
bytes32(0xbd78fb88c65e9a8804773c3a0e0350627ae244d6daf312a549fc1e08ef9bf56e);
bytes32 public constant STABLE_HASH = bytes32(0x24174b50e2a4c46e25d5367496b6a2ca38bf33dceb07ef3aba32e2c1266a6bf1);
bytes32(0x356ae496acb4119a46481b3326102cb38281aad285e579d14598f6c5bb76f5e2);
bytes32 public constant STABLE_HASH = bytes32(0xa4bb872f2e22f611d0fd1ff88d960edc58283528282cb20aab4fbe14da557300);
bytes32 public constant ORACLE_CALLER_HASH =
bytes32(0xed0f7d96dcba353321d583022005b03c09088f7de3800703dc8324b1da6c77a6);
bytes32(0xf130f5cb7eebcf57bac9f5d273fd8cc18dfb1b3f48d114a5e6a8230440d50e0f);

// Deployment addresses.
GenericFactory public factory;
Expand Down
6 changes: 4 additions & 2 deletions src/ReservoirPair.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { StdMath } from "src/libraries/StdMath.sol";
import { FactoryStoreLib } from "src/libraries/FactoryStore.sol";
import { Bytes32Lib } from "src/libraries/Bytes32.sol";
import { LogCompression } from "src/libraries/LogCompression.sol";
import { Buffer } from "src/libraries/Buffer.sol";

import { IAssetManager, IERC20 } from "src/interfaces/IAssetManager.sol";
import { IAssetManagedPair } from "src/interfaces/IAssetManagedPair.sol";
Expand All @@ -25,6 +26,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
using SafeTransferLib for address;
using StdMath for uint256;
using FixedPointMathLib for uint256;
using Buffer for uint16;

uint256 public constant MINIMUM_LIQUIDITY = 1e3;
uint256 public constant FEE_ACCURACY = 1_000_000; // 100%
Expand Down Expand Up @@ -93,7 +95,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
//////////////////////////////////////////////////////////////////////////*/

Slot0 internal _slot0 = Slot0({ reserve0: 0, reserve1: 0, packedTimestamp: 0, index: type(uint16).max });
Slot0 internal _slot0 = Slot0({ reserve0: 0, reserve1: 0, packedTimestamp: 0, index: Buffer.SIZE - 1});

function _currentTime() internal view returns (uint32) {
return uint32(block.timestamp & 0x7FFFFFFF);
Expand Down Expand Up @@ -608,7 +610,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
aPrevious.logAccRawPrice + aPrevious.logInstantRawPrice * int88(int256(uint256(aTimeElapsed)));
int88 logAccClampedPrice =
aPrevious.logAccClampedPrice + aPrevious.logInstantClampedPrice * int88(int256(uint256(aTimeElapsed)));
aSlot0.index += 1;
aSlot0.index = aSlot0.index.next();
_observations[aSlot0.index] = Observation(
int24(aLogInstantRawPrice),
int24(aLogInstantClampedPrice),
Expand Down
51 changes: 51 additions & 0 deletions src/libraries/Buffer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.8.0;

library Buffer {
// The buffer is a circular storage structure with 2048 (2 ** 11) slots.
uint16 public constant SIZE = 2048;

/**
* @dev Returns the index of the element before the one pointed by `index`.
*/
function prev(uint16 index) internal pure returns (uint16) {
return sub(index, 1);
}

/**
* @dev Returns the index of the element after the one pointed by `index`.
*/
function next(uint16 index) internal pure returns (uint16) {
return add(index, 1);
}

/**
* @dev Returns the index of an element `offset` slots after the one pointed by `index`.
*/
function add(uint16 index, uint16 offset) internal pure returns (uint16) {
unchecked {
return (index + offset) % SIZE;
}
}

/**
* @dev Returns the index of an element `offset` slots before the one pointed by `index`.
*/
function sub(uint16 index, uint16 offset) internal pure returns (uint16) {
unchecked {
return (index + SIZE - offset) % SIZE;
}
}
}
5 changes: 3 additions & 2 deletions test/unit/OracleWriter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { LogCompression } from "src/libraries/LogCompression.sol";
import { FactoryStoreLib } from "src/libraries/FactoryStore.sol";
import { ConstantProductOracleMath } from "src/libraries/ConstantProductOracleMath.sol";
import { StableOracleMath } from "src/libraries/StableOracleMath.sol";
import { Buffer } from "src/libraries/Buffer.sol";
import { GenericFactory } from "src/GenericFactory.sol";
import { Constants } from "src/Constants.sol";

Expand Down Expand Up @@ -196,7 +197,7 @@ contract OracleWriterTest is BaseTest {
// sanity
(,,, uint16 lIndex) = _pair.getReserves();
Observation memory lObs = _oracleCaller.observation(_pair, lIndex);
assertEq(lIndex, type(uint16).max);
assertEq(lIndex, Buffer.SIZE - 1);
assertEq(LogCompression.fromLowResLog(lObs.logInstantRawPrice), lOriginalPrice, "instant 1");

// act
Expand All @@ -207,7 +208,7 @@ contract OracleWriterTest is BaseTest {
(,,, lIndex) = _pair.getReserves();
lObs = _oracleCaller.observation(_pair, lIndex);

assertEq(lIndex, type(uint16).max);
assertEq(lIndex, Buffer.SIZE - 1);
assertNotEq(LogCompression.fromLowResLog(lObs.logInstantRawPrice), lOriginalPrice);
assertNotEq(LogCompression.fromLowResLog(lObs.logInstantClampedPrice), lOriginalPrice);

Expand Down
59 changes: 59 additions & 0 deletions test/unit/libraries/Buffer.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "forge-std/Test.sol";

import { Buffer } from "src/libraries/Buffer.sol";

contract BufferTest is Test {
using Buffer for uint16;

function testPrev_AtLimit() external {
// arrange
uint16 lIndex = 0;

// act & assert
assertEq(lIndex.prev(), Buffer.SIZE - 1);
}

function testNext_AtLimit() external {
// arrange
uint16 lLimit = Buffer.SIZE - 1;

// act & assert
assertEq(lLimit.next(), 0);
}

function testNext_GreaterThanBufferSize(uint16 aStartingIndex) external {
// assume
uint16 lStartingIndex = uint16(bound(aStartingIndex, Buffer.SIZE, type(uint16).max));

// act & assert
unchecked {
assertEq(lStartingIndex.next(), (lStartingIndex + 1) % Buffer.SIZE);
}
assertLt(lStartingIndex.next(), Buffer.SIZE); // index returned always within bounds of Buffer.SIZE
}

function testAdd_IndexGreaterThanBufferSize(uint16 aStartingIndex, uint16 aOffset) external {
// assume
uint16 lStartingIndex = uint16(bound(aStartingIndex, Buffer.SIZE, type(uint16).max));

// act
uint16 lResult = lStartingIndex.add(aOffset);

// assert
assertLt(lResult, Buffer.SIZE);
}

function testSub_IndexGreaterThanBufferSize(uint16 aStartingIndex, uint16 aOffset) external {
// assume
uint16 lStartingIndex = uint16(bound(aStartingIndex, Buffer.SIZE, type(uint16).max));

// act
uint16 lResult = lStartingIndex.sub(aOffset);

// assert
assertLt(lResult, Buffer.SIZE);
}
}

0 comments on commit 99a8c67

Please sign in to comment.