Skip to content

Commit 74e0574

Browse files
committed
merge main into update-max-claimable
2 parents 9e525bc + 7c32748 commit 74e0574

File tree

114 files changed

+5075
-1190
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+5075
-1190
lines changed

contracts/Split.sol

-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ contract Split is
126126
function distribute() public virtual {
127127
uint256 count = payeeCount();
128128
for (uint256 i = 0; i < count; i++) {
129-
// note: `_release` should not fail because payee always has shares, protected by `_appPay`
130129
_release(payable(payee(i)));
131130
}
132131
}
@@ -137,7 +136,6 @@ contract Split is
137136
function distribute(IERC20Upgradeable token) public virtual {
138137
uint256 count = payeeCount();
139138
for (uint256 i = 0; i < count; i++) {
140-
// note: `_release` should not fail because payee always has shares, protected by `_appPay`
141139
_release(token, payee(i));
142140
}
143141
}

contracts/airdrop/AirdropERC1155.sol

+100-13
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@ import "../interfaces/airdrop/IAirdropERC1155.sol";
1313

1414
// ========== Features ==========
1515
import "../extension/Ownable.sol";
16-
17-
import "../openzeppelin-presets/metatx/ERC2771ContextUpgradeable.sol";
18-
import "../lib/MerkleProof.sol";
16+
import "../extension/PermissionsEnumerable.sol";
1917

2018
contract AirdropERC1155 is
2119
Initializable,
2220
Ownable,
21+
PermissionsEnumerable,
2322
ReentrancyGuardUpgradeable,
24-
ERC2771ContextUpgradeable,
2523
MulticallUpgradeable,
2624
IAirdropERC1155
2725
{
@@ -32,6 +30,13 @@ contract AirdropERC1155 is
3230
bytes32 private constant MODULE_TYPE = bytes32("AirdropERC1155");
3331
uint256 private constant VERSION = 1;
3432

33+
uint256 public payeeCount;
34+
uint256 public processedCount;
35+
36+
uint256[] private indicesOfFailed;
37+
38+
mapping(uint256 => AirdropContent) private airdropContent;
39+
3540
/*///////////////////////////////////////////////////////////////
3641
Constructor + initializer logic
3742
//////////////////////////////////////////////////////////////*/
@@ -40,6 +45,7 @@ contract AirdropERC1155 is
4045

4146
/// @dev Initiliazes the contract, like a constructor.
4247
function initialize(address _defaultAdmin) external initializer {
48+
_setupRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);
4349
_setupOwner(_defaultAdmin);
4450
__ReentrancyGuard_init();
4551
}
@@ -62,31 +68,112 @@ contract AirdropERC1155 is
6268
Airdrop logic
6369
//////////////////////////////////////////////////////////////*/
6470

