Skip to content

Commit

Permalink
feat: disable distributions from the protocol (#372)
Browse files Browse the repository at this point in the history
  • Loading branch information
arr00 authored Jan 3, 2024
1 parent cce0ea5 commit 5413bbd
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 53 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,3 @@ jobs:
run: forge install
- name: Check contract deployable mainnet
run: "node js/contracts-deployable.js --via-ir --optimize --optimizer-runs 0"
- name: Check contracts deployable base
run: "node js/contracts-deployable.js --via-ir --optimize --optimizer-runs 0 --evm-version paris"
9 changes: 9 additions & 0 deletions contracts/authorities/BondingCurveAuthority.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { PartyFactory } from "../party/PartyFactory.sol";
import { IERC721 } from "../tokens/IERC721.sol";
import { MetadataProvider } from "../renderers/MetadataProvider.sol";
import { LibSafeCast } from "contracts/utils/LibSafeCast.sol";
import { ProposalStorage } from "contracts/proposals/ProposalStorage.sol";

contract BondingCurveAuthority {
using LibSafeCast for uint256;
Expand All @@ -23,6 +24,7 @@ contract BondingCurveAuthority {
error ExcessSlippage();
error AddAuthorityProposalNotSupported();
error SellZeroPartyCards();
error DistributionsNotSupported();

event TreasuryFeeUpdated(uint16 previousTreasuryFee, uint16 newTreasuryFee);
event PartyDaoFeeUpdated(uint16 previousPartyDaoFee, uint16 newPartyDaoFee);
Expand Down Expand Up @@ -229,6 +231,13 @@ contract BondingCurveAuthority {
if (partyOpts.proposalEngine.enableAddAuthorityProposal) {
revert AddAuthorityProposalNotSupported();
}

if (
partyOpts.proposalEngine.distributionsConfig !=
ProposalStorage.DistributionsConfig.NotAllowed
) {
revert DistributionsNotSupported();
}
}

/**
Expand Down
13 changes: 4 additions & 9 deletions contracts/party/PartyGovernance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,10 @@ abstract contract PartyGovernance is
// Must not require a vote to create a distribution, otherwise
// distributions can only be created through a distribution
// proposal.
if (_getSharedProposalStorage().opts.distributionsRequireVote) {
if (
_getSharedProposalStorage().opts.distributionsConfig !=
DistributionsConfig.AllowedWithoutVote
) {
revert DistributionsRequireVoteError();
}
// Must be an active member.
Expand Down Expand Up @@ -1117,14 +1120,6 @@ abstract contract PartyGovernance is
return snapshotNumHosts > 0 && snapshotNumHosts == numHostsAccepted;
}

function _areVotesPassing(
uint96 voteCount,
uint96 totalVotingPower,
uint16 passThresholdBps
) private pure returns (bool) {
return (uint256(voteCount) * 1e4) / uint256(totalVotingPower) >= uint256(passThresholdBps);
}

function _setPreciousList(
IERC721[] memory preciousTokens,
uint256[] memory preciousTokenIds
Expand Down
8 changes: 5 additions & 3 deletions contracts/party/PartyGovernanceNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ abstract contract PartyGovernanceNFT is PartyGovernance, ERC721, IERC2981 {
name = name_;
symbol = symbol_;
if (rageQuitTimestamp_ != 0) {
if (!proposalEngineOpts.distributionsRequireVote) {
if (proposalEngineOpts.distributionsConfig == DistributionsConfig.AllowedWithoutVote) {
revert CannotEnableRageQuitIfNotDistributionsRequireVoteError();
}

Expand Down Expand Up @@ -346,8 +346,10 @@ abstract contract PartyGovernanceNFT is PartyGovernance, ERC721, IERC2981 {
}

// Prevent enabling ragequit if distributions can be created without a vote.
if (!_getSharedProposalStorage().opts.distributionsRequireVote)
revert CannotEnableRageQuitIfNotDistributionsRequireVoteError();
if (
_getSharedProposalStorage().opts.distributionsConfig ==
DistributionsConfig.AllowedWithoutVote
) revert CannotEnableRageQuitIfNotDistributionsRequireVoteError();

uint40 oldRageQuitTimestamp = rageQuitTimestamp;

Expand Down
5 changes: 4 additions & 1 deletion contracts/proposals/ProposalExecutionEngine.sol
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ contract ProposalExecutionEngine is
_getSharedProposalStorage().opts.allowArbCallsToSpendPartyEth
);
} else if (pt == ProposalType.Distribute) {
if (!_getSharedProposalStorage().opts.distributionsRequireVote) {
if (
_getSharedProposalStorage().opts.distributionsConfig !=
DistributionsConfig.AllowedWithVote
) {
revert ProposalDisabled(pt);
}

Expand Down
10 changes: 8 additions & 2 deletions contracts/proposals/ProposalStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ abstract contract ProposalStorage {
uint96 totalVotingPower;
}

enum DistributionsConfig {
AllowedWithoutVote,
AllowedWithVote,
NotAllowed
}

struct ProposalEngineOpts {
// Whether the party can add new authorities with the add authority proposal.
bool enableAddAuthorityProposal;
Expand All @@ -32,8 +38,8 @@ abstract contract ProposalStorage {
bool allowArbCallsToSpendPartyEth;
// Whether operators can be used.
bool allowOperators;
// Whether distributions require a vote or can be executed by any active member.
bool distributionsRequireVote;
// Distributions config for the party.
DistributionsConfig distributionsConfig;
}

uint256 internal constant PROPOSAL_FLAG_UNANIMOUS = 0x1;
Expand Down
25 changes: 23 additions & 2 deletions test/authorities/BondingCurveAuthority.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { PartyFactory } from "../../contracts/party/PartyFactory.sol";
import { BondingCurveAuthority } from "../../contracts/authorities/BondingCurveAuthority.sol";
import { SetupPartyHelper } from "../utils/SetupPartyHelper.sol";
import { MetadataProvider } from "contracts/renderers/MetadataProvider.sol";
import { ProposalStorage } from "../../contracts/proposals/ProposalStorage.sol";

contract BondingCurveAuthorityTest is SetupPartyHelper {
event TreasuryFeeUpdated(uint16 previousTreasuryFee, uint16 newTreasuryFee);
Expand Down Expand Up @@ -59,6 +60,7 @@ contract BondingCurveAuthorityTest is SetupPartyHelper {
opts.governance.executionDelay = 4 days;
opts.governance.passThresholdBps = 1000;
opts.governance.totalVotingPower = 0;
opts.proposalEngine.distributionsConfig = ProposalStorage.DistributionsConfig.NotAllowed;

// Set a default treasury fee
vm.prank(globalDaoWalletAddress);
Expand Down Expand Up @@ -157,7 +159,7 @@ contract BondingCurveAuthorityTest is SetupPartyHelper {
);
}

function test_creatorParty_revertAddAuthorityProposalNotSupported() external {
function test_createParty_revertAddAuthorityProposalNotSupported() external {
opts.proposalEngine.enableAddAuthorityProposal = true;

vm.expectRevert(BondingCurveAuthority.AddAuthorityProposalNotSupported.selector);
Expand All @@ -174,7 +176,26 @@ contract BondingCurveAuthorityTest is SetupPartyHelper {
);
}

function test_creatorParty_revertBelowMinExecutionDelay() external {
function test_createParty_revertDistributionsNotSupported() external {
opts.proposalEngine.distributionsConfig = ProposalStorage
.DistributionsConfig
.AllowedWithoutVote;

vm.expectRevert(BondingCurveAuthority.DistributionsNotSupported.selector);
authority.createParty(
BondingCurveAuthority.BondingCurvePartyOptions({
partyFactory: partyFactory,
partyImpl: partyImpl,
opts: opts,
creatorFeeOn: true,
a: 50_000,
b: uint80(0.001 ether)
}),
1
);
}

function test_createParty_revertBelowMinExecutionDelay() external {
opts.governance.executionDelay = 0;

vm.expectRevert(BondingCurveAuthority.ExecutionDelayTooShort.selector);
Expand Down
19 changes: 10 additions & 9 deletions test/crowdfund/CrowdfundFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import "./MockMarketWrapper.sol";
import "contracts/globals/Globals.sol";
import "contracts/globals/LibGlobals.sol";
import "contracts/renderers/MetadataRegistry.sol";
import { ProposalStorage } from "contracts/proposals/ProposalStorage.sol";
import "contracts/renderers/MetadataProvider.sol";
import { FixedPointMathLib } from "solmate/utils/FixedPointMathLib.sol";
import { LibSafeCast } from "contracts/utils/LibSafeCast.sol";
Expand Down Expand Up @@ -141,7 +142,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
})
});

Expand Down Expand Up @@ -219,7 +220,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
})
});

Expand Down Expand Up @@ -422,7 +423,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
})
});

Expand Down Expand Up @@ -495,7 +496,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
})
});

Expand Down Expand Up @@ -566,7 +567,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
})
});

Expand Down Expand Up @@ -638,7 +639,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
}),
preciousTokens: new IERC721[](0),
preciousTokenIds: new uint256[](0),
Expand Down Expand Up @@ -714,7 +715,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
}),
preciousTokens: new IERC721[](0),
preciousTokenIds: new uint256[](0),
Expand Down Expand Up @@ -804,7 +805,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
}),
preciousTokens: new IERC721[](0),
preciousTokenIds: new uint256[](0),
Expand Down Expand Up @@ -870,7 +871,7 @@ contract CrowdfundFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
}),
preciousTokens: new IERC721[](0),
preciousTokenIds: new uint256[](0),
Expand Down
2 changes: 1 addition & 1 deletion test/crowdfund/InitialETHCrowdfund.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1748,7 +1748,7 @@ contract InitialETHCrowdfundTest is InitialETHCrowdfundTestBase {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
}),
preciousTokens: new IERC721[](0),
preciousTokenIds: new uint256[](0),
Expand Down
14 changes: 10 additions & 4 deletions test/party/PartyFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ contract PartyFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
})
});
uint40 rageQuitTimestamp = uint40(block.timestamp + 30 days);
Expand Down Expand Up @@ -111,7 +111,10 @@ contract PartyFactoryTest is Test, TestUtils {
.getProposalEngineOpts();
assertEq(proposalEngineOpts.allowArbCallsToSpendPartyEth, true);
assertEq(proposalEngineOpts.allowOperators, true);
assertEq(proposalEngineOpts.distributionsRequireVote, true);
assertEq(
uint8(proposalEngineOpts.distributionsConfig),
uint8(ProposalStorage.DistributionsConfig.AllowedWithVote)
);
assertEq(party.preciousListHash(), _hashPreciousList(preciousTokens, preciousTokenIds));
}

Expand All @@ -135,7 +138,7 @@ contract PartyFactoryTest is Test, TestUtils {
enableAddAuthorityProposal: true,
allowArbCallsToSpendPartyEth: true,
allowOperators: true,
distributionsRequireVote: true
distributionsConfig: ProposalStorage.DistributionsConfig.AllowedWithVote
})
});
bytes memory customMetadata = abi.encodePacked(_randomBytes32());
Expand Down Expand Up @@ -168,7 +171,10 @@ contract PartyFactoryTest is Test, TestUtils {
.getProposalEngineOpts();
assertEq(proposalEngineOpts.allowArbCallsToSpendPartyEth, true);
assertEq(proposalEngineOpts.allowOperators, true);
assertEq(proposalEngineOpts.distributionsRequireVote, true);
assertEq(
uint8(proposalEngineOpts.distributionsConfig),
uint8(ProposalStorage.DistributionsConfig.AllowedWithVote)
);
assertEq(party.preciousListHash(), _hashPreciousList(preciousTokens, preciousTokenIds));
assertEq(address(registry.getProvider(address(party))), address(provider));
assertEq(provider.getMetadata(address(party), 0), customMetadata);
Expand Down
Loading

0 comments on commit 5413bbd

Please sign in to comment.