-
Notifications
You must be signed in to change notification settings - Fork 0
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 change reward threshold in live contract. Closes #80 #81
Add change reward threshold in live contract. Closes #80 #81
Conversation
oldBalance <= minBalanceForTransfer | ||
|| !participantIsReadyForTransfer(participant) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it safe to skip the check !participantIsReadyForTransfer(participant)
? I understand that oldBalance <= minBalanceForTransfer
costs less gas than participantIsReadyForTransfer
, which is a good optimisation.
I am struggling to understand if this is correct, though.
Situations to consider:
- minBalanceForTransfer is increased
- minBalanceForTransfer is decreased
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the min balance for transfer is increased
- participants that were below the threshold
- nothing happens, as they are now even further below the threshold
- participants that were above the threshold before
- and will be above the threshold after
- they will stay in the array and not be added twice, as the situation is as if the threshold was never changed
- and will be below the threshold after
- they are kept in the
readyForTransfer
structure, and not removed. I think that's ok. They won't be added twice either (their old balance can't be below the threshold if they were already above it, and they are in the array of readyToTransfer participants)
- they are kept in the
- and will be above the threshold after
If the min balance for transfer is decreased
- participants that were above the threshold
- will stay in
readyForTransfer
, and not be removed (this code path doesn't exist) - will not be added twice, as
oldbalance <= minBalanceForTransfer
is false (they were already above the previous higher threshold)- as is
!participantIsReadyForTransfer(..)
(they are already in the array)
- will stay in
- participants that were below the threshold
- if they are still below the threshold, nothing happens
- if they are now above the threshold, they are marked as ready
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll need to think about this a bit.
In the meantime, what do you think about adding tests for the different situations you described above? This would ensure that the implementation handles them exactly as it should.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all covered in passing tests now, no contract changes necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
participants that were above the threshold before
and will be below the threshold after
they are kept in the readyForTransfer structure, and not removed. I think that's ok.
This means that we will pay rewards to these participants on the next payout cycle even though they don't meet the new threshold requirement.
I don't have a strong opinion about whether this is ok or not; I am happy to follow your decision.
I think it's worth adding a code comment to explain that this behaviour is intentional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is there in tests, to me that's good enough - if one would change the logic, this test would start failing. Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can fix this if it becomes a problem
vm.expectRevert(); | ||
impactEvaluator.readyForTransfer(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do these two lines do?
Shouldn't we assert that impactEvaluator.readyForTransfer(2)
returns false
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are trying to assert that there are only 2 participants ready for transfer, then I think the following check is easier to understand and probably produces more helpful error message too.
assertEq(impactEvaluator.participantCountReadyForTransfer(), 2)
See
impact-evaluator/src/Balances.sol
Lines 21 to 23 in 087c50d
function participantCountReadyForTransfer() public view returns (uint) { | |
return readyForTransfer.length; | |
} |
Alternatively:
assertEq(impactEvaluator.readyForTransfer.length, 2)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do these two lines do?
Shouldn't we assert that impactEvaluator.readyForTransfer(2) returns false?
Context is important: The line above tells the compiler that the next line should throw. This function is none that we provided, it's how Solidity exposes public arrays to contract consumers. It's effectively return array[index]
but throws if index
can't be found.
Here we want to assert how many participants are ready for transfer, and what their addresses are.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we want to assert how many participants are ready for transfer, and what their addresses are.
Yes, that was my assumption too.
I am trying to say that the following code makes your intent more explicit / easier to understand, especially for people unfamiliar with solidity testing, like me.
assertEq(impactEvaluator.readyForTransfer.length, 2)
Compare that with your current version
vm.expectRevert();
impactEvaluator.readyForTransfer(2);
Anyhow, this is not a big deal; feel free to keep what you have now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertEq(impactEvaluator.readyForTransfer.length, 2)
This one isn't available in array getters, you can only get an element at an index
If you have anything more to add, hindsight please :) |
Closes #80
If the new balance is above the threshold and the participant isn't yet in the list of participants ready for transfer, add them. This is a good UX improvement, while only making
setScores()
a tad more expensive.