Skip to content

Commit

Permalink
Merge branch 'dev' into change-packages
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVolosnikov committed Sep 18, 2023
2 parents 3cf3896 + f6576a8 commit 2e1ec26
Show file tree
Hide file tree
Showing 23 changed files with 840 additions and 168 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/echidna_periphery.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Echidna Periphery

on:
push:
branches:
- master
- staged
pull_request:
branches:
- master

jobs:
UnitAsserts:
strategy:
matrix:
testName:
- TickLensEchidnaTest

runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 20
cache: 'npm'

- name: Install dependencies
run: npm run ci-install

- name: Compile contracts
run: npm run compile
working-directory: ./src/periphery

- name: Run ${{ matrix.testName }}
uses: crytic/echidna-action@v2
with:
solc-version: 0.8.20
files: ./src/periphery/
contract: ${{ matrix.testName }}
crytic-args: --hardhat-ignore-compile
solc-args: --evm-version paris
config: ./src/periphery/contracts/test/echidna/echidna.config.yml
27 changes: 27 additions & 0 deletions docs/Contracts/Core/base/TickStructure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@


# TickStructure


Algebra tick structure abstract contract

Encapsulates the logic of interaction with the data structure with ticks

*Developer note: Ticks are stored as a doubly linked list. A three-level bitmap tree is used to search through the list*


## Variables
### uint32 tickTreeRoot

The root of tick search tree

*Developer note: Each bit corresponds to one node in the second layer of tick tree: '1' if node has at least one active bit.
**important security note: caller should check reentrancy lock to prevent read-only reentrancy***

### mapping(int16 => uint256) tickTreeSecondLayer

The second layer of tick search tree

*Developer note: Each bit in node corresponds to one node in the leafs layer (`tickTable`) of tick tree: '1' if leaf has at least one active bit.
**important security note: caller should check reentrancy lock to prevent read-only reentrancy***

38 changes: 38 additions & 0 deletions docs/Contracts/Core/interfaces/IAlgebraPoolState.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,41 @@ The next initialized tick after current global tick
| ---- | ---- | ----------- |
| [0] | int24 | The next initialized tick |

### tickTreeRoot

```solidity
function tickTreeRoot() external view returns (uint32)
```

The root of tick search tree

*Developer note: Each bit corresponds to one node in the second layer of tick tree: '1' if node has at least one active bit.
**important security note: caller should check reentrancy lock to prevent read-only reentrancy***

**Returns:**

| Name | Type | Description |
| ---- | ---- | ----------- |
| [0] | uint32 | The root of tick search tree as bitmap |

### tickTreeSecondLayer

```solidity
function tickTreeSecondLayer(int16) external view returns (uint256)
```

The second layer of tick search tree

*Developer note: Each bit in node corresponds to one node in the leafs layer (`tickTable`) of tick tree: '1' if leaf has at least one active bit.
**important security note: caller should check reentrancy lock to prevent read-only reentrancy***

| Name | Type | Description |
| ---- | ---- | ----------- |
| | int16 | |

**Returns:**

| Name | Type | Description |
| ---- | ---- | ----------- |
| [0] | uint256 | The node of tick search tree second layer |

3 changes: 2 additions & 1 deletion docs/Contracts/Periphery/NonfungiblePositionManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ must be collected first.
### approveForFarming

```solidity
function approveForFarming(uint256 tokenId, bool approve) external payable
function approveForFarming(uint256 tokenId, bool approve, address farmingAddress) external payable
```

Changes approval of token ID for farming.
Expand All @@ -221,6 +221,7 @@ Changes approval of token ID for farming.
| ---- | ---- | ----------- |
| tokenId | uint256 | The ID of the token that is being approved / unapproved |
| approve | bool | New status of approval |
| farmingAddress | address | The address of farming: used to prevent tx frontrun |

### switchFarmingStatus

Expand Down
40 changes: 40 additions & 0 deletions docs/Contracts/Periphery/TickLens.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,43 @@ Get all the tick data for the populated ticks from a word of the tick bitmap of
| ---- | ---- | ----------- |
| populatedTicks | struct ITickLens.PopulatedTick[] | An array of tick data for the given word in the tick bitmap |

