GovernanceMothership - notifyFor allows to arbitrarily create new or override other users stake in governance modules Unverified
The `notify*` methods are called to update linked governance modules when an accounts stake changes in the Mothership. The linked modules then update their own balances of the user to accurately reflect the account's real stake in the Mothership.\\nBesides `notify` there's also a method named `notifyFor` which is publicly accessible. It is assumed that the method should be used similar to `notify` to force an update for another account's balance.\\nHowever, invoking the method forces an update in the linked modules for the provided address, but takes `balanceOf(msg.sender)` instead of `balanceOf(account)`. This allows malicious actors to:\\nArbitrarily change other accounts stake in linked governance modules (e.g. zeroing stake, increasing stake) based on the callers stake in the mothership\\nDuplicate stake out of thin air to arbitrary addresses (e.g. staking in mothership once and calling `notifyFor` many other account addresses)\\npublicly accessible method allows forcing stake updates for arbitrary users\\n```\\nfunction notifyFor(address account) external {\\n    \\_notifyFor(account, balanceOf(msg.sender));\\n}\\n```\\n\\nthe method calls the linked governance modules\\n```\\nfunction \\_notifyFor(address account, uint256 balance) private {\\n    uint256 modulesLength = \\_modules.length();\\n    for (uint256 i = 0; i < modulesLength; ++i) {\\n        IGovernanceModule(\\_modules.at(i)).notifyStakeChanged(account, balance);\\n    }\\n}\\n```\\n\\nwhich will arbitrarily `mint` or `burn` stake in the `BalanceAccounting` of `Factory` or `Reward` (or other linked governance modules)\\n```\\nfunction notifyStakeChanged(address account, uint256 newBalance) external override onlyMothership {\\n    \\_notifyStakeChanged(account, newBalance);\\n}\\n```\\n\\n```\\nfunction \\_notifyStakeChanged(address account, uint256 newBalance) internal override {\\n    uint256 balance = balanceOf(account);\\n    if (newBalance > balance) {\\n        \\_mint(account, newBalance.sub(balance));\\n    } else if (newBalance < balance) {\\n        \\_burn(account, balance.sub(newBalance));\\n    } else {\\n        return;\\n    }\\n    uint256 newTotalSupply = totalSupply();\\n\\n    \\_defaultFee.updateBalance(account, \\_defaultFee.votes[account], balance, newBalance, newTotalSupply, \\_DEFAULT\\_FEE, \\_emitDefaultFeeVoteUpdate);\\n    \\_defaultSlippageFee.updateBalance(account, \\_defaultSlippageFee.votes[account], balance, newBalance, newTotalSupply, \\_DEFAULT\\_SLIPPAGE\\_FEE, \\_emitDefaultSlippageFeeVoteUpdate);\\n    \\_defaultDecayPeriod.updateBalance(account, \\_defaultDecayPeriod.votes[account], balance, newBalance, newTotalSupply, \\_DEFAULT\\_DECAY\\_PERIOD, \\_emitDefaultDecayPeriodVoteUpdate);\\n    \\_referralShare.updateBalance(account, \\_referralShare.votes[account], balance, newBalance, newTotalSupply, \\_DEFAULT\\_REFERRAL\\_SHARE, \\_emitReferralShareVoteUpdate);\\n    \\_governanceShare.updateBalance(account, \\_governanceShare.votes[account], balance, newBalance, newTotalSupply, \\_DEFAULT\\_GOVERNANCE\\_SHARE, \\_emitGovernanceShareVoteUpdate);\\n}\\n```\\n\\n```\\nfunction \\_notifyStakeChanged(address account, uint256 newBalance) internal override updateReward(account) {\\n    uint256 balance = balanceOf(account);\\n    if (newBalance > balance) {\\n        \\_mint(account, newBalance.sub(balance));\\n    } else if (newBalance < balance) {\\n        \\_burn(account, balance.sub(newBalance));\\n    }\\n}\\n```\\n
Remove `notifyFor` or change it to take the balance of the correct account `_notifyFor(account, balanceOf(msg.sender))`.\\nIt is questionable whether the public `notify*()` family of methods is actually needed as stake should only change - and thus an update of linked modules should only be required - if an account calls `stake()` or `unstake()`. It should therefore be considered to remove `notify()`, `notifyFor` and `batchNotifyFor`.
```\\nfunction notifyFor(address account) external {\\n    \\_notifyFor(account, balanceOf(msg.sender));\\n}\\n```\\n