Skip to content

Commit de1b8f7

Browse files
arr000xble
andauthored
feat: membership sale (#328)
* add `SellPartyCardsAuthority` * update deploy * add a few tests * update events and add helper functions * update relevant abis * fix tests * add more tests * add more tests * update `isSaleActive` logic * move Contributed event * merge `AboveMaximumContributionsError` and `BelowMinimumContributionsError` * remove redundant initial delegate check * fix compile errors * transfer contribution to Party and fix totalContribution * update `ContributionRouter` * fix `isSaleActive` * fix tests and increase coverage * fix test * update contribute event * fix event and tests * tweaks * increase coverage * perf: optimize and refactor `SellPartyCardsAuthority` (#30) * fix tests * update delegate comments * ensure contract is an authority before sale creation * fix deploy * emit `Finalized` if not enough room for another contribution * style: rename `delegate` to `initialDelegate` * fix(`SellPartyCardsAuthority`): mitigations (#329) * Fix merge conflict --------- Co-authored-by: Brian Le <brian@brianle.xyz>
1 parent 6a1d972 commit de1b8f7

File tree

7 files changed

+1379
-5
lines changed

7 files changed

+1379
-5
lines changed

contracts/authorities/SellPartyCardsAuthority.sol

Lines changed: 670 additions & 0 deletions
Large diffs are not rendered by default.

contracts/crowdfund/ContributionRouter.sol

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pragma solidity 0.8.20;
44
import { LibAddress } from "../utils/LibAddress.sol";
55
import { LibRawResult } from "../utils/LibRawResult.sol";
66
import { InitialETHCrowdfund } from "../crowdfund/InitialETHCrowdfund.sol";
7+
import { SellPartyCardsAuthority } from "../../contracts/authorities/SellPartyCardsAuthority.sol";
78

89
contract ContributionRouter {
910
using LibRawResult for bytes;
@@ -75,11 +76,13 @@ contract ContributionRouter {
7576
assembly {
7677
target := shr(96, calldataload(sub(calldatasize(), 20)))
7778
}
78-
if (msg.sig == InitialETHCrowdfund.batchContributeFor.selector) {
79+
if (
80+
msg.sig == InitialETHCrowdfund.batchContributeFor.selector ||
81+
msg.sig == SellPartyCardsAuthority.batchContributeFor.selector
82+
) {
7983
uint256 numOfMints;
8084
assembly {
81-
// 196 is the offset of the length of `tokenIds` in the
82-
// calldata.
85+
// 196 is the offset of the array length in the calldata.
8386
numOfMints := calldataload(196)
8487
}
8588
feeAmount *= numOfMints;

contracts/utils/LibSafeCast.sol

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ library LibSafeCast {
88
error Uint256ToInt128CastOutOfRangeError(uint256 u256);
99
error Uint256ToUint128CastOutOfRangeError(uint256 u256);
1010
error Uint256ToUint40CastOutOfRangeError(uint256 u256);
11+
error Uint96ToUint16CastOutOfRange(uint96 u96);
1112

1213
function safeCastUint256ToUint96(uint256 v) internal pure returns (uint96) {
1314
if (v > uint256(type(uint96).max)) {
@@ -23,13 +24,27 @@ library LibSafeCast {
2324
return uint128(v);
2425
}
2526

27+
function safeCastUint256ToUint160(uint256 v) internal pure returns (uint160) {
28+
if (v > uint256(type(uint160).max)) {
29+
revert Uint256ToUint128CastOutOfRangeError(v);
30+
}
31+
return uint160(v);
32+
}
33+
2634
function safeCastUint256ToInt192(uint256 v) internal pure returns (int192) {
2735
if (v > uint256(uint192(type(int192).max))) {
2836
revert Uint256ToInt192CastOutOfRange(v);
2937
}
3038
return int192(uint192(v));
3139
}
3240

41+
function safeCastUint96ToUint16(uint96 v) internal pure returns (uint16) {
42+
if (v > uint96(type(uint16).max)) {
43+
revert Uint96ToUint16CastOutOfRange(v);
44+
}
45+
return uint16(v);
46+
}
47+
3348
function safeCastUint96ToInt192(uint96 v) internal pure returns (int192) {
3449
return int192(uint192(v));
3550
}

deploy/Deploy.s.sol

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import "../contracts/market-wrapper/NounsMarketWrapper.sol";
3131
import { AtomicManualParty } from "../contracts/crowdfund/AtomicManualParty.sol";
3232
import { ContributionRouter } from "../contracts/crowdfund/ContributionRouter.sol";
3333
import { AddPartyCardsAuthority } from "../contracts/authorities/AddPartyCardsAuthority.sol";
34+
import { SellPartyCardsAuthority } from "../contracts/authorities/SellPartyCardsAuthority.sol";
3435
import { SSTORE2MetadataProvider } from "../contracts/renderers/SSTORE2MetadataProvider.sol";
3536
import { BasicMetadataProvider } from "../contracts/renderers/BasicMetadataProvider.sol";
3637
import "./LibDeployConstants.sol";
@@ -81,6 +82,7 @@ abstract contract Deploy {
8182
AtomicManualParty public atomicManualParty;
8283
ContributionRouter public contributionRouter;
8384
AddPartyCardsAuthority public addPartyCardsAuthority;
85+
SellPartyCardsAuthority public sellPartyCardsAuthority;
8486

8587
function deploy(LibDeployConstants.DeployConstants memory deployConstants) public virtual {
8688
_switchDeployer(DeployerRole.Default);
@@ -349,6 +351,15 @@ abstract contract Deploy {
349351
_trackDeployerGasAfter();
350352
console.log(" Deployed - AddPartyCardsAuthority", address(addPartyCardsAuthority));
351353

354+
// DEPLOY_SELL_PARTY_CARDS_AUTHORITY
355+
console.log("");
356+
console.log("### SellPartyCardsAuthority");
357+
console.log(" Deploying - SellPartyCardsAuthority");
358+
_trackDeployerGasBefore();
359+
sellPartyCardsAuthority = new SellPartyCardsAuthority();
360+
_trackDeployerGasAfter();
361+
console.log(" Deployed - SellPartyCardsAuthority", address(sellPartyCardsAuthority));
362+
352363
// DEPLOY_BATCH_BUY_OPERATOR
353364
console.log("");
354365
console.log("### CollectionBatchBuyOperator");
@@ -685,7 +696,7 @@ contract DeployScript is Script, Deploy {
685696
Deploy.deploy(deployConstants);
686697
vm.stopBroadcast();
687698

688-
AddressMapping[] memory addressMapping = new AddressMapping[](28);
699+
AddressMapping[] memory addressMapping = new AddressMapping[](29);
689700
addressMapping[0] = AddressMapping("Globals", address(globals));
690701
addressMapping[1] = AddressMapping("TokenDistributor", address(tokenDistributor));
691702
addressMapping[2] = AddressMapping(
@@ -741,6 +752,10 @@ contract DeployScript is Script, Deploy {
741752
"AddPartyCardsAuthority",
742753
address(addPartyCardsAuthority)
743754
);
755+
addressMapping[28] = AddressMapping(
756+
"SellPartyCardsAuthority",
757+
address(sellPartyCardsAuthority)
758+
);
744759

745760
console.log("");
746761
console.log("### Deployed addresses");

0 commit comments

Comments
 (0)