- One high-risk issue found, unrelated to V2, in a function no one has used to date (more info below).
- Three medium-risk issues found, all fixed as part of V2.
- Some additional low-risk and gas optimizations found as well (not summarized in this post).
- The issue is in the
delegateBySigfunction that’s part of
NounsToken, only when the delegatee is address zero (
- When this function is used to delegate to address zero, the delegator wallet loses all its Nouns votes and can no longer transfer their Nouns out of that wallet.
- To date there have been no uses of
delegateBySig; nouns.wtf and other governance clients have been using
delegatewhich doesn’t have this issue.
- To be extra safe, avoid using
delegateBySig; if you must, triple check the message you’re signing is delegating to a non-zero delegatee.
It’s a function of
NounsToken that is meant to support the use case of a Nouner signing a message with their intent to delegate, then passing that message to someone else to post on chain and pay gas.
This is part of a bigger concept of supporting “gasless transactions”, where various apps can allow you to submit transactions for free, or rather pay them for the gas in a currency other than ETH (e.g. your credit card, or some USD-pegged ERC20 token).
|Issue||Fix (already part of V2)|
|Vote gas refund could be abused with long vote reasons.||Total gas use is capped at 200K, supporting voting reason up to roughly 9,190 characters.|
|Proposals should be cancelable by anyone when proposer’s votes are less than or equal to proposal threshold.
In V1, they were not cancelable when proposer’s votes were exactly proposal threshold.
|In V2 anyone can cancel a proposal when proposer’s votes are less than or equal to proposal threshold.|
|In V1 it’s possible to burn the veto power without meaning to, if the vetoer accidentally set a new vetoer to address zero.
The main concern was that setting a new vetoer was a single step that did not check for address zero.
|In V2 setting the vetoer is a 2-step process:
1. Setting a pendingVetoer
2. pendingVetoer then needs to call acceptVetoer
Any further question? Please reach out in the #54-tech-grants Discord channel.