refactor: Complete project renaming from HARB/Harberger to KRAIKEN

- Updated all production code references from 'harb' to 'kraiken'
- Changed 'Harberger tax' references to 'self-assessed tax'
- Updated function names (_getHarbToken -> _getKraikenToken)
- Modified documentation and comments to reflect new branding
- Updated token symbol from HARB to KRAIKEN in tests
- Maintained backward compatibility with test variable names

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
johba 2025-08-19 11:05:08 +02:00
parent 7eef96f366
commit 400ab325ed
11 changed files with 66 additions and 66 deletions

View file

@ -4,7 +4,7 @@ Core KRAIKEN protocol contracts implementing the dominant liquidity manager stra
## Core Contracts ## Core Contracts
**Kraiken.sol** - ERC20 with Harberger staking **Kraiken.sol** - ERC20 with self-assessed tax staking
- `outstandingSupply()` = totalSupply - liquidityManager balance - `outstandingSupply()` = totalSupply - liquidityManager balance
- Proportional staking pool growth/shrink on mint/burn - Proportional staking pool growth/shrink on mint/burn
- 20% supply cap (20k positions max) - 20% supply cap (20k positions max)
@ -26,7 +26,7 @@ Core KRAIKEN protocol contracts implementing the dominant liquidity manager stra
- Returns 4 params for position adjustment - Returns 4 params for position adjustment
- Upgradeable for new strategies - Upgradeable for new strategies
**Stake.sol** - Harberger tax **Stake.sol** - Self-assessed tax system
- Self-assessed valuations - Self-assessed valuations
- Continuous auction mechanism - Continuous auction mechanism
@ -36,7 +36,6 @@ Core KRAIKEN protocol contracts implementing the dominant liquidity manager stra
When `token0isWeth = true`: When `token0isWeth = true`:
- Amount0 functions return **ETH** amounts - Amount0 functions return **ETH** amounts
- Amount1 functions return **KRAIKEN** amounts - Amount1 functions return **KRAIKEN** amounts
- Discovery position must use `getAmount1ForLiquidity()` for KRAIKEN
### Outstanding Supply ### Outstanding Supply
Excludes tokens used for liquidity positions: Excludes tokens used for liquidity positions:
@ -59,11 +58,11 @@ uint256 requiredEth = outstandingSupply.mulDiv(sqrtVwapX96, 1 << 96);
- 100% = KRAIKEN valued at 170% for reserves - 100% = KRAIKEN valued at 170% for reserves
2. **anchorShare** (0-1e18) 2. **anchorShare** (0-1e18)
- Floor ETH = totalETH × (1 - anchorShare)² - 0 anchorShare = 5% of ETH in anchor
- 95% anchorShare = 90.1% floor allocation - 1e18 anchorShare = 25% of ETH in anchor
3. **anchorWidth** (0-100) 3. **anchorWidth** (0-100)
- % of current price for anchor range - token width of the anchor position, for now we keep it an 50
4. **discoveryDepth** (0-1e18) 4. **discoveryDepth** (0-1e18)
- 2x-10x liquidity multiplier vs anchor - 2x-10x liquidity multiplier vs anchor
@ -147,4 +146,5 @@ forge test --mc Test # Match contract
- `test/helpers/UniswapTestBase.sol` - Pool setup - `test/helpers/UniswapTestBase.sol` - Pool setup
- `test/helpers/KraikenTestBase.sol` - Common utils - `test/helpers/KraikenTestBase.sol` - Common utils
- `lib/uni-v3-lib/` - Uniswap V3 math - `lib/uni-v3-lib/` - Uniswap V3 math
- [UNISWAP_V3_MATH.md](UNISWAP_V3_MATH.md) - Math reference - [UNISWAP_V3_MATH.md](UNISWAP_V3_MATH.md) - Math reference
- IMPORTANT: do not modify implementation files like LiquidityProvider or ThreePositionStrategy

View file

