Skip to content

Commit

Permalink
Airdrop
Browse files Browse the repository at this point in the history
  • Loading branch information
kumaryash90 committed Mar 18, 2024
1 parent 2fa9b0f commit a874e4d
Showing 1 changed file with 279 additions and 0 deletions.
279 changes: 279 additions & 0 deletions contracts/prebuilts/unaudited/airdrop/Airdrop.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.11;

/// @author thirdweb

// $$\ $$\ $$\ $$\ $$\
// $$ | $$ | \__| $$ | $$ |
// $$$$$$\ $$$$$$$\ $$\ $$$$$$\ $$$$$$$ |$$\ $$\ $$\ $$$$$$\ $$$$$$$\
// \_$$ _| $$ __$$\ $$ |$$ __$$\ $$ __$$ |$$ | $$ | $$ |$$ __$$\ $$ __$$\
// $$ | $$ | $$ |$$ |$$ | \__|$$ / $$ |$$ | $$ | $$ |$$$$$$$$ |$$ | $$ |
// $$ |$$\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ |
// \$$$$ |$$ | $$ |$$ |$$ | \$$$$$$$ |\$$$$$\$$$$ |\$$$$$$$\ $$$$$$$ |
// \____/ \__| \__|\__|\__| \_______| \_____\____/ \_______|\_______/

import { Initializable } from "../../../extension/Initializable.sol";
import { Ownable } from "../../../extension/Ownable.sol";

import "../../../eip/interface/IERC721.sol";
import "../../../eip/interface/IERC1155.sol";
import "../../../lib/MerkleProof.sol";
import "../../../lib/CurrencyTransferLib.sol";

