Skip to content

Commit

Permalink
fix: batchBuyUnlock does not deduct from msg.value after each iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
kyriediculous committed Jun 19, 2024
1 parent ebdd11a commit f55818f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/lpETH/LpETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ contract LpETH is
lpCut = fee60x18.mul(MIN_LP_CUT).unwrap();
treasuryCut = fee60x18.mul(TREASURY_CUT).unwrap();
uint256 baseReward = unlock.fee - lpCut - treasuryCut;
UD60x18 progress = ud(request.createdAt - block.number).div(ud(UNSETH_EXPIRATION_TIME));
UD60x18 progress = ud(request.createdAt - block.timestamp).div(ud(UNSETH_EXPIRATION_TIME));
reward = ud(baseReward).mul(UNIT_60x18.sub(progress)).unwrap();
// Adjust lpCut by the remaining amount after subtracting the reward
// This step seems to adjust lpCut to balance out the distribution
Expand Down Expand Up @@ -447,6 +447,7 @@ contract LpETH is
uint256 totalRewards;
uint256 totalLpCut;
uint256 totalTreasuryCut;
uint256 msgValue = msg.value;

uint256[] memory tokenIds = new uint256[](n);

Expand All @@ -464,7 +465,7 @@ contract LpETH is
uint256 lpCut = fee60x18.mul(MIN_LP_CUT).unwrap();
uint256 treasuryCut = fee60x18.mul(TREASURY_CUT).unwrap();
uint256 baseReward = unlock.fee - lpCut - treasuryCut;
UD60x18 progress = ud(request.createdAt - block.number).div(ud(UNSETH_EXPIRATION_TIME));
UD60x18 progress = ud(request.createdAt - block.timestamp).div(ud(UNSETH_EXPIRATION_TIME));
reward = ud(baseReward).mul(UNIT_60x18.sub(progress)).unwrap();
// Adjust lpCut by the remaining amount after subtracting the reward
// This step seems to adjust lpCut to balance out the distribution
Expand All @@ -486,10 +487,14 @@ contract LpETH is

// transfer unlock amount minus reward from caller to pool
// the reward is the discount paid. 'reward < unlock.fee' always.
if (msg.value < request.amount - reward) revert ErrorInsufficientAmount();

if (msgValue < request.amount - reward) revert ErrorInsufficientAmount();
msgValue -= request.amount - reward;
// transfer unlock to caller
UNSETH.safeTransferFrom(address(this), msg.sender, unlock.tokenId);
// transfer unused ETH back
if (msgValue > 0) {
payable(msg.sender).transfer(msgValue);
}
}

// Update pool state
Expand Down
39 changes: 39 additions & 0 deletions test/lpETH/LpETH.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,43 @@ contract LPETH_Test is Test, ERC721Receiver {
// TODO: check events
// TODO: check amount
}

function test_batch_buyUnlock() public {
uint256 unsETHRequestId = 1337; // not token id !
uint256 swapAmount = 250 ether;
vm.deal(payable(address(this)), 2000 ether);
lpETH.deposit{ value: 1000 ether }(0);

vm.mockCall(
address(token1_adapter), abi.encodeCall(Adapter.minMaxAmount, ()), abi.encode(0 ether, 100_000 ether)
);

vm.mockCall(address(token1_adapter), abi.encodeCall(Adapter.totalStaked, ()), abi.encode(1000 ether));

vm.mockCall(
address(token1_adapter),
abi.encodeCall(Adapter.requestWithdraw, (swapAmount)),
abi.encode(unsETHRequestId, swapAmount)
);

token1.mint(address(this), 250 ether);
token1.approve(address(lpETH), 200 ether);
for (uint256 i = 0; i < 5; i++) {
vm.mockCall(
address(token1_adapter), abi.encodeCall(Adapter.requestWithdraw, (10 ether)), abi.encode(i, 10 ether)
);
lpETH.swap(address(token1), 10 ether, 0);

vm.mockCall(address(token1_adapter), abi.encodeCall(Adapter.isFinalized, (i)), abi.encode(false));
}

// 50 ETH in unlocks pending

// try to buy 50 ETH with 10 ETH
vm.expectRevert(abi.encodeWithSelector(LpETHEvents.ErrorInsufficientAmount.selector));
lpETH.batchBuyUnlock{ value: 10 ether }(5);

// now try with 50 ETH
lpETH.batchBuyUnlock{ value: 50 ether }(5);
}
}

0 comments on commit f55818f

Please sign in to comment.