@ -66,7 +66,7 @@ forge script script/BaseSepoliaDeploy.sol:BaseSepoliaDeploy --slow --broadcast -
if verification fails: if verification fails:
```shell ```shell
forge verify-contract --watch --chain sepolia --constructor-args $(cast abi-encode "constructor(string,string,address,address,address)" "Harberger Tax" "HARB" "0x0227628f3F023bb0B980b67D528571c95c6DaC1c" "0xb16F35c0Ae2912430DAc15764477E179D9B9EbEa" "0x64dda11815b883c589afed914666ef2d63c8c338") 0x7517db0f2b24223f2f0e3567149ca180e204da8a Harb forge verify-contract --watch --chain sepolia --constructor-args $(cast abi-encode "constructor(string,string,address,address,address)" "Kraiken" "KRAIKEN" "0x0227628f3F023bb0B980b67D528571c95c6DaC1c" "0xb16F35c0Ae2912430DAc15764477E179D9B9EbEa" "0x64dda11815b883c589afed914666ef2d63c8c338") 0x7517db0f2b24223f2f0e3567149ca180e204da8a Kraiken
forge verify-contract --watch --chain sepolia --constructor-args $(cast abi-encode "constructor(address)" "0x7517db0f2b24223f2f0e3567149ca180e204da8a") 0x00b4d656b8182d0c2f4841b7a6f1429b94f73a66 Stake forge verify-contract --watch --chain sepolia --constructor-args $(cast abi-encode "constructor(address)" "0x7517db0f2b24223f2f0e3567149ca180e204da8a") 0x00b4d656b8182d0c2f4841b7a6f1429b94f73a66 Stake
``` ```
@ -94,7 +94,7 @@ $ cast --help
address: 0xf6a3eef9088A255c32b6aD2025f83E57291D9011 address: 0xf6a3eef9088A255c32b6aD2025f83E57291D9011
### Harberg ### Kraiken
address: 0x22c264Ecf8D4E49D1E3CabD8DD39b7C4Ab51C1B8 address: 0x22c264Ecf8D4E49D1E3CabD8DD39b7C4Ab51C1B8
@ -109,7 +109,7 @@ address: 0x3d6a8797693a0bC598210782B6a889E11A2340Cd
## Deployment on Base ## Deployment on Base
### Harberg ### Kraiken
address: 0x45caa5929f6ee038039984205bdecf968b954820 address: 0x45caa5929f6ee038039984205bdecf968b954820

View file

@ -6,7 +6,7 @@ A static liquidity provider strategy in a dynamic market leads to:
- impermanent loss - impermanent loss
- reduced earnings - reduced earnings
Harbergs baseline-like liquidity setup can reduce impermanent loss only at the cost of liquidity share and fee earnings. Token-printing-priviliges gives unfair advantage, but not forever. Kraiken's baseline-like liquidity setup can reduce impermanent loss only at the cost of liquidity share and fee earnings. Token-printing-priviliges gives unfair advantage, but not forever.
## Succesfull/Dynamic LP strategies use indicators: ## Succesfull/Dynamic LP strategies use indicators:
onchain: onchain:
@ -19,7 +19,7 @@ offchain:
- Macro - Macro
- Sentiment - Sentiment
## Making the Harberg LP strategy dynamic ## Making the Kraiken LP strategy dynamic
- **Oracle Problem \#1:** The offchain indicators can not be used by decentralized communities at all, having a unsolved oracle trust issue. - **Oracle Problem \#1:** The offchain indicators can not be used by decentralized communities at all, having a unsolved oracle trust issue.
- use staking, an egoistic marketplace, as data source for sentiment - use staking, an egoistic marketplace, as data source for sentiment

View file

