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

PROTO: Read voting power from chain #21

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

stepandel
Copy link
Contributor

This PR is WIP. It's an attempt to illustrate a potential algorithm for reading voting power directly from Alligator

// TODO: Should we limit the length of the chain?

// Continue building the chain recursively
for (uint i = 0; i < backwardSubdelegationKeys[current].length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

backwardSubdelegationKeys array can be infinitely and cheaply expanded for by subdelegating from multiple addresses.

loops over dynamic unbounded arrays are the reason why this approach susceptible to DOS attack, as this function can easily be made to exceed block size limit and thus voter might be unable to vote due to someone else's actions

you could try to get around it by processing n values each time, but that then requires a much more complex logic and multiple transactions which kind of defeat the purpose.

) {
k = i;
// Do the same for forwardSubdelegationKeys
if (forwardSubdelegationKeys[to].length == 0) {

Choose a reason for hiding this comment

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

It looks like potential DoS issue in case forwardSubdelegationKeys will be large enough. Similar to comment from @jjranalli regarding the backwardSubdelegationKeys.

Possible solutions:

  • Limit max number of these delegation keys?
  • Use mapping (?) - need to review if this possible.

Choose a reason for hiding this comment

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

P.S coud you please check whether EnumerableSet help us for searching purposes? It has complexity O(1) which would help for our case. We can use "contains" method

return 0;
}

uint265 proxyBalance = IVotes(OP_TOKEN).getPastVotes(proxyAddress(from), blockNumber);

Choose a reason for hiding this comment

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

looks like uint265=> uint256?

}

// Draining proxies starting from the closest to the voter
function _drainProxies(address current, uint265 remainingBalance) internal {

Choose a reason for hiding this comment

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

uint265 => 256?

if (k == 0) {
if (
subdelegationRules.allowance
< (subdelegationRules.allowanceType == AllowanceType.Relative ? 1e5 : votesToCast)

Choose a reason for hiding this comment

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

I think it's good to keep string/number repeateble values in the constants to keep code readable
e.g
uint constant public MAX_ALLOWANCE = 1e5;

@@ -212,17 +165,16 @@ contract AlligatorOPV5 is IAlligatorOPV5, UUPSUpgradeable, OwnableUpgradeable, P
* @param support The support value for the vote. 0=against, 1=for, 2=abstain
*/
function castVoteBySig(
address[] calldata authority,

Choose a reason for hiding this comment

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

It looks like authority param still presented in the doc comments while deleted in the code

@@ -235,7 +187,6 @@ contract AlligatorOPV5 is IAlligatorOPV5, UUPSUpgradeable, OwnableUpgradeable, P
* @param params The custom params of the vote
*/
function castVoteWithReasonAndParamsBySig(

Choose a reason for hiding this comment

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

It looks like authority param still presented in the doc comments while deleted in the code

}
}

function _validateAndApplyRules(address from, SubdelegationRules rules, uint256 balance) {

Choose a reason for hiding this comment

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

this function has no identifier like: private, public, internal

} else {
// Check if the address is already in the array
bool found = false;
for (uint256 i = 0; i < backwardSubdelegationKeys[from].length; i++) {

Choose a reason for hiding this comment

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

If we'll save backwardSubdelegationKeys[from].length to the local variable and use in the cycle it would be gas efficient. For instance I did some benchmark on 10-30 items:

Снимок экрана 2024-02-28 в 12 14 46

Base automatically changed from dev to main April 5, 2024 01:26
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.

3 participants