### getClosestActiveTicks

```solidity
function getClosestActiveTicks(address pool, int24 targetTick) public view returns (struct ITickLens.PopulatedTick[2] populatedTicks)
```

Get closest initialized ticks around `targetTick`

| Name | Type | Description |
| ---- | ---- | ----------- |
| pool | address | The address of the pool for which to fetch populated tick data |
| targetTick | int24 | The tick around which the nearest ticks will be searched |

**Returns:**

| Name | Type | Description |
| ---- | ---- | ----------- |
| populatedTicks | struct ITickLens.PopulatedTick[2] | An array of two ticks: before or at `targetTick` and after `targetTick` |

### getNextActiveTicks

```solidity
function getNextActiveTicks(address pool, int24 startingTick, uint256 amount, bool upperDirection) public view returns (struct ITickLens.PopulatedTick[] populatedTicks)
```

Get all the tick data for the `amount` of populated ticks after `startingTick` (including `startingTick` itself)

| Name | Type | Description |
| ---- | ---- | ----------- |
| pool | address | The address of the pool for which to fetch populated tick data |
| startingTick | int24 | The starting tick index. Must be populated tick |
| amount | uint256 | The maximum amount of ticks requested |
| upperDirection | bool | The direction of search. Will fetch 'next' ticks in direction of price increase if true |

**Returns:**

| Name | Type | Description |
| ---- | ---- | ----------- |
| populatedTicks | struct ITickLens.PopulatedTick[] | An array of tick data for fetched ticks |

53 changes: 0 additions & 53 deletions docs/Contracts/Periphery/interfaces/IERC20Metadata.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ must be collected first.
### approveForFarming

```solidity
function approveForFarming(uint256 tokenId, bool approve) external payable
function approveForFarming(uint256 tokenId, bool approve, address farmingAddress) external payable
```

Changes approval of token ID for farming.
Expand All @@ -292,6 +292,7 @@ Changes approval of token ID for farming.
| ---- | ---- | ----------- |
| tokenId | uint256 | The ID of the token that is being approved / unapproved |
| approve | bool | New status of approval |
| farmingAddress | address | The address of farming: used to prevent tx frontrun |

### switchFarmingStatus

Expand Down
40 changes: 40 additions & 0 deletions docs/Contracts/Periphery/interfaces/ITickLens.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,43 @@ Get all the tick data for the populated ticks from a word of the tick bitmap of
| ---- | ---- | ----------- |
| populatedTicks | struct ITickLens.PopulatedTick[] | An array of tick data for the given word in the tick bitmap |

### getClosestActiveTicks

```solidity
function getClosestActiveTicks(address pool, int24 targetTick) external view returns (struct ITickLens.PopulatedTick[2] populatedTicks)
```

Get closest initialized ticks around `targetTick`

| Name | Type | Description |
| ---- | ---- | ----------- |
| pool | address | The address of the pool for which to fetch populated tick data |
| targetTick | int24 | The tick around which the nearest ticks will be searched |

**Returns:**

| Name | Type | Description |
| ---- | ---- | ----------- |
| populatedTicks | struct ITickLens.PopulatedTick[2] | An array of two ticks: before or at `targetTick` and after `targetTick` |

### getNextActiveTicks

```solidity
function getNextActiveTicks(address pool, int24 startingTick, uint256 amount, bool upperDirection) external view returns (struct ITickLens.PopulatedTick[] populatedTicks)
```

Get all the tick data for the `amount` of populated ticks after `startingTick` (including `startingTick` itself)

| Name | Type | Description |
| ---- | ---- | ----------- |
| pool | address | The address of the pool for which to fetch populated tick data |
| startingTick | int24 | The starting tick index. Must be populated tick |
| amount | uint256 | The maximum amount of ticks requested |
| upperDirection | bool | The direction of search. Will fetch 'next' ticks in direction of price increase if true |

**Returns:**

| Name | Type | Description |
| ---- | ---- | ----------- |
| populatedTicks | struct ITickLens.PopulatedTick[] | An array of tick data for fetched ticks |

