Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mock contracts for StEth, WstEth, WithdrawalQueue for testing the DG setup on Holesky #143

Open
wants to merge 4 commits into
base: develop-archive
Choose a base branch
from

Conversation

sandstone-ag
Copy link
Contributor

Add mock contracts for StEth, WstEth, WithdrawalQueue for testing the DG setup on Holesky

import {PercentD16, HUNDRED_PERCENT_D16} from "contracts/types/PercentD16.sol";

/* solhint-disable no-unused-vars,custom-errors */
contract StETHMock is ERC20, IStETH {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose using the StETH contract as the base for the mock. It’s straightforward, with minimal dependencies, and migrating from version 0.4.24 shouldn’t be difficult. This approach will also add clarity to the implementation. The current mock is somewhat misleading because it stores share information in the balances mapping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

address private deployer;

function run() external {
if (17000 != block.chainid) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it important which chain the mocks are deployed on? It seems they aren’t tied to any specific contracts on a particular chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script and contracts are not intended for use on mainnet, but it can be used on any testnet if needed. So I changed the check and error message.

///

IStETH public ST_ETH;
address payable private refundAddress;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Private and internal variables and methods of the contracts (in libraries only private) should use an underscore (_) prefix, as recommended in the Solidity style guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

function rebaseTotalPooledEther(PercentD16 rebaseFactor) public {
totalPooledEther = PercentD16.unwrap(rebaseFactor) * totalPooledEther / HUNDRED_PERCENT_D16;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to use PercentD16.toUint256() instead of unwrap()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return lastCheckpointIndex;
}

function requestWithdrawals(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To match the original contract, it would be nice also to revert if the contract is paused.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


if (request.claimed) revert RequestAlreadyClaimed(_requestId);

// NB! This allows claim for anyone! // if (request.owner != msg.sender) revert NotOwner(msg.sender, request.owner);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to preserve the original behavior. Why do we need to remove this check from the mock?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

assert(requestsByOwner[request.owner].remove(_requestId));

uint256 ethWithDiscount = _calculateClaimableEther(request, _requestId, _hint);
lockedEtherAmount = lockedEtherAmount - ethWithDiscount;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: lockedEtherAmount -= ethWithDiscount;

WithdrawalRequest storage request = queue[_requestId];
if (request.claimed) revert RequestAlreadyClaimed(_requestId);

// NB! This allows transfer for anyone // if (_from != request.owner) revert TransferFromIncorrectOwner(_from, request.owner);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should transferring to itself be allowed in the mock?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

WithdrawalRequest memory lastFinalizedRequest = queue[lastFinalizedRequestId];
WithdrawalRequest memory requestToFinalize = queue[_lastRequestIdToBeFinalized];

uint128 stETHToFinalize = requestToFinalize.cumulativeStETH - lastFinalizedRequest.cumulativeStETH;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original contract has a check that _amountOfETH <= stETHToFinalize. Is it safe to remove it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's safe IMO. This implementation allows to receive an arbitrary amount of ether for finalization, and it allows to claim only previously requested amount of ether. The excessive (not claimable) ether amount stored in the UnsafeWithdrawalQueueMock can be returned to a special refund address using the method refundEth(). I think this logic is much simpler for further usage in manual tests.

stETH = _stETH;
}

function mint(address account, uint256 amount) external {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

burn and mint are not needed for the wstETH token, the wrap and unwrap methods should be used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@sandstone-ag sandstone-ag changed the base branch from develop to develop-archive November 11, 2024 10:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants