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

Feat/rename waterfall to OptimisticWithdrawalRecipient #62

Merged
merged 17 commits into from
Aug 10, 2023

Conversation

samparsky
Copy link
Collaborator

Fixes #60

Copy link
Contributor

@OisinKyne OisinKyne left a comment

Choose a reason for hiding this comment

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

A couple stupid questions, a couple nitpicks, and maybe one restructuring of a function selector to consider. Happy for you to decide yes or no on my suggestions and to simply merge, unless you want to discuss something raised here.

Comment on lines +34 to +38
seed = keccak256(abi.encodePacked(seed));
principal = address(bytes20(seed));

seed = keccak256(abi.encodePacked(seed));
reward = address(bytes20(seed));
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't this result in principal and reward being the same address if they are deterministically generated from the same seed? And will that not mess up tests?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

they are different addresses the first seed = ... changes the seed for the second call


owrFactoryModule = new OptimisticWithdrawalRecipientFactory();

nonOWRRecipient = makeAddr("nonOWRRecipient");
Copy link
Contributor

Choose a reason for hiding this comment

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

Super pointless nitpick: R is present in the acronym and Recipient, expands to nonOptimisticWithdrawalRecipientRecipient.

You can probably ignore this, its literally free text for ad address creator :)


nonOWRRecipient = makeAddr("nonOWRRecipient");
(principalRecipient, rewardRecipient) = generateTrancheRecipients(10);
threshold = ETH_STAKE;
Copy link
Contributor

Choose a reason for hiding this comment

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

Where does this constant come from? (just because its non obvious to me) And does it matter that threshold is declared as uint256 here, while we are going to have to bitpack it into uint96 when we call the factory with it?

Copy link
Contributor

Choose a reason for hiding this comment

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

I see now that the arg is uint256 but that it will revert if the number is bigger than uint96, is that annoying/a good design?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

a couple of constants are declared in the OWRTestHelper contract which is inherited by the test suite

Copy link
Collaborator Author

@samparsky samparsky Aug 10, 2023

Choose a reason for hiding this comment

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

I see now that the arg is uint256 but that it will revert if the number is bigger than uint96, is that annoying/a good design?

I'm not sure which is cheaper, doing the type check manually or the EVM doing it. Also, we are able to set a custom error if we do the check ourselves

/// @return owr Address of new OptimisticWithdrawalRecipient clone
function createOWRecipient(
address token,
address nonOWRecipient,
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we maybe want to call this recoveryAddress? We should also include in the natspec an explainer like:

"If this address is 0x0, recovery of unrelated tokens can be completed by either the principal or reward recipients. If this address is set, only this address can recover tokens (or ether) that are not the focus of this OWRecipient contract"

Copy link
Contributor

Choose a reason for hiding this comment

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

Also I would probably make it the second last arg in the function, just because it feels right to specify the important ones first. And I assume if we made it the last arg we might end up with weird word sizes or something.

event WaterfallFunds(
address[] recipients, uint256[] payouts, uint256 pullFlowFlag
event DistributeFunds(
uint256[] payouts, uint256 pullFlowFlag
Copy link
Contributor

Choose a reason for hiding this comment

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

Can the second arg here be a boolean rather than uint256?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or like a smaller uint? That might neccessitate the payouts array being a uint smaller than 256 as well, but I think I am overthinking things here, might not be worth it.

Copy link
Collaborator Author

@samparsky samparsky Aug 10, 2023

Choose a reason for hiding this comment

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

events arguments take an entire word size in the evm 32 bytes, so using bool or uint256 doesn't really matter

I'd think uint256 will be cheaper cos the EVM doesn't have to do additional expansion

}

/// Get waterfall tranche `i`
/// Get OWR tranche `i`
/// @dev emulates to uint256[] internal immutable tranche;
function _getTranche(uint256 i) internal pure returns (uint256) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume this is a requirement for a CloneWithImmutableArgs design, but it seems weird to me. Its internal so I guess it can't be abused too much either, but I assume if you give anything other than 0 or 1 to this method, you'll get a nonsensical response for a tranche, yes? Is that a risk?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I believe it's not possible to pass anything other than 0 or 1 to the method because it's an internal method.

/// -----------------------------------------------------------------------
/// storage - mutables
/// -----------------------------------------------------------------------

/// Amount of distributed waterfall token
/// Amount of distributed OWRecipient token
/// @dev ERC20s with very large decimals may overflow & cause issues
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we clarify that this contract will break beyond uint96?

/// @dev can PUSH or PULL funds to recipients
function _waterfallFunds(uint256 pullFlowFlag) internal {
function _distributeFunds(uint256 pullFlowFlag) internal {
Copy link
Contributor

Choose a reason for hiding this comment

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

Any gas to be saved by changing the param down to boolean or uint16 or something?

@samparsky samparsky merged commit 009cf98 into main Aug 10, 2023
1 check passed
@OisinKyne OisinKyne deleted the feat/rename-waterfall branch October 10, 2023 09:07
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.

Rename WaterfallModule contract to OptimisticWithdrawalRecipient
2 participants