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 SnapshotStakingPool and SignedSnapshotStakingPool #2

Merged
merged 12 commits into from
Jul 4, 2024

Conversation

pblivin0x
Copy link
Contributor

No description provided.

Copy link
Contributor

@ckoopmann ckoopmann left a comment

Choose a reason for hiding this comment

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

Mainly commented on the EIP712 signature mechanism.
I might be misunderstanding the reason why we are doing this, but from a security / cryptography perspective the current way we use it is superflous. (see comments below).

Generally snapshot / staking logic LGTM, also assuming that it didn't change significantly from my last review.

src/SnapshotStakingPool.sol Outdated Show resolved Hide resolved
src/SnapshotStakingPool.sol Outdated Show resolved Hide resolved
Copy link
Contributor

@ckoopmann ckoopmann left a comment

Choose a reason for hiding this comment

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

LGTM. Great work. I especially like the inheritance structure, very clean indeed.

Only added some minor nit picks / questions as well as the suggestion of maybe utilizing custom errors in some cases.

import {ISignedSnapshotStakingPool} from "../interfaces/staking/ISignedSnapshotStakingPool.sol";

import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
Copy link
Contributor

Choose a reason for hiding this comment

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

Great find of this SignatureChecker library with both ECDSA and SC signature support. Just what we needed 👍


/* EVENTS */

event DistributorChanged(address newDistributor);
Copy link
Contributor

Choose a reason for hiding this comment

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

Super small nit. Just for completeness sake we might want to add 1 line docs for each event.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added here e68a09d

function accrue(uint256 amount) external nonReentrant onlyDistributor {
require(amount > 0, "Cannot accrue 0");
require(totalSupply() > 0, "Cannot accrue with 0 staked supply");
require(canAccrue(), "Snapshot delay not passed");
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we are using solidity > 0.8 we could use Custom errors that can take extra parameters. (for example in this case you could add the time when the delay would have passed as error parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added custom errors here 0697f39

uint256 currentId = _getCurrentSnapshotId();
uint256 lastId = nextClaimId[msg.sender];
uint256 amount = rewardOfInRange(msg.sender, lastId, currentId);
require(amount > 0, "No rewards to claim");
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 really need to revert here ? Is there any scenario where people might want to claim snapshots without any rewards ? What is the downside of just returning 0 rewards ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed here 0697f39

/// @inheritdoc ISnapshotStakingPool
function claimPartial(uint256 startSnapshotId, uint256 endSnapshotId) public nonReentrant {
require(startSnapshotId >= nextClaimId[msg.sender], "Cannot claim from past snapshots");
uint256 amount = rewardOfInRange(msg.sender, startSnapshotId, endSnapshotId);
Copy link
Contributor

Choose a reason for hiding this comment

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

Line 113- 116 seem to be identical with the last couple of lines in claim. Maybe we can factor out to an internal function ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cleaned up here 0697f39

require(startSnapshotId <= endSnapshotId && endSnapshotId <= _getCurrentSnapshotId(), "Cannot claim from future snapshots");

uint256 rewards = 0;
for (uint256 i = startSnapshotId; i <= endSnapshotId; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting that the range here includes both the start and end value. Nothing wrong with that just have to keep it in mind since this might be different to what people are used to.

(Also wondering if doing i < endSnapshotId + 1 might save gas or would compile to the same bytecode)
Regarding gas, also I remember ++i being cheaper than i++ (and functionally equivalent in this case). Although not sure if this is still the case with solidity 0.8

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 things are a bit wonky with the 1 based indexing of ERC20Snapshot - open to suggestions on what could be more readable

/// @inheritdoc ISnapshotStakingPool
function rewardOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {
require(snapshotId > 0, "ERC20Snapshot: id is 0");
require(snapshotId <= _getCurrentSnapshotId(), "Cannot claim from future snapshots");
Copy link
Contributor

Choose a reason for hiding this comment

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

Another example where Custom errors with parameters might be helpful.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added custom errors here 0697f39

@pblivin0x pblivin0x changed the title Add SnapshotStakingPool Add SnapshotStakingPool and SignedSnapshotStakingPool Jul 3, 2024
@pblivin0x pblivin0x marked this pull request as ready for review July 3, 2024 18:39
Copy link
Contributor

@ckoopmann ckoopmann left a comment

Choose a reason for hiding this comment

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

Great work. Can't find anything to complain. Let's send it out for audit.

@pblivin0x pblivin0x merged commit 93ee6d1 into main Jul 4, 2024
1 check passed
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