contract Airdrop is Initializable, Ownable {
/*///////////////////////////////////////////////////////////////
State & structs
//////////////////////////////////////////////////////////////*/

// ERC20 claimable
address public tokenAddress20;

Check failure

Code scanning / Slither

Uninitialized state variables High

Check warning

Code scanning / Slither

State variables that could be declared constant Warning

Airdrop.tokenAddress20 should be constant
mapping(address => bytes32) public merkleRoot20;
mapping(address => bool) public claimed20;

// Native token claimable
bytes32 public merkleRootETH;
mapping(address => bool) public claimedETH;

// ERC721 claimable
address public tokenAddress721;

Check failure

Code scanning / Slither

Uninitialized state variables High

Check warning

Code scanning / Slither

State variables that could be declared constant Warning

Airdrop.tokenAddress721 should be constant
mapping(address => bytes32) public merkleRoot721;
mapping(uint256 => bool) public claimed721;

// ERC1155 claimable
address public tokenAddress1155;

Check failure

Code scanning / Slither

Uninitialized state variables High

Check warning

Code scanning / Slither

State variables that could be declared constant Warning

Airdrop.tokenAddress1155 should be constant
mapping(address => bytes32) public merkleRoot1155;
mapping(uint256 => mapping(address => bool)) public claimed1155;

struct AirdropContent20 {
address recipient;
uint256 amount;
}

struct AirdropContent721 {
address recipient;
uint256 tokenId;
}

struct AirdropContent1155 {
address recipient;
uint256 tokenId;
uint256 amount;
}

/*///////////////////////////////////////////////////////////////
Errors
//////////////////////////////////////////////////////////////*/

error AirdropInvalidProof();
error AirdropFailed();
error AirdropNoMerkleRoot();
error AirdropValueMismatch();

/*///////////////////////////////////////////////////////////////
Constructor
//////////////////////////////////////////////////////////////*/

constructor() {
_disableInitializers();
}

function initialize(address _defaultAdmin) external initializer {
_setupOwner(_defaultAdmin);

Check warning on line 81 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L81

Added line #L81 was not covered by tests
}

/*///////////////////////////////////////////////////////////////
Airdrop Push
//////////////////////////////////////////////////////////////*/

function airdropERC20(address _tokenAddress, AirdropContent20[] calldata _contents) external {
address _from = msg.sender;
uint256 len = _contents.length;

Check warning on line 90 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L89-L90

Added lines #L89 - L90 were not covered by tests

for (uint256 i = 0; i < len; ) {
CurrencyTransferLib.transferCurrency(_tokenAddress, _from, _contents[i].recipient, _contents[i].amount);

Check warning on line 93 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L92-L93

Added lines #L92 - L93 were not covered by tests

unchecked {
i += 1;

Check warning on line 96 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L96

Added line #L96 was not covered by tests
}
}
}

function airdropNativeToken(AirdropContent20[] calldata _contents) external payable {
uint256 len = _contents.length;

Check warning on line 102 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L102

Added line #L102 was not covered by tests

uint256 nativeTokenAmount;
uint256 refundAmount;

Check warning

Code scanning / Slither

Uninitialized local variables Medium

Check warning on line 105 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L104-L105

Added lines #L104 - L105 were not covered by tests

for (uint256 i = 0; i < len; ) {
nativeTokenAmount += _contents[i].amount;

Check warning on line 108 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L107-L108

Added lines #L107 - L108 were not covered by tests

if (nativeTokenAmount > msg.value) {
revert AirdropValueMismatch();

Check warning on line 111 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L110-L111

Added lines #L110 - L111 were not covered by tests
}

(bool success, ) = _contents[i].recipient.call{ value: _contents[i].amount }("");

Check warning on line 114 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L114

Added line #L114 was not covered by tests

if (!success) {
refundAmount += _contents[i].amount;

Check warning on line 117 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L116-L117

Added lines #L116 - L117 were not covered by tests
}

unchecked {
i += 1;

Check warning on line 121 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L121

Added line #L121 was not covered by tests
}
}

if (nativeTokenAmount != msg.value) {
revert AirdropValueMismatch();

Check warning on line 126 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L125-L126

Added lines #L125 - L126 were not covered by tests
}

if (refundAmount > 0) {

Check warning on line 129 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L129

Added line #L129 was not covered by tests
// refund failed payments' amount to sender address
// solhint-disable avoid-low-level-calls
// slither-disable-next-line low-level-calls
(bool refundSuccess, ) = msg.sender.call{ value: refundAmount }("");

Check warning on line 133 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L133

Added line #L133 was not covered by tests
}
}

Check failure

Code scanning / Slither

Functions that send Ether to arbitrary destinations High

Check notice

Code scanning / Slither

Calls inside a loop Low


function airdrop721(address _tokenAddress, AirdropContent721[] calldata _contents) external {
address _from = msg.sender;

Check warning on line 138 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L138

Added line #L138 was not covered by tests

uint256 len = _contents.length;

Check warning on line 140 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L140

Added line #L140 was not covered by tests

for (uint256 i = 0; i < len; ) {
IERC721(_tokenAddress).safeTransferFrom(_from, _contents[i].recipient, _contents[i].tokenId);

Check warning on line 143 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L142-L143

Added lines #L142 - L143 were not covered by tests

unchecked {
i += 1;

Check warning on line 146 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L146

Added line #L146 was not covered by tests
}
}
}

Check notice

Code scanning / Slither

Calls inside a loop Low


function airdropERC1155(address _tokenAddress, AirdropContent1155[] calldata _contents) external {
address _from = msg.sender;

Check warning on line 152 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L152

Added line #L152 was not covered by tests

uint256 len = _contents.length;

Check warning on line 154 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L154

Added line #L154 was not covered by tests

for (uint256 i = 0; i < len; ) {
IERC1155(_tokenAddress).safeTransferFrom(

Check warning on line 157 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L156-L157

Added lines #L156 - L157 were not covered by tests
_from,
_contents[i].recipient,
_contents[i].tokenId,
_contents[i].amount,
""
);

unchecked {
i += 1;

Check warning on line 166 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L166

Added line #L166 was not covered by tests
}
}
}

/*///////////////////////////////////////////////////////////////
Airdrop Claimable
//////////////////////////////////////////////////////////////*/

function claim20(address _token, address _receiver, uint256 _quantity, bytes32[] calldata _proofs) external {
bytes32 _merkleRoot = merkleRoot20[_token];

Check warning on line 176 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L176

Added line #L176 was not covered by tests

if (_merkleRoot == bytes32(0)) {
revert AirdropNoMerkleRoot();

Check warning on line 179 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L178-L179

Added lines #L178 - L179 were not covered by tests
}

bool valid;
(valid, ) = MerkleProof.verify(_proofs, _merkleRoot, keccak256(abi.encodePacked(msg.sender, _quantity)));

Check warning on line 183 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L182-L183

Added lines #L182 - L183 were not covered by tests

if (!valid) {
revert AirdropInvalidProof();

Check warning on line 186 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L185-L186

Added lines #L185 - L186 were not covered by tests
}

claimed20[msg.sender] = true;

Check warning on line 189 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L189

Added line #L189 was not covered by tests

CurrencyTransferLib.transferCurrency(tokenAddress20, owner(), _receiver, _quantity);

Check warning on line 191 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L191

Added line #L191 was not covered by tests
}

function claimETH(address _receiver, uint256 _quantity, bytes32[] calldata _proofs) external {
bool valid;
(valid, ) = MerkleProof.verify(_proofs, merkleRootETH, keccak256(abi.encodePacked(msg.sender, _quantity)));

Check warning on line 196 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L195-L196

Added lines #L195 - L196 were not covered by tests

if (!valid) {
revert AirdropInvalidProof();

Check warning on line 199 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L198-L199

Added lines #L198 - L199 were not covered by tests
}

claimedETH[msg.sender] = true;

Check warning on line 202 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L202

Added line #L202 was not covered by tests

(bool success, ) = _receiver.call{ value: _quantity }("");
if (!success) revert AirdropFailed();

Check warning on line 205 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L204-L205

Added lines #L204 - L205 were not covered by tests
}

Check warning

Code scanning / Slither

Low-level calls Warning


function claim721(address _token, address _receiver, uint256 _tokenId, bytes32[] calldata _proofs) external {
bytes32 _merkleRoot = merkleRoot721[_token];

Check warning on line 209 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L209

Added line #L209 was not covered by tests

if (_merkleRoot == bytes32(0)) {
revert AirdropNoMerkleRoot();

Check warning on line 212 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L211-L212

Added lines #L211 - L212 were not covered by tests
}

bool valid;
(valid, ) = MerkleProof.verify(_proofs, _merkleRoot, keccak256(abi.encodePacked(msg.sender, _tokenId)));

Check warning on line 216 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L215-L216

Added lines #L215 - L216 were not covered by tests

if (!valid) {
revert AirdropInvalidProof();

Check warning on line 219 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L218-L219

Added lines #L218 - L219 were not covered by tests
}

claimed721[_tokenId] = true;

Check warning on line 222 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L222

Added line #L222 was not covered by tests

IERC721(tokenAddress721).safeTransferFrom(owner(), _receiver, _tokenId);

Check warning on line 224 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L224

Added line #L224 was not covered by tests
}

function claim1155(
address _token,
address _receiver,
uint256 _tokenId,
uint256 _quantity,
bytes32[] calldata _proofs
) external {
bytes32 _merkleRoot = merkleRoot1155[_token];

Check warning on line 234 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L234

Added line #L234 was not covered by tests

if (_merkleRoot == bytes32(0)) {
revert AirdropNoMerkleRoot();

Check warning on line 237 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L236-L237

Added lines #L236 - L237 were not covered by tests
}

bool valid;
(valid, ) = MerkleProof.verify(_proofs, _merkleRoot, keccak256(abi.encodePacked(msg.sender, _quantity)));

Check warning on line 241 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L240-L241

Added lines #L240 - L241 were not covered by tests

if (!valid) {
revert AirdropInvalidProof();

Check warning on line 244 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L243-L244

Added lines #L243 - L244 were not covered by tests
}

claimed1155[_tokenId][msg.sender] = true;

Check warning on line 247 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L247

Added line #L247 was not covered by tests

IERC1155(tokenAddress1155).safeTransferFrom(owner(), _receiver, _tokenId, _quantity, "");

Check warning on line 249 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L249

Added line #L249 was not covered by tests
}

/*///////////////////////////////////////////////////////////////
Setter functions
//////////////////////////////////////////////////////////////*/

function setMerkleRoot20(address _token, bytes32 _merkleRoot) external onlyOwner {
merkleRoot20[_token] = _merkleRoot;

Check warning on line 257 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L257

Added line #L257 was not covered by tests
}

function setMerkleRootETH(bytes32 _merkleRoot) external onlyOwner {
merkleRootETH = _merkleRoot;

Check warning on line 261 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L261

Added line #L261 was not covered by tests
}

function setMerkleRoot721(address _token, bytes32 _merkleRoot) external onlyOwner {
merkleRoot721[_token] = _merkleRoot;

Check warning on line 265 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L265

Added line #L265 was not covered by tests
}

function setMerkleRoot1155(address _token, bytes32 _merkleRoot) external onlyOwner {
merkleRoot1155[_token] = _merkleRoot;

Check warning on line 269 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L269

Added line #L269 was not covered by tests
}

/*///////////////////////////////////////////////////////////////
Miscellaneous
//////////////////////////////////////////////////////////////*/

function _canSetOwner() internal view virtual override returns (bool) {
return msg.sender == owner();

Check warning on line 277 in contracts/prebuilts/unaudited/airdrop/Airdrop.sol

View check run for this annotation

Codecov / codecov/patch

contracts/prebuilts/unaudited/airdrop/Airdrop.sol#L277

Added line #L277 was not covered by tests
}
}

0 comments on commit a874e4d

Please sign in to comment.