add tax rate adjustment
This commit is contained in:
parent
4845129fe3
commit
3225be1084
4 changed files with 33 additions and 17 deletions
|
|
@ -30,6 +30,7 @@ contract Stake is IStake {
|
|||
error PositionNotFound();
|
||||
|
||||
event PositionCreated(uint256 indexed positionId, address indexed owner, uint256 share, uint32 creationTime, uint32 taxRate);
|
||||
event TaxPaid(uint256 indexed positionId, address indexed owner, uint256 taxAmount);
|
||||
event PositionRemoved(uint256 indexed positionId, uint256 share, uint32 lastTaxTime);
|
||||
|
||||
struct StakingPosition {
|
||||
|
|
@ -123,7 +124,7 @@ contract Stake is IStake {
|
|||
}
|
||||
// dissolve position
|
||||
// TODO: what if someone calls payTax and exitPosition in the same transaction?
|
||||
_payTax(pos, 0);
|
||||
_payTax(positionsToSnatch[i], pos, 0);
|
||||
_exitPosition(positionsToSnatch[i], pos);
|
||||
// TODO: exit positions partially, if needed
|
||||
// TODO: avoid greeving where more positions are freed than needed.
|
||||
|
|
@ -151,20 +152,31 @@ contract Stake is IStake {
|
|||
emit PositionCreated(positionId, sp.owner, sp.share, sp.creationTime, sp.taxRate);
|
||||
}
|
||||
|
||||
function changeTax(uint256 positionID, uint32 taxRate) public {
|
||||
StakingPosition storage pos = positions[positionID];
|
||||
if (pos.owner != msg.sender) {
|
||||
revert NoPermission(msg.sender, pos.owner);
|
||||
}
|
||||
// to prevent snatch-and-change grieving attack, pay TAX_FLOOR_DURATION
|
||||
require(taxRate > pos.taxRate);
|
||||
_payTax(positionID, pos, TAX_FLOOR_DURATION);
|
||||
pos.taxRate = taxRate;
|
||||
}
|
||||
|
||||
function exitPosition(uint256 positionId) public {
|
||||
StakingPosition storage pos = positions[positionId];
|
||||
if (pos.owner != msg.sender) {
|
||||
revert NoPermission(msg.sender, pos.owner);
|
||||
}
|
||||
// to prevent snatch-and-exit grieving attack, pay TAX_FLOOR_DURATION
|
||||
_payTax(pos, TAX_FLOOR_DURATION);
|
||||
_payTax(positionId, pos, TAX_FLOOR_DURATION);
|
||||
_exitPosition(positionId, pos);
|
||||
}
|
||||
|
||||
function payTax(uint256 positionID) public {
|
||||
StakingPosition storage pos = positions[positionID];
|
||||
// TODO: what if someone calls payTax and exitPosition in the same transaction?
|
||||
_payTax(pos, 0);
|
||||
_payTax(positionID, pos, 0);
|
||||
}
|
||||
|
||||
function taxDue(uint256 positionID, uint256 taxFloorDuration) public view returns (uint256 amountDue) {
|
||||
|
|
@ -178,7 +190,7 @@ contract Stake is IStake {
|
|||
amountDue = assetsBefore * pos.taxRate * elapsedTime / (365 * 24 * 60 * 60) / TAX_RATE_BASE;
|
||||
}
|
||||
|
||||
function _payTax(StakingPosition storage pos, uint256 taxFloorDuration) private {
|
||||
function _payTax(uint256 positionID, StakingPosition storage pos, uint256 taxFloorDuration) private {
|
||||
// ihet = Implied Holding Expiry Timestamp
|
||||
uint256 ihet = (block.timestamp - pos.creationTime < taxFloorDuration)
|
||||
? pos.creationTime + taxFloorDuration
|
||||
|
|
@ -191,6 +203,7 @@ contract Stake is IStake {
|
|||
taxAmountDue = assetsBefore;
|
||||
}
|
||||
SafeERC20.safeTransfer(tokenContract, taxPool, taxAmountDue);
|
||||
emit TaxPaid(positionID, pos.owner, taxAmountDue);
|
||||
if (assetsBefore - taxAmountDue > 0) {
|
||||
// if something left over, update storage
|
||||
pos.share = assetsToShares(assetsBefore - taxAmountDue, Math.Rounding.Down);
|
||||
|
|
@ -199,6 +212,7 @@ contract Stake is IStake {
|
|||
// if nothing left over, liquidate position
|
||||
// TODO: emit event
|
||||
outstandingStake -= pos.share;
|
||||
emit PositionRemoved(positionID, pos.share, pos.lastTaxTime);
|
||||
delete pos.owner;
|
||||
delete pos.creationTime;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,10 @@ contract BaseLineLPTest is Test {
|
|||
harb.setLiquidityManager(address(liquidityManager));
|
||||
}
|
||||
|
||||
function testLP(address account, uint256 amount) public {
|
||||
function testLP(address account) public {
|
||||
vm.assume(account != address(0));
|
||||
vm.assume(account != address(1)); // TWAB sponsorship address
|
||||
vm.assume(account != address(2)); // tax pool address
|
||||
vm.deal(account, 10 ether);
|
||||
vm.prank(account);
|
||||
(bool sent, ) = address(liquidityManager).call{value: 10 ether}("");
|
||||
|
|
@ -83,7 +86,6 @@ contract BaseLineLPTest is Test {
|
|||
vm.expectRevert();
|
||||
liquidityManager.shift();
|
||||
|
||||
int24 startTick = (address(weth) < address(harb)) ? int24(128219) : int24(-128219); //initialize at 1 cent
|
||||
liquidityManager.slide();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue