forked from PartyDAO/party-protocol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CrowdfundFactory.sol
120 lines (110 loc) · 4.92 KB
/
CrowdfundFactory.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
import "../globals/IGlobals.sol";
import "../utils/LibRawResult.sol";
import "../utils/Proxy.sol";
import "../renderers/RendererStorage.sol";
import "./AuctionCrowdfund.sol";
import "./BuyCrowdfund.sol";
import "./CollectionBuyCrowdfund.sol";
/// @notice Factory used to deploys new proxified `Crowdfund` instances.
contract CrowdfundFactory {
using LibRawResult for bytes;
event BuyCrowdfundCreated(BuyCrowdfund crowdfund, BuyCrowdfund.BuyCrowdfundOptions opts);
event AuctionCrowdfundCreated(
AuctionCrowdfund crowdfund,
AuctionCrowdfund.AuctionCrowdfundOptions opts
);
event CollectionBuyCrowdfundCreated(
CollectionBuyCrowdfund crowdfund,
CollectionBuyCrowdfund.CollectionBuyCrowdfundOptions opts
);
// The `Globals` contract storing global configuration values. This contract
// is immutable and it’s address will never change.
IGlobals private immutable _GLOBALS;
// Set the `Globals` contract.
constructor(IGlobals globals) {
_GLOBALS = globals;
}
/// @notice Create a new crowdfund to purchase a specific NFT (i.e., with a
/// known token ID) listing for a known price.
/// @param opts Options used to initialize the crowdfund. These are fixed
/// and cannot be changed later.
/// @param createGateCallData Encoded calldata used by `createGate()` to
/// create the crowdfund if one is specified in `opts`.
function createBuyCrowdfund(
BuyCrowdfund.BuyCrowdfundOptions memory opts,
bytes memory createGateCallData
) public payable returns (BuyCrowdfund inst) {
opts.gateKeeperId = _prepareGate(opts.gateKeeper, opts.gateKeeperId, createGateCallData);
inst = BuyCrowdfund(
payable(
new Proxy{ value: msg.value }(
_GLOBALS.getImplementation(LibGlobals.GLOBAL_BUY_CF_IMPL),
abi.encodeCall(BuyCrowdfund.initialize, (opts))
)
)
);
emit BuyCrowdfundCreated(inst, opts);
}
/// @notice Create a new crowdfund to bid on an auction for a specific NFT
/// (i.e. with a known token ID).
/// @param opts Options used to initialize the crowdfund. These are fixed
/// and cannot be changed later.
/// @param createGateCallData Encoded calldata used by `createGate()` to create
/// the crowdfund if one is specified in `opts`.
function createAuctionCrowdfund(
AuctionCrowdfund.AuctionCrowdfundOptions memory opts,
bytes memory createGateCallData
) public payable returns (AuctionCrowdfund inst) {
opts.gateKeeperId = _prepareGate(opts.gateKeeper, opts.gateKeeperId, createGateCallData);
inst = AuctionCrowdfund(
payable(
new Proxy{ value: msg.value }(
_GLOBALS.getImplementation(LibGlobals.GLOBAL_AUCTION_CF_IMPL),
abi.encodeCall(AuctionCrowdfund.initialize, (opts))
)
)
);
emit AuctionCrowdfundCreated(inst, opts);
}
/// @notice Create a new crowdfund to purchase any NFT from a collection
/// (i.e. any token ID) from a collection for a known price.
/// @param opts Options used to initialize the crowdfund. These are fixed
/// and cannot be changed later.
/// @param createGateCallData Encoded calldata used by `createGate()` to create
/// the crowdfund if one is specified in `opts`.
function createCollectionBuyCrowdfund(
CollectionBuyCrowdfund.CollectionBuyCrowdfundOptions memory opts,
bytes memory createGateCallData
) public payable returns (CollectionBuyCrowdfund inst) {
opts.gateKeeperId = _prepareGate(opts.gateKeeper, opts.gateKeeperId, createGateCallData);
inst = CollectionBuyCrowdfund(
payable(
new Proxy{ value: msg.value }(
_GLOBALS.getImplementation(LibGlobals.GLOBAL_COLLECTION_BUY_CF_IMPL),
abi.encodeCall(CollectionBuyCrowdfund.initialize, (opts))
)
)
);
emit CollectionBuyCrowdfundCreated(inst, opts);
}
function _prepareGate(
IGateKeeper gateKeeper,
bytes12 gateKeeperId,
bytes memory createGateCallData
) private returns (bytes12 newGateKeeperId) {
if (address(gateKeeper) == address(0) || gateKeeperId != bytes12(0)) {
// Using an existing gate on the gatekeeper
// or not using a gate at all.
return gateKeeperId;
}
// Call the gate creation function on the gatekeeper.
(bool s, bytes memory r) = address(gateKeeper).call(createGateCallData);
if (!s) {
r.rawRevert();
}
// Result is always a bytes12.
return abi.decode(r, (bytes12));
}
}