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/zellic gas optimization #183

Merged
merged 3 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
178189
178162
Original file line number Diff line number Diff line change
@@ -1 +1 @@
184774
184048
2 changes: 1 addition & 1 deletion .forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
311515
311216
2 changes: 1 addition & 1 deletion .forge-snapshots/BinHookTest#testSwapSucceedsWithHook.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
189692
189420
2 changes: 1 addition & 1 deletion .forge-snapshots/BinPoolManagerBytecodeSize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24173
23911
Original file line number Diff line number Diff line change
@@ -1 +1 @@
133833
133811
Original file line number Diff line number Diff line change
@@ -1 +1 @@
32518
32521
Original file line number Diff line number Diff line change
@@ -1 +1 @@
142629
142616
Original file line number Diff line number Diff line change
@@ -1 +1 @@
289662
289602
2 changes: 1 addition & 1 deletion .forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
127005
126984
Original file line number Diff line number Diff line change
@@ -1 +1 @@
970510
968494
Original file line number Diff line number Diff line change
@@ -1 +1 @@
329822
327806
Original file line number Diff line number Diff line change
@@ -1 +1 @@
337829
337530
Original file line number Diff line number Diff line change
@@ -1 +1 @@
140380
140081
Original file line number Diff line number Diff line change
@@ -1 +1 @@
173317
173046
Original file line number Diff line number Diff line change
@@ -1 +1 @@
179345
179074
Original file line number Diff line number Diff line change
@@ -1 +1 @@
133348
133077
Original file line number Diff line number Diff line change
@@ -1 +1 @@
163446
162720
Original file line number Diff line number Diff line change
@@ -1 +1 @@
304787
304488
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerBytecodeSize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
21216
20856
Original file line number Diff line number Diff line change
@@ -1 +1 @@
150173
149202
Original file line number Diff line number Diff line change
@@ -1 +1 @@
131090
130815
Original file line number Diff line number Diff line change
@@ -1 +1 @@
163667
163156
Original file line number Diff line number Diff line change
@@ -1 +1 @@
149106
148595
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#swap_simple.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
71701
71190
Original file line number Diff line number Diff line change
@@ -1 +1 @@
143343
143062
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#swap_withHooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
87879
87368
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#swap_withNative.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
71704
71193
Original file line number Diff line number Diff line change
@@ -1 +1 @@
31971
31953
7 changes: 4 additions & 3 deletions src/pool-bin/BinPoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {BinHooks} from "./libraries/BinHooks.sol";
import {PriceHelper} from "./libraries/PriceHelper.sol";
import {BeforeSwapDelta} from "../types/BeforeSwapDelta.sol";
import "./interfaces/IBinHooks.sol";
import {BinSlot0} from "./types/BinSlot0.sol";

