Skip to content

Commit c976a12

Browse files
committed
feat: sponsorship campaigns
1 parent 4ba236d commit c976a12

File tree

6 files changed

+80
-122
lines changed

6 files changed

+80
-122
lines changed

broadcast/10_Deploy_Incentives_CampaignRegistry.s.sol/80002/run-latest.json

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

contracts/incentives/campaigns/CampaignBase.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ abstract contract CampaignBase is
164164

165165
/// @notice Adds funds to the campaign's balance.
166166
/// @param amount The amount of funds to add.
167-
function addFunds(uint256 amount) external {
167+
function addFunds(uint256 amount) external onlyOwner {
168168
require(amount > 0, "Invalid amount to allocate in campaign.");
169169
uint256 deposited = LEDGER_VAULT.collect(msg.sender, amount, MMC);
170170
_sumLedgerEntry(msg.sender, deposited, MMC);
@@ -173,7 +173,7 @@ abstract contract CampaignBase is
173173

174174
/// @notice Removes funds from the campaign's balance.
175175
/// @param amount The amount of funds to remove.
176-
function removeFunds(uint256 amount) external {
176+
function removeFunds(uint256 amount) external onlyOwner {
177177
require(getLedgerBalance(msg.sender, MMC) >= amount, "Insufficient funds allocated in campaign.");
178178
uint256 confirmed = LEDGER_VAULT.transfer(msg.sender, amount, MMC);
179179
_subLedgerEntry(msg.sender, confirmed, MMC);

contracts/incentives/campaigns/CampaignRegistry.sol

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ contract CampaignRegistry is Initializable, UUPSUpgradeable, AccessControlledUpg
1818
using ERC165Checker for address;
1919
using EnumerableSet for EnumerableSet.AddressSet;
2020

21+
uint256 private constant MIN_EXPIRE_AT = 1 hours;
2122
/// @dev The interface ID for ICampaign, used to verify that a campaign contract implements the correct interface.
2223
bytes4 private constant INTERFACE_CAMPAIGN = type(ICampaign).interfaceId;
23-
uint256 private constant MIN_EXPIRE_AT = 1 hours;
2424
/// @dev Maps a campaign reference to its associated scope, which defines the entity the campaign operates on.
2525
mapping(bytes32 => address) private _scopes;
2626

@@ -67,30 +67,29 @@ contract CampaignRegistry is Initializable, UUPSUpgradeable, AccessControlledUpg
6767
/// @return The address of the associated campaign if found, otherwise `address(0)`.
6868
function getCampaign(address account, address policy) external view returns (address) {
6969
// Compute the unique identifier for the campaign association
70-
bytes32 scopeId = _computeComposedKey(account, policy);
71-
return _scopes[scopeId]; // Return the campaign address if it exists, else return address(0)
70+
return _scopes[_computeComposedKey(account, policy)];
7271
}
7372

7473
/// @notice Creates and registers a new campaign by cloning a given template contract.
7574
/// @dev The provided template must be a valid campaign contract.
7675
/// @param template The address of the campaign contract to clone.
7776
/// @param policy The policy the campaign is linked to.
78-
/// @param expireAt The timestamp when the campaign expires.
77+
/// @param expiration The timestamp when the campaign expires.
7978
/// @param description A brief description of the campaign.
8079
/// @return The address of the newly created campaign.
8180
function createCampaign(
8281
address template,
8382
address policy,
84-
uint256 expireAt,
83+
uint256 expiration,
8584
string calldata description
8685
) external onlyValidCampaigns(template) returns (address) {
8786
// minimum 1 hour to set as expire at
88-
if (expireAt < MIN_EXPIRE_AT) {
87+
if (expiration < MIN_EXPIRE_AT) {
8988
revert InvalidInput();
9089
}
9190

92-
bytes32 salt = keccak256(abi.encodePacked(msg.sender, template, expireAt));
93-
address clone = template.cloneDeterministic(salt);
91+
uint expireAt = block.timestamp + expiration;
92+
address clone = _clone(template, expireAt);
9493
address campaign = _setup(clone, expireAt);
9594
// store "linked" owner + scope + campaign
9695
// this is useful during campaign retrieval from scope context
@@ -114,7 +113,6 @@ contract CampaignRegistry is Initializable, UUPSUpgradeable, AccessControlledUpg
114113
return campaign;
115114
}
116115

117-
/// @notice Associates a scope with a campaign.
118116
/// @dev Creates a unique identifier for the scope based on the owner's address
119117
/// and the scope address. The generated scope ID is mapped to the campaign
120118
/// in the `_scopes` mapping, allowing efficient retrieval.
@@ -128,6 +126,12 @@ contract CampaignRegistry is Initializable, UUPSUpgradeable, AccessControlledUpg
128126
return scopeId;
129127
}
130128

129+
/// @dev Deploy a new minimal-proxy (EIP-1167) based on the specified campaign template.
130+
function _clone(address template, uint256 expireAt) private returns (address) {
131+
bytes32 salt = keccak256(abi.encodePacked(msg.sender, template, expireAt));
132+
return template.cloneDeterministic(salt);
133+
}
134+
131135
/// @notice Computes a unique key by combining a scope and an account address.
132136
/// @param account The address of the user for whom the key is being generated.
133137
/// @param scope The address representing the scope.

contracts/incentives/campaigns/sponsored/SubscriptionCampaignTpl.sol

Lines changed: 0 additions & 22 deletions
This file was deleted.

contracts/interfaces/IScope

Whitespace-only changes.

script/deployment/09_Deploy_Incentives_CampaignSubscription.s.sol

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)