71+
///@notice Lets contract-owner set up an airdrop of ERC721 NFTs to a list of addresses.
72+
function addAirdropRecipients(AirdropContent[] calldata _contents) external onlyRole(DEFAULT_ADMIN_ROLE) {
73+
uint256 len = _contents.length;
74+
require(len > 0, "No payees provided.");
75+
76+
uint256 currentCount = payeeCount;
77+
payeeCount += len;
78+
79+
for (uint256 i = currentCount; i < len; i += 1) {
80+
airdropContent[i] = _contents[i];
81+
}
82+
83+
emit RecipientsAdded(_contents);
84+
}
85+
86+
/// @notice Lets contract-owner send ERC721 NFTs to a list of addresses.
87+
function airdrop(uint256 paymentsToProcess) external nonReentrant {
88+
uint256 totalPayees = payeeCount;
89+
uint256 countOfProcessed = processedCount;
90+
91+
require(countOfProcessed + paymentsToProcess <= totalPayees, "invalid no. of payments");
92+
93+
processedCount += paymentsToProcess;
94+
95+
for (uint256 i = countOfProcessed; i < (countOfProcessed + paymentsToProcess); i += 1) {
96+
AirdropContent memory content = airdropContent[i];
97+
98+
IERC1155(content.tokenAddress).safeTransferFrom(
99+
content.tokenOwner,
100+
content.recipient,
101+
content.tokenId,
102+
content.amount,
103+
""
104+
);
105+
106+
emit AirdropPayment(content.recipient, content);
107+
}
108+
}
109+
65110
/**
66111
* @notice Lets contract-owner send ERC1155 tokens to a list of addresses.
67112
* @dev The token-owner should approve target tokens to Airdrop contract,
68113
* which acts as operator for the tokens.
69114
*
70115
* @param _tokenAddress Contract address of ERC1155 tokens to air-drop.
71116
* @param _tokenOwner Address from which to transfer tokens.
72-
* @param _recipients List of recipient addresses for the air-drop.
73-
* @param _amounts Quantity of tokens to air-drop, per recipient.
74-
* @param _tokenIds List of ERC1155 token-Ids to drop.
117+
* @param _contents List containing recipient, tokenId and amounts to airdrop.
75118
*/
76119
function airdrop(
77120
address _tokenAddress,
78121
address _tokenOwner,
79-
address[] memory _recipients,
80-
uint256[] memory _amounts,
81-
uint256[] memory _tokenIds
122+
AirdropContent[] calldata _contents
82123
) external nonReentrant onlyOwner {
83-
uint256 len = _tokenIds.length;
84-
require(len == _recipients.length && len == _amounts.length, "length mismatch");
124+
uint256 len = _contents.length;
85125

86126
IERC1155 token = IERC1155(_tokenAddress);
87127

88128
for (uint256 i = 0; i < len; i++) {
89-
token.safeTransferFrom(_tokenOwner, _recipients[i], _tokenIds[i], _amounts[i], "");
129+
token.safeTransferFrom(_tokenOwner, _contents[i].recipient, _contents[i].tokenId, _contents[i].amount, "");
130+
}
131+
}
132+
133+
/*///////////////////////////////////////////////////////////////
134+
Airdrop view logic
135+
//////////////////////////////////////////////////////////////*/
136+
137+
/// @notice Returns all airdrop payments set up -- pending, processed or failed.
138+
function getAllAirdropPayments() external view returns (AirdropContent[] memory contents) {
139+
uint256 count = payeeCount;
140+
contents = new AirdropContent[](count);
141+
142+
for (uint256 i = 0; i < count; i += 1) {
143+
contents[i] = airdropContent[i];
144+
}
145+
}
146+
147+
/// @notice Returns all pending airdrop payments.
148+
function getAllAirdropPaymentsPending() external view returns (AirdropContent[] memory contents) {
149+
uint256 endCount = payeeCount;
150+
uint256 startCount = processedCount;
151+
contents = new AirdropContent[](endCount - startCount);
152+
153+
uint256 idx;
154+
for (uint256 i = startCount; i < endCount; i += 1) {
155+
contents[idx] = airdropContent[i];
156+
idx += 1;
157+
}
158+
}
159+
160+
/// @notice Returns all pending airdrop processed.
161+
function getAllAirdropPaymentsProcessed() external view returns (AirdropContent[] memory contents) {
162+
uint256 count = processedCount;
163+
contents = new AirdropContent[](count);
164+
165+
for (uint256 i = 0; i < count; i += 1) {
166+
contents[i] = airdropContent[i];
167+
}
168+
}
169+
170+
/// @notice Returns all pending airdrop failed.
171+
function getAllAirdropPaymentsFailed() external view returns (AirdropContent[] memory contents) {
172+
uint256 count = indicesOfFailed.length;
173+
contents = new AirdropContent[](count);
174+
175+
for (uint256 i = 0; i < count; i += 1) {
176+
contents[i] = airdropContent[indicesOfFailed[i]];
90177
}
91178
}
92179

contracts/airdrop/AirdropERC20.sol

+105-28
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,30 @@ import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
1313