2 changes: 1 addition & 1 deletion src/core/contracts/AlgebraFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ contract AlgebraFactory is IAlgebraFactory, Ownable2Step, AccessControlEnumerabl

/// @inheritdoc IAlgebraFactory
/// @dev keccak256 of AlgebraPool init bytecode. Used to compute pool address deterministically
bytes32 public constant POOL_INIT_CODE_HASH = 0x0b1b184697cab1d9381cadf912f1418a9862246dced222beb0bdff79a50549de;
bytes32 public constant POOL_INIT_CODE_HASH = 0x46cbced75f1535f44e1566a1c1b1f28ca3b008ac868c1c2c45c1880a9586958f;

constructor(address _poolDeployer) {
require(_poolDeployer != address(0));
Expand Down
10 changes: 6 additions & 4 deletions src/core/contracts/base/TickStructure.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ abstract contract TickStructure is AlgebraPoolBase {
using TickManagement for mapping(int24 => TickManagement.Tick);
using TickTree for mapping(int16 => uint256);

uint32 internal tickTreeRoot; // The root bitmap of search tree
mapping(int16 => uint256) internal tickSecondLayer; // The second layer of search tree
/// @inheritdoc IAlgebraPoolState
uint32 public override tickTreeRoot; // The root bitmap of search tree
/// @inheritdoc IAlgebraPoolState
mapping(int16 => uint256) public override tickTreeSecondLayer; // The second layer of search tree

// the leaves of the tree are stored in `tickTable`

Expand Down Expand Up @@ -51,13 +53,13 @@ abstract contract TickStructure is AlgebraPoolBase {
if (tick > currentTick) nextInitializedTick = tick;
else prevInitializedTick = tick;
} else {
nextTick = tickTable.getNextTick(tickSecondLayer, oldTickTreeRoot, tick);
nextTick = tickTable.getNextTick(tickTreeSecondLayer, oldTickTreeRoot, tick);
prevTick = ticks[nextTick].prevTick;
}
ticks.insertTick(tick, prevTick, nextTick);
}

uint32 newTickTreeRoot = tickTable.toggleTick(tickSecondLayer, oldTickTreeRoot, tick);
uint32 newTickTreeRoot = tickTable.toggleTick(tickTreeSecondLayer, oldTickTreeRoot, tick);
return (prevInitializedTick, nextInitializedTick, newTickTreeRoot);
}

Expand Down
12 changes: 12 additions & 0 deletions src/core/contracts/interfaces/pool/IAlgebraPoolState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,16 @@ interface IAlgebraPoolState {
/// @dev **important security note: caller should check reentrancy lock to prevent read-only reentrancy**
/// @return The next initialized tick
function nextTickGlobal() external view returns (int24);

/// @notice The root of tick search tree
/// @dev Each bit corresponds to one node in the second layer of tick tree: '1' if node has at least one active bit.
/// **important security note: caller should check reentrancy lock to prevent read-only reentrancy**
/// @return The root of tick search tree as bitmap
function tickTreeRoot() external view returns (uint32);

/// @notice The second layer of tick search tree
/// @dev Each bit in node corresponds to one node in the leafs layer (`tickTable`) of tick tree: '1' if leaf has at least one active bit.
/// **important security note: caller should check reentrancy lock to prevent read-only reentrancy**
/// @return The node of tick search tree second layer
function tickTreeSecondLayer(int16) external view returns (uint256);
}
4 changes: 4 additions & 0 deletions src/core/test/AlgebraPool.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ describe('AlgebraPool', () => {
expect(await pool.isUnlocked()).to.be.true; // false checked inside of TestAlgebraReentrantCallee.sol
});

it('tickTreeRoot is clear', async () => {
expect(await pool.tickTreeRoot()).to.be.eq(0);
});

describe('#initialize', () => {
it('fails if already initialized', async () => {
await pool.initialize(encodePriceSqrt(1, 1));
Expand Down
3 changes: 2 additions & 1 deletion src/periphery/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ cache/
crytic-export/
node_modules/
typechain/
.env
.env
**/hardhat-dependency-compiler
Loading

0 comments on commit 2e1ec26

Please sign in to comment.