@ -34,7 +34,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
/// @notice Immutable contract references /// @notice Immutable contract references
address private immutable factory; address private immutable factory;
IWETH9 private immutable weth; IWETH9 private immutable weth;
Kraiken private immutable harb; Kraiken private immutable kraiken;
Optimizer private immutable optimizer; Optimizer private immutable optimizer;
IUniswapV3Pool private immutable pool; IUniswapV3Pool private immutable pool;
bool private immutable token0isWeth; bool private immutable token0isWeth;
@ -57,15 +57,15 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
/// @notice Constructor initializes all contract references and pool configuration /// @notice Constructor initializes all contract references and pool configuration
/// @param _factory The address of the Uniswap V3 factory /// @param _factory The address of the Uniswap V3 factory
/// @param _WETH9 The address of the WETH contract /// @param _WETH9 The address of the WETH contract
/// @param _harb The address of the Kraiken token contract /// @param _kraiken The address of the Kraiken token contract
/// @param _optimizer The address of the optimizer contract /// @param _optimizer The address of the optimizer contract
constructor(address _factory, address _WETH9, address _harb, address _optimizer) { constructor(address _factory, address _WETH9, address _kraiken, address _optimizer) {
factory = _factory; factory = _factory;
weth = IWETH9(_WETH9); weth = IWETH9(_WETH9);
poolKey = PoolAddress.getPoolKey(_WETH9, _harb, FEE); poolKey = PoolAddress.getPoolKey(_WETH9, _kraiken, FEE);
pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey));
harb = Kraiken(_harb); kraiken = Kraiken(_kraiken);
token0isWeth = _WETH9 < _harb; token0isWeth = _WETH9 < _kraiken;
optimizer = Optimizer(_optimizer); optimizer = Optimizer(_optimizer);
} }
@ -75,9 +75,9 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
function uniswapV3MintCallback(uint256 amount0Owed, uint256 amount1Owed, bytes calldata) external { function uniswapV3MintCallback(uint256 amount0Owed, uint256 amount1Owed, bytes calldata) external {
CallbackValidation.verifyCallback(factory, poolKey); CallbackValidation.verifyCallback(factory, poolKey);
// Handle HARB minting // Handle KRAIKEN minting
uint256 harbPulled = token0isWeth ? amount1Owed : amount0Owed; uint256 kraikenPulled = token0isWeth ? amount1Owed : amount0Owed;
harb.mint(harbPulled); kraiken.mint(kraikenPulled);
// Handle WETH conversion // Handle WETH conversion
uint256 ethOwed = token0isWeth ? amount0Owed : amount1Owed; uint256 ethOwed = token0isWeth ? amount0Owed : amount1Owed;
@ -138,7 +138,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
// Update total supply tracking if price moved up // Update total supply tracking if price moved up
if (isUp) { if (isUp) {
harb.setPreviousTotalSupply(harb.totalSupply()); kraiken.setPreviousTotalSupply(kraiken.totalSupply());
} }
// Get optimizer parameters and set new positions // Get optimizer parameters and set new positions
@ -212,21 +212,21 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
IERC20(address(weth)).transfer(feeDestination, fee0); IERC20(address(weth)).transfer(feeDestination, fee0);
_recordVolumeAndPrice(currentPrice, fee0); _recordVolumeAndPrice(currentPrice, fee0);
} else { } else {
IERC20(address(harb)).transfer(feeDestination, fee0); IERC20(address(kraiken)).transfer(feeDestination, fee0);
} }
} }
if (fee1 > 0) { if (fee1 > 0) {
if (token0isWeth) { if (token0isWeth) {
IERC20(address(harb)).transfer(feeDestination, fee1); IERC20(address(kraiken)).transfer(feeDestination, fee1);
} else { } else {
IERC20(address(weth)).transfer(feeDestination, fee1); IERC20(address(weth)).transfer(feeDestination, fee1);
_recordVolumeAndPrice(currentPrice, fee1); _recordVolumeAndPrice(currentPrice, fee1);
} }
} }
// Burn any remaining HARB tokens // Burn any remaining KRAIKEN tokens
harb.burn(harb.balanceOf(address(this))); kraiken.burn(kraiken.balanceOf(address(this)));
} }
/// @notice Allow contract to receive ETH /// @notice Allow contract to receive ETH
@ -242,8 +242,8 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
} }
/// @notice Implementation of abstract function from ThreePositionStrategy /// @notice Implementation of abstract function from ThreePositionStrategy
function _getHarbToken() internal view override returns (address) { function _getKraikenToken() internal view override returns (address) {
return address(harb); return address(kraiken);
} }
/// @notice Implementation of abstract function from ThreePositionStrategy /// @notice Implementation of abstract function from ThreePositionStrategy
@ -273,6 +273,6 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
/// @notice Implementation of abstract function from ThreePositionStrategy /// @notice Implementation of abstract function from ThreePositionStrategy
function _getOutstandingSupply() internal view override returns (uint256) { function _getOutstandingSupply() internal view override returns (uint256) {
return harb.outstandingSupply(); return kraiken.outstandingSupply();
} }
} }

