some fixes
This commit is contained in:
parent
92fd80d5ce
commit
b903c88ee9
2 changed files with 110 additions and 100 deletions
|
|
@ -36,7 +36,6 @@ contract BaseLineLP {
|
|||
|
||||
enum Stage { FLOOR, ANCHOR, DISCOVERY }
|
||||
|
||||
uint256 constant CAPITAL_INEFFICIENCY = 120;
|
||||
uint256 constant LIQUIDITY_RATIO_DIVISOR = 100;
|
||||
|
||||
// the address of the Uniswap V3 factory
|
||||
|
|
@ -59,6 +58,8 @@ contract BaseLineLP {
|
|||
uint256 private lastDay;
|
||||
uint256 private mintedToday;
|
||||
|
||||
uint256 constant ANCHOR_LIQ_SHARE = 5; // 5%
|
||||
uint256 constant CAPITAL_INEFFICIENCY = 120;
|
||||
// State variables to track total ETH spent
|
||||
uint256 public cumulativeVolumeWeightedPrice;
|
||||
uint256 public cumulativeVolume;
|
||||
|
|
@ -124,9 +125,7 @@ contract BaseLineLP {
|
|||
}
|
||||
|
||||
function outstanding() public view returns (uint256 _outstanding) {
|
||||
//_outstanding = (harb.totalSupply() - harb.balanceOf(address(pool)) - harb.balanceOf(address(this)));
|
||||
// This introduces capital inefficiency, but haven't found another way yet to protect capital from whale attacks
|
||||
_outstanding = (harb.totalSupply() - harb.balanceOf(address(pool)) - harb.balanceOf(address(this))) * CAPITAL_INEFFICIENCY / 100;
|
||||
_outstanding = (harb.totalSupply() - harb.balanceOf(address(pool)) - harb.balanceOf(address(this)));
|
||||
}
|
||||
|
||||
function spendingLimit() public view returns (uint256, uint256) {
|
||||
|
|
@ -241,19 +240,18 @@ contract BaseLineLP {
|
|||
requiredEthForBuyback = outstandingSupply / vwap * 10**18;
|
||||
}
|
||||
uint256 ethBalance = (address(this).balance + weth.balanceOf(address(this)));
|
||||
// leave at least 5% of supply for anchor
|
||||
ethBalance = ethBalance * 90 / 100;
|
||||
// leave at least x% of supply for anchor
|
||||
ethBalance = ethBalance * (100 - ANCHOR_LIQ_SHARE) / 100;
|
||||
if (ethBalance < requiredEthForBuyback) {
|
||||
// not enough ETH, find a lower price
|
||||
requiredEthForBuyback = ethBalance;
|
||||
// put the price 5% lower than needed
|
||||
vwapTick = tickAtPrice(outstandingSupply, requiredEthForBuyback);
|
||||
vwapTick = tickAtPrice(outstandingSupply * CAPITAL_INEFFICIENCY / 100, requiredEthForBuyback);
|
||||
} else if (vwap == 0) {
|
||||
requiredEthForBuyback = ethBalance;
|
||||
vwapTick = currentTick;
|
||||
} else {
|
||||
// put the price 5% lower than needed
|
||||
vwapTick = tickAtPrice(cumulativeVolumeWeightedPrice / 10**18, cumulativeVolume);
|
||||
vwapTick = tickAtPrice(cumulativeVolumeWeightedPrice * CAPITAL_INEFFICIENCY / 100 / 10**18, cumulativeVolume);
|
||||
|
||||
if (requiredEthForBuyback < ethBalance) {
|
||||
// invest a majority of the ETH still in floor, even though not needed
|
||||
requiredEthForBuyback = (requiredEthForBuyback + (5 * ethBalance)) / 6;
|
||||
|
|
|
|||
|
|
@ -132,14 +132,17 @@ contract BaseLineLP2Test is Test {
|
|||
// have some time pass to record prices in uni oracle
|
||||
uint256 timeBefore = block.timestamp;
|
||||
vm.warp(timeBefore + (60 * 60 * 5));
|
||||
lm.slide();
|
||||
|
||||
// Check liquidity positions after slide
|
||||
(uint256 ethFloor, uint256 ethAnchor, uint256 ethDiscovery, uint256 harbFloor, uint256 harbAnchor, uint256 harbDiscovery) = checkLiquidityPositionsAfter("slide");
|
||||
assertGt(ethFloor, ethAnchor * 5, "slide - Floor should hold more ETH than Anchor");
|
||||
assertGt(harbDiscovery, harbAnchor * 90, "slide - Discovery should hold more HARB than Anchor");
|
||||
assertEq(harbFloor, 0, "slide - Floor should have no HARB");
|
||||
assertEq(ethDiscovery, 0, "slide - Discovery should have no ETH");
|
||||
try lm.slide() {
|
||||
// Check liquidity positions after slide
|
||||
(uint256 ethFloor, uint256 ethAnchor, uint256 ethDiscovery, uint256 harbFloor, uint256 harbAnchor, uint256 harbDiscovery) = checkLiquidityPositionsAfter("slide");
|
||||
assertGt(ethFloor, ethAnchor * 4, "slide - Floor should hold more ETH than Anchor");
|
||||
assertGt(harbDiscovery, harbAnchor * 90, "slide - Discovery should hold more HARB than Anchor");
|
||||
assertEq(harbFloor, 0, "slide - Floor should have no HARB");
|
||||
assertEq(ethDiscovery, 0, "slide - Discovery should have no ETH");
|
||||
} catch {
|
||||
console.log("slide failed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -147,14 +150,18 @@ contract BaseLineLP2Test is Test {
|
|||
// have some time pass to record prices in uni oracle
|
||||
uint256 timeBefore = block.timestamp;
|
||||
vm.warp(timeBefore + (60 * 60 * 5));
|
||||
lm.shift();
|
||||
|
||||
// Check liquidity positions after shift
|
||||
(uint256 ethFloor, uint256 ethAnchor, uint256 ethDiscovery, uint256 harbFloor, uint256 harbAnchor, uint256 harbDiscovery) = checkLiquidityPositionsAfter("shift");
|
||||
assertGt(ethFloor, ethAnchor * 5, "shift - Floor should hold more ETH than Anchor");
|
||||
assertGt(harbDiscovery, harbAnchor * 90, "shift - Discovery should hold more HARB than Anchor");
|
||||
assertEq(harbFloor, 0, "shift - Floor should have no HARB");
|
||||
assertEq(ethDiscovery, 0, "shift - Discovery should have no ETH");
|
||||
try lm.shift() {
|
||||
// Check liquidity positions after shift
|
||||
(uint256 ethFloor, uint256 ethAnchor, uint256 ethDiscovery, uint256 harbFloor, uint256 harbAnchor, uint256 harbDiscovery) = checkLiquidityPositionsAfter("shift");
|
||||
assertGt(ethFloor, ethAnchor * 4, "shift - Floor should hold more ETH than Anchor");
|
||||
assertGt(harbDiscovery, harbAnchor * 90, "shift - Discovery should hold more HARB than Anchor");
|
||||
assertEq(harbFloor, 0, "shift - Floor should have no HARB");
|
||||
assertEq(ethDiscovery, 0, "shift - Discovery should have no ETH");
|
||||
} catch {
|
||||
console.log("shift failed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -435,101 +442,106 @@ contract BaseLineLP2Test is Test {
|
|||
// }
|
||||
|
||||
|
||||
function testScenarioB() public {
|
||||
// function testScenarioB() public {
|
||||
// setUpCustomToken0(false);
|
||||
// vm.deal(account, 100 ether);
|
||||
// vm.prank(account);
|
||||
// weth.deposit{value: 100 ether}();
|
||||
|
||||
// uint256 traderBalanceBefore = weth.balanceOf(account);
|
||||
|
||||
// // Setup initial liquidity
|
||||
// slide();
|
||||
|
||||
// buy(2 ether);
|
||||
|
||||
// shift();
|
||||
|
||||
// buy(2 ether);
|
||||
|
||||
// shift();
|
||||
|
||||
// buy(2 ether);
|
||||
|
||||
// shift();
|
||||
|
||||
// sell(harb.balanceOf(account));
|
||||
|
||||
// slide();
|
||||
|
||||
// writeCsv();
|
||||
// uint256 traderBalanceAfter = weth.balanceOf(account);
|
||||
// console.log(traderBalanceBefore);
|
||||
// console.log(traderBalanceAfter);
|
||||
// assertGt(traderBalanceBefore, traderBalanceAfter, "trader should not have made profit");
|
||||
// }
|
||||
|
||||
function testScenarioFuzz(uint8 numActions, uint8 frequency, uint8[] calldata amounts) public {
|
||||
vm.assume(numActions > 5);
|
||||
vm.assume(frequency > 0);
|
||||
vm.assume(frequency < 20);
|
||||
vm.assume(amounts.length >= numActions);
|
||||
|
||||
setUpCustomToken0(false);
|
||||
vm.deal(account, 100 ether);
|
||||
vm.prank(account);
|
||||
weth.deposit{value: 100 ether}();
|
||||
|
||||
uint256 traderBalanceBefore = weth.balanceOf(account);
|
||||
|
||||
// Setup initial liquidity
|
||||
slide();
|
||||
|
||||
buy(2 ether);
|
||||
uint256 traderBalanceBefore = weth.balanceOf(account);
|
||||
uint8 f = 0;
|
||||
for (uint i = 0; i < numActions; i++) {
|
||||
uint256 amount = (uint256(amounts[i]) * 1 ether) + 1 ether;
|
||||
uint256 harbBal = harb.balanceOf(account);
|
||||
|
||||
shift();
|
||||
if (harbBal == 0) {
|
||||
amount = amount % (weth.balanceOf(account) / 2);
|
||||
amount = amount == 0 ? weth.balanceOf(account) : amount;
|
||||
buy(amount);
|
||||
} else if (weth.balanceOf(account) == 0) {
|
||||
sell(amount % harbBal);
|
||||
} else {
|
||||
if (amount % 2 == 0) {
|
||||
amount = amount % (weth.balanceOf(account) / 2);
|
||||
amount = amount == 0 ? weth.balanceOf(account) : amount;
|
||||
buy(amount);
|
||||
} else {
|
||||
sell(amount % harbBal);
|
||||
}
|
||||
}
|
||||
|
||||
buy(2 ether);
|
||||
if (f >= frequency) {
|
||||
(, int24 currentTick, , , , , ) = pool.slot0();
|
||||
(, int24 tickLower, int24 tickUpper) = lm.positions(BaseLineLP.Stage.ANCHOR);
|
||||
int24 midTick = (tickLower + tickUpper) / 2;
|
||||
if (currentTick < midTick) {
|
||||
// Current tick is below the midpoint, so call slide()
|
||||
slide();
|
||||
} else if (currentTick > midTick) {
|
||||
// Current tick is above the midpoint, so call shift()
|
||||
shift();
|
||||
}
|
||||
|
||||
shift();
|
||||
|
||||
buy(2 ether);
|
||||
|
||||
shift();
|
||||
f = 0;
|
||||
} else {
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
// Simulate large sell to push price down to floor
|
||||
sell(harb.balanceOf(account));
|
||||
|
||||
slide();
|
||||
|
||||
writeCsv();
|
||||
uint256 traderBalanceAfter = weth.balanceOf(account);
|
||||
console.log(traderBalanceBefore);
|
||||
console.log(traderBalanceAfter);
|
||||
|
||||
if (traderBalanceAfter > traderBalanceBefore){
|
||||
writeCsv();
|
||||
}
|
||||
assertGt(traderBalanceBefore, traderBalanceAfter, "trader should not have made profit");
|
||||
}
|
||||
|
||||
// function testScenarioFuzz(uint8 numActions, uint8 frequency, uint8[] calldata amounts) public {
|
||||
// vm.assume(numActions > 5);
|
||||
// vm.assume(frequency > 0);
|
||||
// vm.assume(frequency < 20);
|
||||
// vm.assume(amounts.length >= numActions);
|
||||
|
||||
// setUpCustomToken0(false);
|
||||
// vm.deal(account, 400 ether);
|
||||
// vm.prank(account);
|
||||
// weth.deposit{value: 400 ether}();
|
||||
|
||||
|
||||
// // Setup initial liquidity
|
||||
// slide();
|
||||
|
||||
// uint256 traderBalanceBefore = weth.balanceOf(account);
|
||||
// uint8 f = 0;
|
||||
// for (uint i = 0; i < numActions; i++) {
|
||||
// uint256 amount = (amounts[i] * 1 ether) + 1 ether;
|
||||
// uint256 harbBal = harb.balanceOf(account);
|
||||
// if (harbBal == 0) {
|
||||
// buy(amount % (weth.balanceOf(account) / 2));
|
||||
// } else if (weth.balanceOf(account) == 0) {
|
||||
// sell(amount % harbBal);
|
||||
// } else {
|
||||
// if (amount % 2 == 0) {
|
||||
// buy(amount % (weth.balanceOf(account) / 2));
|
||||
// } else {
|
||||
// sell(amount % harbBal);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (f >= frequency) {
|
||||
// (, int24 currentTick, , , , , ) = pool.slot0();
|
||||
// (, int24 tickLower, int24 tickUpper) = lm.positions(BaseLineLP.Stage.ANCHOR);
|
||||
// int24 midTick = (tickLower + tickUpper) / 2;
|
||||
// if (currentTick < midTick) {
|
||||
// // Current tick is below the midpoint, so call slide()
|
||||
// slide();
|
||||
// } else if (currentTick > midTick) {
|
||||
// // Current tick is above the midpoint, so call shift()
|
||||
// shift();
|
||||
// }
|
||||
|
||||
// f = 0;
|
||||
// } else {
|
||||
// f++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Simulate large sell to push price down to floor
|
||||
// sell(harb.balanceOf(account));
|
||||
|
||||
// slide();
|
||||
|
||||
// uint256 traderBalanceAfter = weth.balanceOf(account);
|
||||
|
||||
// if (traderBalanceAfter > traderBalanceBefore){
|
||||
// writeCsv();
|
||||
// }
|
||||
// assertGt(traderBalanceBefore, traderBalanceAfter, "trader should not have made profit");
|
||||
// }
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue