-
Notifications
You must be signed in to change notification settings - Fork 33
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
feat: add new distributor #377
Open
0xble
wants to merge
15
commits into
main
Choose a base branch
from
feat/rooms-distributor
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+868
−2
Open
Changes from 10 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
2be91b2
add new distributor
0xble 1f92bfd
add updated proposal execution engine
arr00 60391db
fix distributor
0xble 24752c8
add tests for `getIntrinsicVotingPowerAt`
arr00 c153ed7
check edge cases
arr00 1a7704c
update comments
arr00 7ec5d52
add happy path tests
0xble 2b6250e
Make `getIntrinsicVotingPowerAt` view
arr00 f1a13b0
fix issues and add edge case tests
0xble 7c2c5c5
address feedback
0xble b2ca09c
Verify revert message
arr00 8b67ebb
delete unused error and update tests
0xble 3901c52
mitigations: Rooms distributor (#378)
0xble ba5411f
Add to deploy
arr00 0befa6c
Merge branch 'main' into feat/rooms-distributor
arr00 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity 0.8.20; | ||
|
||
import { Party } from "./../party/Party.sol"; | ||
import { PartyGovernance } from "./../party/PartyGovernance.sol"; | ||
import { ProposalExecutionEngine } from "./../proposals/ProposalExecutionEngine.sol"; | ||
import { IERC20 } from "../tokens/IERC20.sol"; | ||
import { LibSafeCast } from "../utils/LibSafeCast.sol"; | ||
import { LibERC20Compat } from "./../utils/LibERC20Compat.sol"; | ||
import { LibAddress } from "./../utils/LibAddress.sol"; | ||
|
||
contract PushDistributor { | ||
event Distributed(Party party, IERC20 token, address[] members, uint256 amount); | ||
|
||
error NotEnoughETH(uint256 expectedAmount, uint256 receivedAmount); | ||
error UnexpectedETH(uint256 amount); | ||
error WrongProposalId(uint256 proposalId); | ||
error WrongMembers(); | ||
error MembersNotSorted(); | ||
|
||
using LibSafeCast for uint256; | ||
using LibERC20Compat for IERC20; | ||
using LibAddress for address payable; | ||
|
||
// Token address used to indicate ETH. | ||
IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); | ||
|
||
function distribute( | ||
IERC20 token, | ||
address[] memory members, | ||
uint256 amount, | ||
uint256 proposalId | ||
) external payable { | ||
Party party = Party(payable(msg.sender)); | ||
if (token == ETH_ADDRESS && msg.value < amount) revert NotEnoughETH(amount, msg.value); | ||
|
||
0xble marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uint40 proposedTime; | ||
uint96 totalVotingPower; | ||
{ | ||
(, PartyGovernance.ProposalStateValues memory proposal) = party.getProposalStateInfo( | ||
proposalId | ||
); | ||
|
||
if (proposal.executedTime != block.timestamp) revert WrongProposalId(proposalId); | ||
|
||
proposedTime = proposal.proposedTime; | ||
totalVotingPower = proposal.totalVotingPower; | ||
} | ||
|
||
address prevMember; | ||
uint96 totalIntrinsicVotingPower; | ||
for (uint256 i = 0; i < members.length; i++) { | ||
address member = members[i]; | ||
|
||
// Prevent duplicate members to prevent members array manipulation. | ||
// For example, a member being replace with another duplicate member | ||
// that has the same voting power. | ||
if (member <= prevMember) revert MembersNotSorted(); | ||
|
||
prevMember = member; | ||
|
||
uint96 intrinsicVotingPower = ProposalExecutionEngine(address(party)) | ||
.getIntrinsicVotingPowerAt(member, proposedTime, 0); | ||
|
||
totalIntrinsicVotingPower += intrinsicVotingPower; | ||
|
||
uint256 shareAmount = (amount * intrinsicVotingPower) / totalVotingPower; | ||
|
||
if (shareAmount > 0) { | ||
// Transfer the share of the distribution to the member. | ||
_transfer(token, member, shareAmount); | ||
} | ||
} | ||
|
||
// If the total intrinsic voting power is not equal to the total voting power, | ||
// it means that the members array is incorrect. | ||
if (totalIntrinsicVotingPower != totalVotingPower) revert WrongMembers(); | ||
|
||
// Send back any remaining ETH to the sender. | ||
uint256 remainingAmount = address(this).balance; | ||
if (remainingAmount > 0) { | ||
_transfer(ETH_ADDRESS, msg.sender, remainingAmount); | ||
} | ||
|
||
emit Distributed(party, token, members, amount); | ||
} | ||
|
||
function _transfer(IERC20 token, address to, uint256 amount) internal { | ||
if (token == ETH_ADDRESS) { | ||
// Do not revert on failure. Set gas to 100k to prevent consuming | ||
// all gas. | ||
to.call{ value: amount, gas: 100_000 }(""); | ||
} else { | ||
token.compatTransferFrom(msg.sender, to, amount); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule forge-std
updated
26 files
+1 −0 | .gitattributes | |
+0 −4 | .github/workflows/ci.yml | |
+1 −1 | package.json | |
+635 −0 | scripts/vm.py | |
+1 −1 | src/Script.sol | |
+23 −4 | src/StdChains.sol | |
+111 −10 | src/StdCheats.sol | |
+15 −0 | src/StdInvariant.sol | |
+18 −14 | src/StdJson.sol | |
+54 −3 | src/StdStorage.sol | |
+61 −33 | src/StdUtils.sol | |
+1 −2 | src/Test.sol | |
+978 −376 | src/Vm.sol | |
+216 −0 | src/mocks/MockERC20.sol | |
+221 −0 | src/mocks/MockERC721.sol | |
+93 −77 | test/StdAssertions.t.sol | |
+93 −37 | test/StdChains.t.sol | |
+124 −60 | test/StdCheats.t.sol | |
+13 −11 | test/StdError.t.sol | |
+27 −12 | test/StdMath.t.sol | |
+66 −34 | test/StdStorage.t.sol | |
+4 −4 | test/StdStyle.t.sol | |
+66 −36 | test/StdUtils.t.sol | |
+15 −0 | test/Vm.t.sol | |
+441 −0 | test/mocks/MockERC20.t.sol | |
+721 −0 | test/mocks/MockERC721.t.sol |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Would like detailed natspec here. It's a pretty advanced function. Otherwise PR looks good.