View file

@ -22,7 +22,7 @@ import {Initializable} from "@openzeppelin/proxy/utils/Initializable.sol";
* - Upgradeable for future algorithm improvements * - Upgradeable for future algorithm improvements
*/ */
contract Optimizer is Initializable, UUPSUpgradeable { contract Optimizer is Initializable, UUPSUpgradeable {
Kraiken private harberg; Kraiken private kraiken;
Stake private stake; Stake private stake;
/// @dev Reverts if the caller is not the admin. /// @dev Reverts if the caller is not the admin.
@ -30,13 +30,13 @@ contract Optimizer is Initializable, UUPSUpgradeable {
/** /**
* @notice Initialize the Optimizer. * @notice Initialize the Optimizer.
* @param _harberg The address of the Kraiken token. * @param _kraiken The address of the Kraiken token.
* @param _stake The address of the Stake contract. * @param _stake The address of the Stake contract.
*/ */
function initialize(address _harberg, address _stake) public initializer { function initialize(address _kraiken, address _stake) public initializer {
// Set the admin for upgradeability (using ERC1967Upgrade _changeAdmin) // Set the admin for upgradeability (using ERC1967Upgrade _changeAdmin)
_changeAdmin(msg.sender); _changeAdmin(msg.sender);
harberg = Kraiken(_harberg); kraiken = Kraiken(_kraiken);
stake = Stake(_stake); stake = Stake(_stake);
} }

View file

@ -27,7 +27,7 @@ error TooMuchSnatch(address receiver, uint256 stakeWanted, uint256 availableStak
* Tax rates and staking positions are adjustable, with a mechanism to prevent snatch-grieving by * Tax rates and staking positions are adjustable, with a mechanism to prevent snatch-grieving by
* enforcing a minimum tax payment duration. * enforcing a minimum tax payment duration.
* *
* @dev Harberger tax implementation: * @dev Self-assessed tax implementation:
* - Continuous auction mechanism * - Continuous auction mechanism
* - Self-assessed valuations create prediction market * - Self-assessed valuations create prediction market
* - Tax collection and redistribution through UBI * - Tax collection and redistribution through UBI
@ -169,7 +169,7 @@ contract Stake {
SafeERC20.safeTransfer(kraiken, taxReceiver, taxAmountDue); SafeERC20.safeTransfer(kraiken, taxReceiver, taxAmountDue);
} }
/// @dev Internal function to close a staking position, transferring the remaining Harberg tokens back to the owner after tax payment. /// @dev Internal function to close a staking position, transferring the remaining Kraiken tokens back to the owner after tax payment.
function _exitPosition(uint256 positionId, StakingPosition storage pos) private { function _exitPosition(uint256 positionId, StakingPosition storage pos) private {
totalSharesAtTaxRate[pos.taxRate] -= pos.share; totalSharesAtTaxRate[pos.taxRate] -= pos.share;
outstandingStake -= pos.share; outstandingStake -= pos.share;
@ -182,7 +182,7 @@ contract Stake {
SafeERC20.safeTransfer(kraiken, owner, assets); SafeERC20.safeTransfer(kraiken, owner, assets);
} }
/// @dev Internal function to reduce the size of a staking position by a specified number of shares, transferring the corresponding Harberg tokens to the owner. /// @dev Internal function to reduce the size of a staking position by a specified number of shares, transferring the corresponding Kraiken tokens to the owner.
function _shrinkPosition(uint256 positionId, StakingPosition storage pos, uint256 sharesToTake) private { function _shrinkPosition(uint256 positionId, StakingPosition storage pos, uint256 sharesToTake) private {
require(sharesToTake < pos.share, "position too small"); require(sharesToTake < pos.share, "position too small");
uint256 assets = sharesToAssets(sharesToTake); uint256 assets = sharesToAssets(sharesToTake);
@ -193,22 +193,22 @@ contract Stake {
SafeERC20.safeTransfer(kraiken, pos.owner, assets); SafeERC20.safeTransfer(kraiken, pos.owner, assets);
} }
/// @notice Converts Harberg token assets to shares of the total staking pool. /// @notice Converts Kraiken token assets to shares of the total staking pool.
/// @param assets Number of Harberg tokens to convert. /// @param assets Number of Kraiken tokens to convert.
/// @return Number of shares corresponding to the input assets based on the current total supply of Harberg tokens. /// @return Number of shares corresponding to the input assets based on the current total supply of Kraiken tokens.
function assetsToShares(uint256 assets) public view returns (uint256) { function assetsToShares(uint256 assets) public view returns (uint256) {
return assets.mulDiv(totalSupply, kraiken.totalSupply(), Math.Rounding.Down); return assets.mulDiv(totalSupply, kraiken.totalSupply(), Math.Rounding.Down);
} }
/// @notice Converts shares of the total staking pool back to Harberg token assets. /// @notice Converts shares of the total staking pool back to Kraiken token assets.
/// @param shares Number of shares to convert. /// @param shares Number of shares to convert.
/// @return The equivalent number of Harberg tokens for the given shares. /// @return The equivalent number of Kraiken tokens for the given shares.
function sharesToAssets(uint256 shares) public view returns (uint256) { function sharesToAssets(uint256 shares) public view returns (uint256) {
return shares.mulDiv(kraiken.totalSupply(), totalSupply, Math.Rounding.Down); return shares.mulDiv(kraiken.totalSupply(), totalSupply, Math.Rounding.Down);
} }
/// @notice Creates a new staking position by potentially snatching shares from existing positions. /// @notice Creates a new staking position by potentially snatching shares from existing positions.
/// @param assets Amount of Harberg tokens to convert into a staking position. /// @param assets Amount of Kraiken tokens to convert into a staking position.
/// @param receiver Address that will own the new staking position. /// @param receiver Address that will own the new staking position.
/// @param taxRate The initial tax rate for the new staking position. /// @param taxRate The initial tax rate for the new staking position.
/// @param positionsToSnatch Array of position IDs that the new position will replace by snatching. /// @param positionsToSnatch Array of position IDs that the new position will replace by snatching.
@ -309,7 +309,7 @@ contract Stake {
} }
/// @notice Combines an ERC20 permit operation with the snatch function, allowing a staking position creation in one transaction. /// @notice Combines an ERC20 permit operation with the snatch function, allowing a staking position creation in one transaction.
/// @param assets Number of Harberg tokens to stake. /// @param assets Number of Kraiken tokens to stake.
/// @param receiver Address that will own the new staking position. /// @param receiver Address that will own the new staking position.
/// @param taxRate The initial tax rate for the new staking position. /// @param taxRate The initial tax rate for the new staking position.
/// @param positionsToSnatch Array of position IDs that the new position will replace by snatching. /// @param positionsToSnatch Array of position IDs that the new position will replace by snatching.
@ -411,8 +411,8 @@ contract Stake {
} }
} }
/// @notice Computes the percentage of Harberg staked from outstanding Stake and authorized Stake. /// @notice Computes the percentage of Kraiken staked from outstanding Stake and authorized Stake.
/// @return percentageStaked A number between 0 and 1e18 indicating the percentage of Harberg supply staked. /// @return percentageStaked A number between 0 and 1e18 indicating the percentage of Kraiken supply staked.
function getPercentageStaked() external view returns (uint256 percentageStaked) { function getPercentageStaked() external view returns (uint256 percentageStaked) {
percentageStaked = (outstandingStake * 1e18) / authorizedStake(); percentageStaked = (outstandingStake * 1e18) / authorizedStake();
} }

View file

@ -61,7 +61,7 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
event EthAbundance(int24 currentTick, uint256 ethBalance, uint256 outstandingSupply, uint256 vwap, int24 vwapTick); event EthAbundance(int24 currentTick, uint256 ethBalance, uint256 outstandingSupply, uint256 vwap, int24 vwapTick);
/// @notice Abstract functions that must be implemented by inheriting contracts /// @notice Abstract functions that must be implemented by inheriting contracts
function _getHarbToken() internal view virtual returns (address); function _getKraikenToken() internal view virtual returns (address);
function _getWethToken() internal view virtual returns (address); function _getWethToken() internal view virtual returns (address);
function _isToken0Weth() internal view virtual returns (bool); function _isToken0Weth() internal view virtual returns (bool);
function _mintPosition(Stage stage, int24 tickLower, int24 tickUpper, uint128 liquidity) internal virtual; function _mintPosition(Stage stage, int24 tickLower, int24 tickUpper, uint128 liquidity) internal virtual;
@ -78,26 +78,26 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
uint256 floorEthBalance = (19 * ethBalance / 20) - (2 * params.anchorShare * ethBalance / 10 ** 19); uint256 floorEthBalance = (19 * ethBalance / 20) - (2 * params.anchorShare * ethBalance / 10 ** 19);
// Step 1: Set ANCHOR position (shallow liquidity for fast price movement) // Step 1: Set ANCHOR position (shallow liquidity for fast price movement)
(uint256 pulledHarb, uint128 anchorLiquidity) = _setAnchorPosition(currentTick, ethBalance - floorEthBalance, params); (uint256 pulledKraiken, uint128 anchorLiquidity) = _setAnchorPosition(currentTick, ethBalance - floorEthBalance, params);
// Step 2: Set DISCOVERY position (depends on anchor's liquidity) // Step 2: Set DISCOVERY position (depends on anchor's liquidity)
uint256 discoveryAmount = _setDiscoveryPosition(currentTick, anchorLiquidity, params); uint256 discoveryAmount = _setDiscoveryPosition(currentTick, anchorLiquidity, params);
// Step 3: Set FLOOR position (deep liquidity, uses VWAP for historical memory) // Step 3: Set FLOOR position (deep liquidity, uses VWAP for historical memory)
_setFloorPosition(currentTick, floorEthBalance, pulledHarb, discoveryAmount, params); _setFloorPosition(currentTick, floorEthBalance, pulledKraiken, discoveryAmount, params);
} }
/// @notice Sets the anchor position around current price (shallow liquidity) /// @notice Sets the anchor position around current price (shallow liquidity)
/// @param currentTick Current market tick /// @param currentTick Current market tick
/// @param anchorEthBalance ETH allocated to anchor position /// @param anchorEthBalance ETH allocated to anchor position
/// @param params Position parameters /// @param params Position parameters
/// @return pulledHarb Amount of HARB pulled for this position /// @return pulledKraiken Amount of KRAIKEN pulled for this position
/// @return anchorLiquidity The liquidity amount for the anchor position /// @return anchorLiquidity The liquidity amount for the anchor position
function _setAnchorPosition( function _setAnchorPosition(
int24 currentTick, int24 currentTick,
uint256 anchorEthBalance, uint256 anchorEthBalance,
PositionParams memory params PositionParams memory params
) internal returns (uint256 pulledHarb, uint128 anchorLiquidity) { ) internal returns (uint256 pulledKraiken, uint128 anchorLiquidity) {
// Enforce anchor range of 1% to 100% of the price // Enforce anchor range of 1% to 100% of the price
int24 anchorSpacing = TICK_SPACING + (34 * int24(params.anchorWidth) * TICK_SPACING / 100); int24 anchorSpacing = TICK_SPACING + (34 * int24(params.anchorWidth) * TICK_SPACING / 100);
@ -112,10 +112,10 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
if (token0isWeth) { if (token0isWeth) {
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, anchorEthBalance); anchorLiquidity = LiquidityAmounts.getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, anchorEthBalance);
pulledHarb = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, anchorLiquidity); pulledKraiken = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, anchorLiquidity);
} else { } else {
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, anchorEthBalance); anchorLiquidity = LiquidityAmounts.getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, anchorEthBalance);
pulledHarb = LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, anchorLiquidity); pulledKraiken = LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, anchorLiquidity);
} }
_mintPosition(Stage.ANCHOR, tickLower, tickUpper, anchorLiquidity); _mintPosition(Stage.ANCHOR, tickLower, tickUpper, anchorLiquidity);
@ -125,7 +125,7 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
/// @param currentTick Current market tick (normalized to tick spacing) /// @param currentTick Current market tick (normalized to tick spacing)
/// @param anchorLiquidity Liquidity amount from anchor position /// @param anchorLiquidity Liquidity amount from anchor position
/// @param params Position parameters /// @param params Position parameters
/// @return discoveryAmount Amount of HARB used for discovery /// @return discoveryAmount Amount of KRAIKEN used for discovery
function _setDiscoveryPosition( function _setDiscoveryPosition(
int24 currentTick, int24 currentTick,
uint128 anchorLiquidity, uint128 anchorLiquidity,
@ -179,13 +179,13 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
/// Extreme floor positions are CORRECT behavior protecting protocol solvency /// Extreme floor positions are CORRECT behavior protecting protocol solvency
/// @param currentTick Current market tick /// @param currentTick Current market tick
/// @param floorEthBalance ETH allocated to floor position (75% of total) /// @param floorEthBalance ETH allocated to floor position (75% of total)
/// @param pulledHarb HARB amount from anchor position /// @param pulledKraiken KRAIKEN amount from anchor position
/// @param discoveryAmount HARB amount from discovery position /// @param discoveryAmount KRAIKEN amount from discovery position
/// @param params Position parameters including capital inefficiency /// @param params Position parameters including capital inefficiency
function _setFloorPosition( function _setFloorPosition(
int24 currentTick, int24 currentTick,
uint256 floorEthBalance, uint256 floorEthBalance,
uint256 pulledHarb, uint256 pulledKraiken,
uint256 discoveryAmount, uint256 discoveryAmount,
PositionParams memory params PositionParams memory params
) internal { ) internal {
@ -193,7 +193,7 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
// Calculate outstanding supply after position minting // Calculate outstanding supply after position minting
uint256 outstandingSupply = _getOutstandingSupply(); uint256 outstandingSupply = _getOutstandingSupply();
outstandingSupply -= pulledHarb; outstandingSupply -= pulledKraiken;
outstandingSupply -= (outstandingSupply >= discoveryAmount) ? discoveryAmount : outstandingSupply; outstandingSupply -= (outstandingSupply >= discoveryAmount) ? discoveryAmount : outstandingSupply;
// Use VWAP for floor position (historical price memory for dormant whale protection) // Use VWAP for floor position (historical price memory for dormant whale protection)

View file

@ -13,20 +13,20 @@ import {ABDKMath64x64} from "@abdk/ABDKMath64x64.sol";
abstract contract UniswapMath { abstract contract UniswapMath {
using Math for uint256; using Math for uint256;
/// @notice Calculates the Uniswap V3 tick corresponding to a given price ratio between Harberg and ETH /// @notice Calculates the Uniswap V3 tick corresponding to a given price ratio between Kraiken and ETH
/// @param t0isWeth Boolean flag indicating if token0 is WETH /// @param t0isWeth Boolean flag indicating if token0 is WETH
/// @param tokenAmount Amount of the Harberg token /// @param tokenAmount Amount of the Kraiken token
/// @param ethAmount Amount of Ethereum /// @param ethAmount Amount of Ethereum
/// @return tick_ The calculated tick for the given price ratio /// @return tick_ The calculated tick for the given price ratio
function _tickAtPrice(bool t0isWeth, uint256 tokenAmount, uint256 ethAmount) internal pure returns (int24 tick_) { function _tickAtPrice(bool t0isWeth, uint256 tokenAmount, uint256 ethAmount) internal pure returns (int24 tick_) {
require(ethAmount > 0, "ETH amount cannot be zero"); require(ethAmount > 0, "ETH amount cannot be zero");
if (tokenAmount == 0) { if (tokenAmount == 0) {
// HARB/ETH // KRAIKEN/ETH
tick_ = TickMath.MAX_TICK; tick_ = TickMath.MAX_TICK;
} else { } else {
// Use ABDKMath64x64 for precise division and square root calculation // Use ABDKMath64x64 for precise division and square root calculation
int128 priceRatioX64 = ABDKMath64x64.div(int128(int256(tokenAmount)), int128(int256(ethAmount))); int128 priceRatioX64 = ABDKMath64x64.div(int128(int256(tokenAmount)), int128(int256(ethAmount)));
// HARB/ETH // KRAIKEN/ETH
tick_ = _tickAtPriceRatio(priceRatioX64); tick_ = _tickAtPriceRatio(priceRatioX64);
} }
// convert to tick in a pool // convert to tick in a pool
@ -42,7 +42,7 @@ abstract contract UniswapMath {
tick_ = TickMath.getTickAtSqrtRatio(sqrtPriceX96); tick_ = TickMath.getTickAtSqrtRatio(sqrtPriceX96);
} }
/// @notice Calculates the price ratio from a given Uniswap V3 tick as HARB/ETH /// @notice Calculates the price ratio from a given Uniswap V3 tick as KRAIKEN/ETH
/// @dev IMPORTANT: Returns price² (squared price) in X96 format, NOT regular price /// @dev IMPORTANT: Returns price² (squared price) in X96 format, NOT regular price
/// This is intentional for capital requirement calculations /// This is intentional for capital requirement calculations
/// To get regular price: sqrt(priceRatioX96) * 2^48 /// To get regular price: sqrt(priceRatioX96) * 2^48

View file

@ -96,7 +96,7 @@ contract MockThreePositionStrategy is ThreePositionStrategy {
} }
// Implementation of abstract functions // Implementation of abstract functions
function _getHarbToken() internal view override returns (address) { function _getKraikenToken() internal view override returns (address) {
return harbToken; return harbToken;
} }

View file

@ -145,7 +145,7 @@ contract TestEnvironment is TestConstants {
} }
weth = IWETH9(address(new WETH())); weth = IWETH9(address(new WETH()));
harberg = new Kraiken("KRAIKEN", "HARB"); harberg = new Kraiken("KRAIKEN", "KRAIKEN");
// Check if the setup meets the required condition // Check if the setup meets the required condition
if (token0shouldBeWeth == (address(weth) < address(harberg))) { if (token0shouldBeWeth == (address(weth) < address(harberg))) {

View file

@ -54,8 +54,8 @@
## Recent Completion ## Recent Completion
**Break down testDoubleOverflowRealisticScenario()** - Successfully split into 3 focused tests with proper assertions: **Break down testDoubleOverflowRealisticScenario()** - Successfully split into 3 focused tests with proper assertions:
- `testDoubleOverflowExtremeEthPriceScenario()` - ETH at $1M, HARB at $1 - `testDoubleOverflowExtremeEthPriceScenario()` - ETH at $1M, KRAIKEN at $1
- `testDoubleOverflowHyperinflatedHarbScenario()` - HARB at $1M, ETH at $3k - `testDoubleOverflowHyperinflatedHarbScenario()` - KRAIKEN at $1M, ETH at $3k
- `testDoubleOverflowMaximumTransactionScenario()` - 10k ETH transactions - `testDoubleOverflowMaximumTransactionScenario()` - 10k ETH transactions
All new tests validate that double overflow requires unrealistic conditions, proving the 1000x compression limit provides adequate protection. All new tests validate that double overflow requires unrealistic conditions, proving the 1000x compression limit provides adequate protection.