Skip to content

Commit

Permalink
use earningsFactorAtInterval to calculate the tokensOwed after expira…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
paco0x authored and ewilz committed Nov 21, 2024
1 parent 2a58a22 commit 73cd6c3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
11 changes: 7 additions & 4 deletions contracts/hooks/examples/TWAMM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,16 @@ contract TWAMM is BaseHook, ITWAMM {
if (amountDelta != 0 && orderKey.expiration <= block.timestamp) revert CannotModifyCompletedOrder(orderKey);

unchecked {
uint256 earningsFactor = orderPool.earningsFactorCurrent - order.earningsFactorLast;
buyTokensOwed = (earningsFactor * order.sellRate) >> FixedPoint96.RESOLUTION;
earningsFactorLast = orderPool.earningsFactorCurrent;
order.earningsFactorLast = earningsFactorLast;
earningsFactorLast = orderKey.expiration <= block.timestamp
? orderPool.earningsFactorAtInterval[orderKey.expiration]
: orderPool.earningsFactorCurrent;
buyTokensOwed =
((earningsFactorLast - order.earningsFactorLast) * order.sellRate) >> FixedPoint96.RESOLUTION;

if (orderKey.expiration <= block.timestamp) {
delete self.orders[_orderId(orderKey)];
} else {
order.earningsFactorLast = earningsFactorLast;
}

if (amountDelta != 0) {
Expand Down
34 changes: 34 additions & 0 deletions test/TWAMM.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,40 @@ contract TWAMMTest is Test, Deployers, GasSnapshot {
twamm.updateOrder(poolKey, orderKey1, amountDelta);
}

function testTWAMM_updatedOrder_calculateTokensOwedAfterExpiration() public {
ITWAMM.OrderKey memory orderKey1;
ITWAMM.OrderKey memory orderKey2;
uint256 orderAmount;
(orderKey1, orderKey2, orderAmount) = submitOrdersBothDirections();

// submit two more orders that will expire after order1 & order2 so the earningsFactorCurrent will continue growing after they expire
uint256 extraOrderAmount = 2 ether;
ITWAMM.OrderKey memory orderKey3 = ITWAMM.OrderKey(address(this), 60000, true);
ITWAMM.OrderKey memory orderKey4 = ITWAMM.OrderKey(address(this), 60000, false);
token0.approve(address(twamm), extraOrderAmount);
token1.approve(address(twamm), extraOrderAmount);
twamm.submitOrder(poolKey, orderKey3, extraOrderAmount);
twamm.submitOrder(poolKey, orderKey4, extraOrderAmount);

// set timestamp to after order1 & order2 expire
vm.warp(40000);

// update order1 & order2 after expiration, should use the earningsFactorAtInterval at expiration to settle
vm.expectEmit(true, true, true, true);
emit UpdateOrder(poolId, address(this), 30000, true, 0, 20000 << 96);
twamm.updateOrder(poolKey, orderKey1, 0);

vm.expectEmit(true, true, true, true);
emit UpdateOrder(poolId, address(this), 30000, false, 0, 20000 << 96);
twamm.updateOrder(poolKey, orderKey2, 0);

uint256 token0Owed = twamm.tokensOwed(poolKey.currency0, orderKey2.owner);
uint256 token1Owed = twamm.tokensOwed(poolKey.currency1, orderKey2.owner);

assertEq(token0Owed, orderAmount);
assertEq(token1Owed, orderAmount);
}

function testTWAMM_updateOrder_zeroForOne_decreasesSellrateUpdatesSellTokensOwed() public {
ITWAMM.OrderKey memory orderKey1;
ITWAMM.OrderKey memory orderKey2;
Expand Down

0 comments on commit 73cd6c3

Please sign in to comment.