1414
// ========== Features ==========
1515
import "../extension/Ownable.sol";
16-
17-
contract AirdropERC20 is Initializable, Ownable, ReentrancyGuardUpgradeable, MulticallUpgradeable, IAirdropERC20 {
16+
import "../extension/PermissionsEnumerable.sol";
17+
18+
contract AirdropERC20 is
19+
Initializable,
20+
Ownable,
21+
PermissionsEnumerable,
22+
ReentrancyGuardUpgradeable,
23+
MulticallUpgradeable,
24+
IAirdropERC20
25+
{
1826
/*///////////////////////////////////////////////////////////////
1927
State variables
2028
//////////////////////////////////////////////////////////////*/
2129

2230
bytes32 private constant MODULE_TYPE = bytes32("AirdropERC20");
2331
uint256 private constant VERSION = 1;
2432

33+
uint256 public payeeCount;
34+
uint256 public processedCount;
35+
36+
uint256[] private indicesOfFailed;
37+
38+
mapping(uint256 => AirdropContent) private airdropContent;
39+
2540
/*///////////////////////////////////////////////////////////////
2641
Constructor + initializer logic
2742
//////////////////////////////////////////////////////////////*/
@@ -30,6 +45,7 @@ contract AirdropERC20 is Initializable, Ownable, ReentrancyGuardUpgradeable, Mul
3045

3146
/// @dev Initiliazes the contract, like a constructor.
3247
function initialize(address _defaultAdmin) external initializer {
48+
_setupRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);
3349
_setupOwner(_defaultAdmin);
3450
__ReentrancyGuard_init();
3551
}
@@ -52,35 +68,96 @@ contract AirdropERC20 is Initializable, Ownable, ReentrancyGuardUpgradeable, Mul
5268
Airdrop logic
5369
//////////////////////////////////////////////////////////////*/
5470

55-
/**
56-
* @notice Lets contract-owner send ERC20 tokens to a list of addresses.
57-
* @dev The token-owner should approve target tokens to Airdrop contract,
58-
* which acts as operator for the tokens.
59-
*
60-
* @param _tokenAddress Contract address of ERC20 tokens to air-drop.
61-
* @param _tokenOwner Address from which to transfer tokens.
62-
* @param _recipients List of recipient addresses for the air-drop.
63-
* @param _amounts Quantity of tokens to air-drop, per recipient.
64-
*/
65-
function airdrop(
66-
address _tokenAddress,
67-
address _tokenOwner,
68-
address[] memory _recipients,
69-
uint256[] memory _amounts
70-
) external payable nonReentrant onlyOwner {
71-
uint256 len = _amounts.length;
72-
require(len == _recipients.length, "length mismatch");
73-
74-
if (_tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) {
75-
uint256 totalAmount;
76-
for (uint256 i = 0; i < len; i++) {
77-
totalAmount += _amounts[i];
71+
///@notice Lets contract-owner set up an airdrop of ERC20 or native tokens to a list of addresses.
72+
function addAirdropRecipients(AirdropContent[] calldata _contents) external payable onlyRole(DEFAULT_ADMIN_ROLE) {
73+
uint256 len = _contents.length;
74+
require(len > 0, "No payees provided.");
75+
76+
uint256 currentCount = payeeCount;
77+
payeeCount += len;
78+
79+
uint256 nativeTokenAmount;
80+
81+
for (uint256 i = currentCount; i < len; i += 1) {
82+
airdropContent[i] = _contents[i];
83+
84+
if (_contents[i].tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) {
85+
nativeTokenAmount += _contents[i].amount;
7886
}
79-
require(totalAmount == msg.value, "Incorrect native token amount");
8087
}
8188

82-
for (uint256 i = 0; i < len; i++) {
83-
CurrencyTransferLib.transferCurrency(_tokenAddress, _tokenOwner, _recipients[i], _amounts[i]);
89+
require(nativeTokenAmount == msg.value, "Incorrect native token amount");
90+
91+
emit RecipientsAdded(_contents);
92+
}
93+
94+
/// @notice Lets contract-owner send ERC20 or native tokens to a list of addresses.
95+
function airdrop(uint256 paymentsToProcess) external nonReentrant {
96+
uint256 totalPayees = payeeCount;
97+
uint256 countOfProcessed = processedCount;
98+
99+
require(countOfProcessed + paymentsToProcess <= totalPayees, "invalid no. of payments");
100+
101+
processedCount += paymentsToProcess;
102+
103+
for (uint256 i = countOfProcessed; i < (countOfProcessed + paymentsToProcess); i += 1) {
104+
AirdropContent memory content = airdropContent[i];
105+
106+
CurrencyTransferLib.transferCurrency(
107+
content.tokenAddress,
108+
content.tokenOwner,
109+
content.recipient,
110+
content.amount
111+
);
112+
113+
emit AirdropPayment(content.recipient, content);
114+
}
115+
}
116+
117+
/*///////////////////////////////////////////////////////////////
118+
Airdrop view logic
119+
//////////////////////////////////////////////////////////////*/
120+
121+
/// @notice Returns all airdrop payments set up -- pending, processed or failed.
122+
function getAllAirdropPayments() external view returns (AirdropContent[] memory contents) {
123+
uint256 count = payeeCount;
124+
contents = new AirdropContent[](count);
125+
126+
for (uint256 i = 0; i < count; i += 1) {
127+
contents[i] = airdropContent[i];
128+
}
129+
}
130+
131+
/// @notice Returns all pending airdrop payments.
132+
function getAllAirdropPaymentsPending() external view returns (AirdropContent[] memory contents) {
133+
uint256 endCount = payeeCount;
134+
uint256 startCount = processedCount;
135+
contents = new AirdropContent[](endCount - startCount);
136+
137+
uint256 idx;
138+
for (uint256 i = startCount; i < endCount; i += 1) {
139+
contents[idx] = airdropContent[i];
140+
idx += 1;
141+
}
142+
}
143+
144+
/// @notice Returns all pending airdrop processed.
145+
function getAllAirdropPaymentsProcessed() external view returns (AirdropContent[] memory contents) {
146+
uint256 count = processedCount;
147+
contents = new AirdropContent[](count);
148+
149+
for (uint256 i = 0; i < count; i += 1) {
150+
contents[i] = airdropContent[i];
151+
}
152+
}
153+
154+
/// @notice Returns all pending airdrop failed.
155+
function getAllAirdropPaymentsFailed() external view returns (AirdropContent[] memory contents) {
156+
uint256 count = indicesOfFailed.length;
157+
contents = new AirdropContent[](count);
158+
159+
for (uint256 i = 0; i < count; i += 1) {
160+
contents[i] = airdropContent[indicesOfFailed[i]];
84161
}
85162
}
86163

0 commit comments

Comments
 (0)