Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
33c3d02
Lint
joaobrunoah Sep 11, 2025
51a467d
Fix tests with forge using contracts compiled with hardhat
joaobrunoah Sep 12, 2025
90caadc
Fix percentage setters
joaobrunoah Sep 12, 2025
955a3dc
Fix setters
joaobrunoah Sep 12, 2025
c1aeb77
Remove unnecessary structs for Add/Remove liquidity hooks
joaobrunoah Sep 12, 2025
dba482a
Improve function names
joaobrunoah Sep 12, 2025
1a69991
Refactor computeSurgeFee to remove locals struct
joaobrunoah Sep 12, 2025
2a7f724
Fix stack-too-deep
joaobrunoah Sep 13, 2025
78b058d
Fix tests - WIP
joaobrunoah Sep 13, 2025
d149b2c
Fix tests - WIP
joaobrunoah Sep 13, 2025
d9a181b
Fix test - WIP
joaobrunoah Sep 15, 2025
4b03180
Fix tests - WIP
joaobrunoah Sep 15, 2025
2aec7a9
Fix tests - WIP
joaobrunoah Sep 15, 2025
143d095
Fix tests - WIP
joaobrunoah Sep 15, 2025
3b65432
Fix tests - WIP
joaobrunoah Sep 15, 2025
998acef
Fix HyperSurgeFee tests
joaobrunoah Sep 15, 2025
4278aed
Clean test file
joaobrunoah Sep 15, 2025
5ce5a52
Fix tests
joaobrunoah Sep 16, 2025
25eb6bf
Fix stack-too-deep
joaobrunoah Sep 16, 2025
d43a44a
Fix stack-too-deep
joaobrunoah Sep 16, 2025
124b896
Fix test
joaobrunoah Sep 16, 2025
a20dbc4
Fix HyperSurgeMaxDeviation file
joaobrunoah Sep 16, 2025
18121e7
Fix test
joaobrunoah Sep 16, 2025
ae9110a
Remove check of token length (it's already checked in the vault)
joaobrunoah Sep 16, 2025
adebde4
Remove unnecessary struct
joaobrunoah Sep 16, 2025
4de2a3e
Fix function comments
joaobrunoah Sep 16, 2025
076677a
Fix PR comments
joaobrunoah Sep 16, 2025
d484ddc
Fix natspec
joaobrunoah Sep 16, 2025
82e410c
Merge pull request #65 from joaobrunoah/hyperliquid-surge-hook-review
bulkcade Sep 22, 2025
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 .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"options": {
"singleQuote": false,
"tabWidth": 4,
"compiler": "0.8.24"
"compiler": "0.8.26"
}
},
{
Expand Down
680 changes: 358 additions & 322 deletions pkg/pool-hooks/contracts/hooks-quantamm/HyperSurgeHook.sol

Large diffs are not rendered by default.

18 changes: 6 additions & 12 deletions pkg/pool-hooks/contracts/hooks-quantamm/LPNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,27 @@ pragma solidity >=0.8.24;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "./UpliftOnlyExample.sol";

/**
/**
* @notice This contract is a simple ERC721 contract for LP NFTs. It overrides update which means
* that the deposits can be transferred feely between users.
* this does require the router to change the vault balances and deposit records as well
*/

/// @title LPNFT contract for QuantAMM LP NFTs
/// @notice implements ERC721 for LP NFTs
/// @title LPNFT contract for QuantAMM LP NFTs
/// @notice implements ERC721 for LP NFTs
contract LPNFT is ERC721 {

uint256 numMinted;

/// @notice the address of the QuantAMM router this token is for
UpliftOnlyExample public router;

/// @notice Modifier for only allowing the router to call certain functions
modifier onlyUpliftOnlyRouter() {
require(msg.sender == address(router), "ROUTERONLY");
require(msg.sender == address(router), "ROUTERONLY");
_;
}


constructor(
string memory _name,
string memory _symbol,
address _router
) ERC721(_name, _symbol) {
constructor(string memory _name, string memory _symbol, address _router) ERC721(_name, _symbol) {
router = UpliftOnlyExample(payable(_router));
}

Expand All @@ -47,7 +41,7 @@ contract LPNFT is ERC721 {

/// @inheritdoc ERC721
function _update(address to, uint256 tokenId, address auth) internal override returns (address previousOwner) {
previousOwner = super._update(to, tokenId, auth);
previousOwner = super._update(to, tokenId, auth);
//_update is called during mint, burn and transfer. This functionality is only for transfer
if (to != address(0) && previousOwner != address(0)) {
//if transfering the record in the vault needs to be changed to reflect the change in ownership
Expand Down
3 changes: 2 additions & 1 deletion pkg/pool-hooks/contracts/test/HardhatImports.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import { RateProviderMock } from "@balancer-labs/v3-vault/contracts/test/RatePro

import { WETHTestToken } from "@balancer-labs/v3-solidity-utils/contracts/test/WETHTestToken.sol";

import { WeightedPool } from "@balancer-labs/v3-pool-weighted/contracts/WeightedPool.sol";
import { WeightedPoolFactory } from "@balancer-labs/v3-pool-weighted/contracts/WeightedPoolFactory.sol";
import { WeightedPoolMock } from "@balancer-labs/v3-pool-weighted/contracts/test/WeightedPoolMock.sol";
import { WeightedPool } from "@balancer-labs/v3-pool-weighted/contracts/WeightedPool.sol";

import { StablePool } from "@balancer-labs/v3-pool-stable/contracts/StablePool.sol";
import { StablePoolFactory } from "@balancer-labs/v3-pool-stable/contracts/StablePoolFactory.sol";
21 changes: 12 additions & 9 deletions pkg/pool-hooks/contracts/test/HyperSurgeHookMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ contract HyperSurgeHookMock is HyperSurgeHook {
}

function PairSpotFromBalancesWeights(
uint256 bIn,
uint256 wIn,
uint256 bOut,
uint256 wOut
uint256[] memory balancesScaled18,
uint256[] memory weights,
uint256 indexTokenIn,
uint256 indexTokenOut
) external pure returns (uint256) {
return _pairSpotFromBalancesWeights(bIn, wIn, bOut, wOut);
return _pairSpotFromBalancesWeights(balancesScaled18, weights, indexTokenIn, indexTokenOut);
}

function RelAbsDiff(uint256 a, uint256 b) external pure returns (uint256) {
Expand All @@ -51,14 +51,17 @@ contract HyperSurgeHookMock is HyperSurgeHook {
}

function EnsureValidPct(uint256 pct) external pure {
_ensureValidPct(pct);
_ensureValidPercentage(pct);
}

function ComputeSurgeFee(
ComputeSurgeFeeLocals memory locals,
PoolSwapParams calldata p,
uint256 staticSwapFee
PoolDetails memory poolDetails,
uint256 staticSwapFee,
uint256[] memory weights,
uint256 calculatedAmountScaled18,
uint256 oraclePrice
) external pure returns (bool ok, uint256 surgeFee) {
return _computeSurgeFee(locals, p, staticSwapFee);
return _computeSurgeFee(p, poolDetails, staticSwapFee, weights, calculatedAmountScaled18, oraclePrice);
}
}
64 changes: 0 additions & 64 deletions pkg/pool-hooks/test/foundry/HyperSurgeAdmin.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -999,70 +999,6 @@ contract HyperSurgeAdminTest is BaseVaultTest, HyperSurgeHookDeployer, WeightedP
assertEq(hook.getCapDeviationPercentage(address(pool), IHyperSurgeHook.TradeType.ARBITRAGE), 1e18);
}

function testFuzz_onRegister_RevertWhenTokenCountBelowTwo(
uint8 n,
uint256 defaultThreshold,
uint256 defaultMaxFee,
uint256 defaultCap
) public {
n = uint8(bound(n, 0, 1));
defaultThreshold = bound(defaultThreshold, 1, 1e9 - 1);
defaultCap = bound(defaultCap, defaultThreshold + 1, 1e9);
defaultMaxFee = bound(defaultMaxFee, 1, 1e9);

defaultThreshold *= 1e9;
defaultCap *= 1e9;
defaultMaxFee *= 1e9;

HyperSurgeHookMock h = new HyperSurgeHookMock(
IVault(vault),
defaultMaxFee,
defaultThreshold,
defaultCap,
"test"
);

TokenConfig[] memory cfgs = new TokenConfig[](n);
LiquidityManagement memory lm;

vm.startPrank(address(vault));
vm.expectRevert(HyperSurgeHook.NumTokensOutOfRange.selector);
h.onRegister(address(0), address(0), cfgs, lm);
vm.stopPrank();
}

function testFuzz_onRegister_RevertWhenTokenCountAboveEight(
uint256 n,
uint256 defaultThreshold,
uint256 defaultMaxFee,
uint256 defaultCap
) public {
n = bound(n, 9, type(uint8).max);
defaultThreshold = bound(defaultThreshold, 1, 1e9 - 1);
defaultCap = bound(defaultCap, defaultThreshold + 1, 1e9);
defaultMaxFee = bound(defaultMaxFee, 1, 1e9);

defaultThreshold *= 1e9;
defaultCap *= 1e9;
defaultMaxFee *= 1e9;

HyperSurgeHookMock h = new HyperSurgeHookMock(
IVault(vault),
defaultMaxFee,
defaultThreshold,
defaultCap,
"test"
);

TokenConfig[] memory cfgs = new TokenConfig[](n);
LiquidityManagement memory lm;

vm.startPrank(address(vault));
vm.expectRevert(HyperSurgeHook.NumTokensOutOfRange.selector);
h.onRegister(address(0), address(0), cfgs, lm);
vm.stopPrank();
}

function test_getHookFlags_SignalsAreSet(
uint256 defaultThreshold,
uint256 defaultMaxFee,
Expand Down
Loading
Loading