/// @notice Holds the state for all bin pools
contract BinPoolManager is IBinPoolManager, ProtocolFees, Extsload {
Expand Down Expand Up @@ -59,9 +60,9 @@ contract BinPoolManager is IBinPoolManager, ProtocolFees, Extsload {

/// @inheritdoc IBinPoolManager
function getSlot0(PoolId id) external view override returns (uint24 activeId, uint24 protocolFee, uint24 lpFee) {
BinPool.Slot0 memory slot0 = pools[id].slot0;
BinSlot0 slot0 = pools[id].slot0;

return (slot0.activeId, slot0.protocolFee, slot0.lpFee);
return (slot0.activeId(), slot0.protocolFee(), slot0.lpFee());
}

/// @inheritdoc IBinPoolManager
Expand Down Expand Up @@ -282,7 +283,7 @@ contract BinPoolManager is IBinPoolManager, ProtocolFees, Extsload {
BinHooks.beforeDonate(key, amount0, amount1, hookData);

/// @dev Share is 1:1 liquidity when liquidity is first added to bin
uint256 currentBinShare = pool.shareOfBin[pool.slot0.activeId];
uint256 currentBinShare = pool.shareOfBin[pool.slot0.activeId()];
if (currentBinShare <= MIN_BIN_SHARE_FOR_DONATE) {
revert InsufficientBinShareForDonate(currentBinShare);
}
Expand Down
57 changes: 24 additions & 33 deletions src/pool-bin/libraries/BinPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pragma solidity ^0.8.0;

import {BalanceDelta, toBalanceDelta} from "../../types/BalanceDelta.sol";
import {BinSlot0} from "../types/BinSlot0.sol";
import {LiquidityConfigurations} from "./math/LiquidityConfigurations.sol";
import {PackedUint128Math} from "./math/PackedUint128Math.sol";
import {Uint256x256Math} from "./math/Uint256x256Math.sol";
Expand Down Expand Up @@ -48,21 +49,9 @@ library BinPool {
/// @dev if swap exactIn, x for y, unspecifiedToken = token y. if swap x for exact out y, unspecified token is x
error BinPool__InsufficientAmountUnSpecified();

struct Slot0 {
// the current activeId
uint24 activeId;
// protocol fee, expressed in hundredths of a bip
// upper 12 bits are for 1->0, and the lower 12 are for 0->1
// the maximum is 1000 - meaning the maximum protocol fee is 0.1%
// the protocolFee is taken from the input first, then the lpFee is taken from the remaining input
uint24 protocolFee;
// lp fee, either static at initialize or dynamic via hook
uint24 lpFee;
}

/// @dev The state of a pool
struct State {
Slot0 slot0;
BinSlot0 slot0;
/// @notice binId ==> (reserve of token x and y in the bin)
mapping(uint256 binId => bytes32 reserve) reserveOfBin;
/// @notice binId ==> (total share minted)
Expand All @@ -79,21 +68,21 @@ library BinPool {

function initialize(State storage self, uint24 activeId, uint24 protocolFee, uint24 lpFee) internal {
/// An initialized pool will not have activeId: 0
if (self.slot0.activeId != 0) revert PoolAlreadyInitialized();
if (self.slot0.activeId() != 0) revert PoolAlreadyInitialized();

self.slot0 = Slot0({activeId: activeId, protocolFee: protocolFee, lpFee: lpFee});
self.slot0 = BinSlot0.wrap(bytes32(0)).setActiveId(activeId).setProtocolFee(protocolFee).setLpFee(lpFee);
}

function setProtocolFee(State storage self, uint24 protocolFee) internal {
self.checkPoolInitialized();
self.slot0.protocolFee = protocolFee;
self.slot0 = self.slot0.setProtocolFee(protocolFee);
}

/// @notice Only dynamic fee pools may update the swap fee.
function setLPFee(State storage self, uint24 lpFee) internal {
self.checkPoolInitialized();

self.slot0.lpFee = lpFee;
self.slot0 = self.slot0.setLpFee(lpFee);
}

struct SwapParams {
Expand All @@ -118,17 +107,17 @@ library BinPool {
internal
returns (BalanceDelta result, SwapState memory swapState)
{
Slot0 memory slot0Cache = self.slot0;
swapState.activeId = slot0Cache.activeId;
BinSlot0 slot0Cache = self.slot0;
swapState.activeId = slot0Cache.activeId();
bool swapForY = params.swapForY;
swapState.protocolFee =
swapForY ? slot0Cache.protocolFee.getZeroForOneFee() : slot0Cache.protocolFee.getOneForZeroFee();
swapForY ? slot0Cache.protocolFee().getZeroForOneFee() : slot0Cache.protocolFee().getOneForZeroFee();
bool exactInput = params.amountSpecified < 0;

{
uint24 lpFee = params.lpFeeOverride.isOverride()
? params.lpFeeOverride.removeOverrideAndValidate(LPFeeLibrary.TEN_PERCENT_FEE)
: slot0Cache.lpFee;
: slot0Cache.lpFee();

/// @dev swap fee includes protocolFee (charged first) and lpFee
swapState.swapFee = swapState.protocolFee == 0 ? lpFee : swapState.protocolFee.calculateSwapFee(lpFee);
Expand Down Expand Up @@ -173,7 +162,7 @@ library BinPool {

if (amountsInWithFees > 0) {
/// @dev calc protocol fee for current bin, totalFee * protocolFee / (protocolFee + lpFee)
bytes32 pFee = totalFee.getProtocolFeeAmt(slot0Cache.protocolFee, swapState.swapFee);
bytes32 pFee = totalFee.getProtocolFeeAmt(slot0Cache.protocolFee(), swapState.swapFee);
if (pFee != 0) {
swapState.feeAmountToProtocol = swapState.feeAmountToProtocol.add(pFee);
amountsInWithFees = amountsInWithFees.sub(pFee);
Expand All @@ -200,7 +189,7 @@ library BinPool {

if (amountsUnspecified == 0) revert BinPool__InsufficientAmountUnSpecified();

self.slot0.activeId = swapState.activeId;
self.slot0 = self.slot0.setActiveId(swapState.activeId);
unchecked {
// uncheckeck as negating positive int128 is safe
if (exactInput) {
Expand Down Expand Up @@ -308,13 +297,14 @@ library BinPool {
returns (BalanceDelta result, uint256[] memory ids, bytes32[] memory amounts)
{
ids = params.ids;
uint256 idsLength = ids.length;
uint256[] memory amountsToBurn = params.amountsToBurn;

if (ids.length == 0 || ids.length != amountsToBurn.length) revert BinPool__InvalidBurnInput();
if (idsLength == 0 || idsLength != amountsToBurn.length) revert BinPool__InvalidBurnInput();

bytes32 amountsOut;
amounts = new bytes32[](ids.length);
for (uint256 i; i < ids.length;) {
amounts = new bytes32[](idsLength);
for (uint256 i; i < idsLength;) {
uint24 id = ids[i].safe24();
uint256 amountToBurn = amountsToBurn[i];

Expand Down Expand Up @@ -349,7 +339,7 @@ library BinPool {
internal
returns (BalanceDelta result, uint24 activeId)
{
activeId = self.slot0.activeId;
activeId = self.slot0.activeId();
bytes32 amountIn = amount0.encode(amount1);

bytes32 binReserves = self.reserveOfBin[activeId];
Expand Down Expand Up @@ -381,7 +371,8 @@ library BinPool {
bytes32 amountsInToBin;
bytes32 binFeeAmt;
bytes32 binCompositionFee;
for (uint256 i; i < params.liquidityConfigs.length;) {
uint256 liquidityConfigsLength = params.liquidityConfigs.length;
for (uint256 i; i < liquidityConfigsLength;) {
// fix stack too deep
{
bytes32 maxAmountsInToBin;
Expand Down Expand Up @@ -426,8 +417,8 @@ library BinPool {
bytes32 compositionFeeAmount
)
{
Slot0 memory slot0Cache = self.slot0;
uint24 activeId = slot0Cache.activeId;
BinSlot0 slot0Cache = self.slot0;
uint24 activeId = slot0Cache.activeId();
bytes32 binReserves = self.reserveOfBin[id];

uint256 price = id.getPriceFromId(params.binStep);
Expand All @@ -441,11 +432,11 @@ library BinPool {
/// eg. current bin is 40/60 (a,b) but user tries to add liquidity with 50/50 ratio
uint24 lpFee = params.lpFeeOverride.isOverride()
? params.lpFeeOverride.removeOverrideAndValidate(LPFeeLibrary.TEN_PERCENT_FEE)
: slot0Cache.lpFee;
: slot0Cache.lpFee();

bytes32 feesAmount;
(feesAmount, feeAmountToProtocol) =
binReserves.getCompositionFeesAmount(slot0Cache.protocolFee, lpFee, amountsIn, supply, shares);
binReserves.getCompositionFeesAmount(slot0Cache.protocolFee(), lpFee, amountsIn, supply, shares);
compositionFeeAmount = feesAmount;
if (feesAmount != 0) {
{
Expand Down Expand Up @@ -492,7 +483,7 @@ library BinPool {
}

function checkPoolInitialized(State storage self) internal view {
if (self.slot0.activeId == 0) {
if (self.slot0.activeId() == 0) {
// revert PoolNotInitialized();
assembly ("memory-safe") {
mstore(0x00, 0x486aa307)
Expand Down
Loading
Loading