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
**Kraiken.sol** - ERC20 with Harberger staking
**Kraiken.sol** - ERC20 with self-assessed tax staking
- `outstandingSupply()` = totalSupply - liquidityManager balance
- Proportional staking pool growth/shrink on mint/burn
- 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
- Upgradeable for new strategies
**Stake.sol** - Harberger tax
**Stake.sol** - Self-assessed tax system
- Self-assessed valuations
- Continuous auction mechanism
@ -36,7 +36,6 @@ Core KRAIKEN protocol contracts implementing the dominant liquidity manager stra
When `token0isWeth = true`:
- Amount0 functions return **ETH** amounts
- Amount1 functions return **KRAIKEN** amounts
- Discovery position must use `getAmount1ForLiquidity()` for KRAIKEN
### Outstanding Supply
Excludes tokens used for liquidity positions:
@ -59,11 +58,11 @@ uint256 requiredEth = outstandingSupply.mulDiv(sqrtVwapX96, 1 << 96);
- 100% = KRAIKEN valued at 170% for reserves
2. **anchorShare** (0-1e18)
- Floor ETH = totalETH × (1 - anchorShare)²
- 95% anchorShare = 90.1% floor allocation
- 0 anchorShare = 5% of ETH in anchor
- 1e18 anchorShare = 25% of ETH in anchor
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)
- 2x-10x liquidity multiplier vs anchor
@ -147,4 +146,5 @@ forge test --mc Test # Match contract
- `test/helpers/UniswapTestBase.sol` - Pool setup
- `test/helpers/KraikenTestBase.sol` - Common utils
- `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:
```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
```
@ -94,7 +94,7 @@ $ cast --help
address: 0xf6a3eef9088A255c32b6aD2025f83E57291D9011
### Harberg
### Kraiken
address: 0x22c264Ecf8D4E49D1E3CabD8DD39b7C4Ab51C1B8
@ -109,7 +109,7 @@ address: 0x3d6a8797693a0bC598210782B6a889E11A2340Cd
## Deployment on Base
### Harberg
### Kraiken
address: 0x45caa5929f6ee038039984205bdecf968b954820

View file

@ -6,7 +6,7 @@ A static liquidity provider strategy in a dynamic market leads to:
- impermanent loss
- 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:
onchain:
@ -19,7 +19,7 @@ offchain:
- Macro
- 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.
- 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
address private immutable factory;
IWETH9 private immutable weth;
Kraiken private immutable harb;
Kraiken private immutable kraiken;
Optimizer private immutable optimizer;
IUniswapV3Pool private immutable pool;
bool private immutable token0isWeth;
@ -57,15 +57,15 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
/// @notice Constructor initializes all contract references and pool configuration
/// @param _factory The address of the Uniswap V3 factory
/// @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
constructor(address _factory, address _WETH9, address _harb, address _optimizer) {
constructor(address _factory, address _WETH9, address _kraiken, address _optimizer) {
factory = _factory;
weth = IWETH9(_WETH9);
poolKey = PoolAddress.getPoolKey(_WETH9, _harb, FEE);
poolKey = PoolAddress.getPoolKey(_WETH9, _kraiken, FEE);
pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey));
harb = Kraiken(_harb);
token0isWeth = _WETH9 < _harb;
kraiken = Kraiken(_kraiken);
token0isWeth = _WETH9 < _kraiken;
optimizer = Optimizer(_optimizer);
}
@ -75,9 +75,9 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
function uniswapV3MintCallback(uint256 amount0Owed, uint256 amount1Owed, bytes calldata) external {
CallbackValidation.verifyCallback(factory, poolKey);
// Handle HARB minting
uint256 harbPulled = token0isWeth ? amount1Owed : amount0Owed;
harb.mint(harbPulled);
// Handle KRAIKEN minting
uint256 kraikenPulled = token0isWeth ? amount1Owed : amount0Owed;
kraiken.mint(kraikenPulled);
// Handle WETH conversion
uint256 ethOwed = token0isWeth ? amount0Owed : amount1Owed;
@ -138,7 +138,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
// Update total supply tracking if price moved up
if (isUp) {
harb.setPreviousTotalSupply(harb.totalSupply());
kraiken.setPreviousTotalSupply(kraiken.totalSupply());
}
// Get optimizer parameters and set new positions
@ -212,21 +212,21 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
IERC20(address(weth)).transfer(feeDestination, fee0);
_recordVolumeAndPrice(currentPrice, fee0);
} else {
IERC20(address(harb)).transfer(feeDestination, fee0);
IERC20(address(kraiken)).transfer(feeDestination, fee0);
}
}
if (fee1 > 0) {
if (token0isWeth) {
IERC20(address(harb)).transfer(feeDestination, fee1);
IERC20(address(kraiken)).transfer(feeDestination, fee1);
} else {
IERC20(address(weth)).transfer(feeDestination, fee1);
_recordVolumeAndPrice(currentPrice, fee1);
}
}
// Burn any remaining HARB tokens
harb.burn(harb.balanceOf(address(this)));
// Burn any remaining KRAIKEN tokens
kraiken.burn(kraiken.balanceOf(address(this)));
}
/// @notice Allow contract to receive ETH
@ -242,8 +242,8 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
}
/// @notice Implementation of abstract function from ThreePositionStrategy
function _getHarbToken() internal view override returns (address) {
return address(harb);
function _getKraikenToken() internal view override returns (address) {
return address(kraiken);
}
/// @notice Implementation of abstract function from ThreePositionStrategy
@ -273,6 +273,6 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
/// @notice Implementation of abstract function from ThreePositionStrategy
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
*/
contract Optimizer is Initializable, UUPSUpgradeable {
Kraiken private harberg;
Kraiken private kraiken;
Stake private stake;
/// @dev Reverts if the caller is not the admin.
@ -30,13 +30,13 @@ contract Optimizer is Initializable, UUPSUpgradeable {
/**
* @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.
*/
function initialize(address _harberg, address _stake) public initializer {
function initialize(address _kraiken, address _stake) public initializer {
// Set the admin for upgradeability (using ERC1967Upgrade _changeAdmin)
_changeAdmin(msg.sender);
harberg = Kraiken(_harberg);
kraiken = Kraiken(_kraiken);
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
* enforcing a minimum tax payment duration.
*
* @dev Harberger tax implementation:
* @dev Self-assessed tax implementation:
* - Continuous auction mechanism
* - Self-assessed valuations create prediction market
* - Tax collection and redistribution through UBI
@ -169,7 +169,7 @@ contract Stake {
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 {
totalSharesAtTaxRate[pos.taxRate] -= pos.share;
outstandingStake -= pos.share;
@ -182,7 +182,7 @@ contract Stake {
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 {
require(sharesToTake < pos.share, "position too small");
uint256 assets = sharesToAssets(sharesToTake);
@ -193,22 +193,22 @@ contract Stake {
SafeERC20.safeTransfer(kraiken, pos.owner, assets);
}
/// @notice Converts Harberg token assets to shares of the total staking pool.
/// @param assets Number of Harberg tokens to convert.
/// @return Number of shares corresponding to the input assets based on the current total supply of Harberg tokens.
/// @notice Converts Kraiken token assets to shares of the total staking pool.
/// @param assets Number of Kraiken tokens to convert.
/// @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) {
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.
/// @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) {
return shares.mulDiv(kraiken.totalSupply(), totalSupply, Math.Rounding.Down);
}
/// @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 taxRate The initial tax rate for the new staking position.
/// @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.
/// @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 taxRate The initial tax rate for the new staking position.
/// @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.
/// @return percentageStaked A number between 0 and 1e18 indicating the percentage of Harberg supply staked.
/// @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 Kraiken supply staked.
function getPercentageStaked() external view returns (uint256 percentageStaked) {
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);
/// @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 _isToken0Weth() internal view virtual returns (bool);
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);
// 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)
uint256 discoveryAmount = _setDiscoveryPosition(currentTick, anchorLiquidity, params);
// 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)
/// @param currentTick Current market tick
/// @param anchorEthBalance ETH allocated to anchor position
/// @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
function _setAnchorPosition(
int24 currentTick,
uint256 anchorEthBalance,
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
int24 anchorSpacing = TICK_SPACING + (34 * int24(params.anchorWidth) * TICK_SPACING / 100);
@ -112,10 +112,10 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
if (token0isWeth) {
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, anchorEthBalance);
pulledHarb = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, anchorLiquidity);
pulledKraiken = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, anchorLiquidity);
} else {
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, anchorEthBalance);
pulledHarb = LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, anchorLiquidity);
pulledKraiken = LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, 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 anchorLiquidity Liquidity amount from anchor position
/// @param params Position parameters
/// @return discoveryAmount Amount of HARB used for discovery
/// @return discoveryAmount Amount of KRAIKEN used for discovery
function _setDiscoveryPosition(
int24 currentTick,
uint128 anchorLiquidity,
@ -179,13 +179,13 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
/// Extreme floor positions are CORRECT behavior protecting protocol solvency
/// @param currentTick Current market tick
/// @param floorEthBalance ETH allocated to floor position (75% of total)
/// @param pulledHarb HARB amount from anchor position
/// @param discoveryAmount HARB amount from discovery position
/// @param pulledKraiken KRAIKEN amount from anchor position
/// @param discoveryAmount KRAIKEN amount from discovery position
/// @param params Position parameters including capital inefficiency
function _setFloorPosition(
int24 currentTick,
uint256 floorEthBalance,
uint256 pulledHarb,
uint256 pulledKraiken,
uint256 discoveryAmount,
PositionParams memory params
) internal {
@ -193,7 +193,7 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
// Calculate outstanding supply after position minting
uint256 outstandingSupply = _getOutstandingSupply();
outstandingSupply -= pulledHarb;
outstandingSupply -= pulledKraiken;
outstandingSupply -= (outstandingSupply >= discoveryAmount) ? discoveryAmount : outstandingSupply;
// 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 {
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 tokenAmount Amount of the Harberg token
/// @param tokenAmount Amount of the Kraiken token
/// @param ethAmount Amount of Ethereum
/// @return tick_ The calculated tick for the given price ratio
function _tickAtPrice(bool t0isWeth, uint256 tokenAmount, uint256 ethAmount) internal pure returns (int24 tick_) {
require(ethAmount > 0, "ETH amount cannot be zero");
if (tokenAmount == 0) {
// HARB/ETH
// KRAIKEN/ETH
tick_ = TickMath.MAX_TICK;
} else {
// Use ABDKMath64x64 for precise division and square root calculation
int128 priceRatioX64 = ABDKMath64x64.div(int128(int256(tokenAmount)), int128(int256(ethAmount)));
// HARB/ETH
// KRAIKEN/ETH
tick_ = _tickAtPriceRatio(priceRatioX64);
}
// convert to tick in a pool
@ -42,7 +42,7 @@ abstract contract UniswapMath {
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
/// This is intentional for capital requirement calculations
/// To get regular price: sqrt(priceRatioX96) * 2^48

View file

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

View file

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

View file

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