Skip to content

Commit

Permalink
finalizeRequests with specific totalAmount
Browse files Browse the repository at this point in the history
  • Loading branch information
jtfirek committed Sep 5, 2024
1 parent bf9dcca commit 33de838
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/EtherFiAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ contract EtherFiAdmin is Initializable, OwnableUpgradeable, UUPSUpgradeable {
for (uint256 i = 0; i < _report.withdrawalRequestsToInvalidate.length; i++) {
withdrawRequestNft.invalidateRequest(_report.withdrawalRequestsToInvalidate[i]);
}
withdrawRequestNft.finalizeRequests(_report.lastFinalizedWithdrawalRequestId);
withdrawRequestNft.finalizeRequests(_report.lastFinalizedWithdrawalRequestId, _report.finalizedWithdrawalAmount);
}

function slotForNextReportToProcess() public view returns (uint32) {
Expand Down
37 changes: 26 additions & 11 deletions src/WithdrawRequestNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,11 @@ contract WithdrawRequestNFT is ERC721Upgradeable, UUPSUpgradeable, OwnableUpgrad
function initializeV2dot5(address _roleRegistry) external onlyOwner {
require(address(roleRegistry) == address(0x00), "already initialized");

DEPRECATED_accumulatedDustEEthShares = 0;
// TODO: compile list of values in DEPRECATED_admins to clear out
DEPRECATED_accumulatedDustEEthShares = 0;

// All requests must be refinalized with the new withdrawal flow
lastFinalizedRequestId = 0;

roleRegistry = RoleRegistry(_roleRegistry);
finalizationCheckpoints.push(FinalizationCheckpoint(0, 0));
Expand Down Expand Up @@ -148,21 +151,21 @@ contract WithdrawRequestNFT is ERC721Upgradeable, UUPSUpgradeable, OwnableUpgrad
emit WithdrawRequestSeized(requestId);
}

/// @notice finalizes a batch of requests and locks the corresponding ETH to be withdrawn
/// @dev called by the `EtherFiAdmin` contract to finalize a batch of requests based on the last oracle report
function finalizeRequests(uint32 lastRequestId) external {
if (!roleRegistry.hasRole(WITHDRAW_NFT_ADMIN_ROLE, msg.sender)) revert IncorrectRole();

uint256 totalAmount = uint256(calculateTotalPendingAmount(lastRequestId));
uint256 cachedSharePrice = liquidityPool.amountForShare(E27_PRECISION_BASE);

finalizationCheckpoints.push(FinalizationCheckpoint(uint32(lastRequestId), cachedSharePrice));

lastFinalizedRequestId = lastRequestId;
_finalizeRequests(lastRequestId, totalAmount);
}

if (totalAmount > 0) {
liquidityPool.withdraw(address(this), totalAmount);
}
/// @notice `finalizeRequests` with the ability to specify the total amount of ETH to be locked
/// @dev The oracle calculates the amount of ETH that is needed to fulfill the pending withdrawal off-chain
function finalizeRequests(uint256 lastRequestId, uint256 totalAmount) external {
if (!roleRegistry.hasRole(WITHDRAW_NFT_ADMIN_ROLE, msg.sender)) revert IncorrectRole();

emit UpdateFinalizedRequestId(lastRequestId, totalAmount);
_finalizeRequests(lastRequestId, totalAmount);
}

function invalidateRequest(uint32 requestId) external {
Expand Down Expand Up @@ -302,7 +305,6 @@ contract WithdrawRequestNFT is ERC721Upgradeable, UUPSUpgradeable, OwnableUpgrad
return finalizationCheckpoints[checkpointId];
}


function getRequest(uint32 requestId) external view returns (IWithdrawRequestNFT.WithdrawRequest memory) {
return _requests[requestId];
}
Expand Down Expand Up @@ -342,6 +344,19 @@ contract WithdrawRequestNFT is ERC721Upgradeable, UUPSUpgradeable, OwnableUpgrad
emit WithdrawRequestClaimed(requestId, amountToWithdraw, 0, recipient);
}

function _finalizeRequests(uint256 lastRequestId, uint256 totalAmount) internal {
uint256 cachedSharePrice = liquidityPool.amountForShare(E27_PRECISION_BASE);
finalizationCheckpoints.push(FinalizationCheckpoint(uint32(lastRequestId), cachedSharePrice));

lastFinalizedRequestId = uint32(lastRequestId);

if (totalAmount > 0) {
liquidityPool.withdraw(address(this), totalAmount);
}

emit UpdateFinalizedRequestId(uint32(lastRequestId), totalAmount);
}

// invalid NFTs is non-transferable except for the case they are being burnt by the owner via `seizeInvalidRequest`
function _beforeTokenTransfer(address /*from*/, address /*to*/, uint256 firstTokenId, uint256 batchSize) internal view override {
for (uint256 i = 0; i < batchSize; i++) {
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/IWithdrawRequestNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ interface IWithdrawRequestNFT {

function invalidateRequest(uint32 requestId) external;
function finalizeRequests(uint32 lastRequestId) external;
function finalizeRequests(uint256 lastRequestId, uint256 totalAmount) external;
}
8 changes: 2 additions & 6 deletions test/WithdrawRequestNFT.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -429,15 +429,11 @@ contract WithdrawRequestNFTTest is TestSetup {
assertEq(address(chad).balance, chadBalance + claimableAmount, "Chad should receive the claimable amount");
}

function test_updated_checkpoint_logic() public payable {
for (uint256 i = 0; i < 100; i++) {
function test_updated_checkpoint_logic() public {
for (uint256 i = 0; i < 50; i++) {
address user = vm.addr(i + 1);
users.push(user);
vm.deal(user, 15 ether);
}

// first 50 users deposit
for (uint256 i = 0; i < 50; i++) {
vm.prank(users[i]);
liquidityPoolInstance.deposit{value: 1 ether}();
}
Expand Down

0 comments on commit 33de838

Please sign in to comment.