Skip to content

Commit 59ae563

Browse files
author
ilitteri
committed
Refactor claim contracts to be UUPS upgradable
1 parent ee2efe2 commit 59ae563

File tree

5 files changed

+205
-35
lines changed

5 files changed

+205
-35
lines changed

claim_contracts/src/AlignedToken.sol

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
5+
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
6+
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
7+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
8+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
9+
10+
contract AlignedTokenV1 is
11+
Initializable,
12+
ERC20Upgradeable,
13+
OwnableUpgradeable,
14+
ERC20PermitUpgradeable,
15+
UUPSUpgradeable
16+
{
17+
/// @custom:oz-upgrades-unsafe-allow constructor
18+
constructor() {
19+
_disableInitializers();
20+
}
21+
22+
function initialize(
23+
address _initialOwner,
24+
address _beneficiary1,
25+
uint256 _beneficiary1Part,
26+
address _beneficiary2,
27+
uint256 _beneficiary2Part,
28+
address _beneficiary3,
29+
uint256 _beneficiary3Part
30+
) public initializer {
31+
__ERC20_init("AlignedTokenV1", "ALI");
32+
__Ownable_init(_initialOwner);
33+
__ERC20Permit_init("AlignedTokenV1");
34+
__UUPSUpgradeable_init();
35+
36+
_mint(_beneficiary1, _beneficiary1Part);
37+
_mint(_beneficiary2, _beneficiary2Part);
38+
_mint(_beneficiary3, _beneficiary3Part);
39+
}
40+
41+
function _authorizeUpgrade(
42+
address newImplementation
43+
) internal override onlyOwner {}
44+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
5+
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
6+
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
7+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
8+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
9+
10+
/// @title AlignedTokenV2Example contract
11+
/// @notice This is an example of how a AlignedToken contract upgrade
12+
/// should look like.
13+
/// @dev Minimum necessary changes:
14+
/// - The initialize function is marked as reinitializer with version 2.
15+
/// @custom:oz-upgrades-from AlignedTokenV1
16+
contract AlignedTokenV2Example is
17+
Initializable,
18+
ERC20Upgradeable,
19+
OwnableUpgradeable,
20+
ERC20PermitUpgradeable,
21+
UUPSUpgradeable
22+
{
23+
/// @custom:oz-upgrades-unsafe-allow constructor
24+
constructor() {
25+
_disableInitializers();
26+
}
27+
28+
function initialize(
29+
address initialOwner,
30+
address beneficiary1,
31+
uint256 beneficiary1Part,
32+
address beneficiary2,
33+
uint256 beneficiary2Part,
34+
address beneficiary3,
35+
uint256 beneficiary3Part
36+
) public initializer {
37+
__ERC20_init("AlignedTokenV2", "ALI");
38+
__Ownable_init(initialOwner);
39+
__ERC20Permit_init("AlignedTokenV2");
40+
__UUPSUpgradeable_init();
41+
42+
_mint(beneficiary1, beneficiary1Part);
43+
_mint(beneficiary2, beneficiary2Part);
44+
_mint(beneficiary3, beneficiary3Part);
45+
}
46+
47+
function _authorizeUpgrade(
48+
address newImplementation
49+
) internal override onlyOwner {}
50+
}

claim_contracts/src/ClaimableAirdrop.sol renamed to claim_contracts/src/ClaimableAirdropV1.sol

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@ pragma solidity ^0.8.13;
44
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
55
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
66
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
7-
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
7+
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
8+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
9+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
810

9-
contract ClaimableAirdrop is ReentrancyGuard, Initializable {
11+
contract ClaimableAirdropV1 is
12+
ReentrancyGuard,
13+
Initializable,
14+
OwnableUpgradeable,
15+
UUPSUpgradeable
16+
{
1017
address public tokenContractAddress;
1118
address public tokenOwnerAddress;
1219
uint256 public limitTimestampToClaim;
@@ -16,12 +23,21 @@ contract ClaimableAirdrop is ReentrancyGuard, Initializable {
1623

1724
event TokenClaimed(address indexed to, uint256 indexed amount);
1825

26+
/// @custom:oz-upgrades-unsafe-allow constructor
27+
constructor() {
28+
_disableInitializers();
29+
}
30+
1931
function initialize(
32+
address _initialOwner,
2033
address _tokenContractAddress,
2134
address _tokenOwnerAddress,
2235
uint256 _limitTimestampToClaim,
2336
bytes32 _claimMerkleRoot
2437
) public initializer nonReentrant {
38+
__Ownable_init(_initialOwner);
39+
__UUPSUpgradeable_init();
40+
2541
tokenContractAddress = _tokenContractAddress;
2642
tokenOwnerAddress = _tokenOwnerAddress;
2743
limitTimestampToClaim = _limitTimestampToClaim;
@@ -60,4 +76,8 @@ contract ClaimableAirdrop is ReentrancyGuard, Initializable {
6076

6177
emit TokenClaimed(msg.sender, amount);
6278
}
79+
80+
function _authorizeUpgrade(
81+
address newImplementation
82+
) internal override onlyOwner {}
6383
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.13;
3+
4+
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5+
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
6+
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
7+
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
8+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
9+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
10+
11+
/// @title ClaimableAirdropV2Example contract
12+
/// @notice This is an example of how a ClaimableAirdrop contract upgrade
13+
/// should look like
14+
/// @dev Minimum necessary changes:
15+
/// - The initialize function is marked as reinitializer with version 2.
16+
/// @custom:oz-upgrades-from ClaimableAirdropV1
17+
contract ClaimableAirdropV2Example is
18+
ReentrancyGuard,
19+
Initializable,
20+
OwnableUpgradeable,
21+
UUPSUpgradeable
22+
{
23+
address public tokenContractAddress;
24+
address public tokenOwnerAddress;
25+
uint256 public limitTimestampToClaim;
26+
bytes32 public claimMerkleRoot;
27+
28+
mapping(address => bool) public hasClaimed;
29+
30+
event TokenClaimed(address indexed to, uint256 indexed amount);
31+
32+
/// @custom:oz-upgrades-unsafe-allow constructor
33+
constructor() {
34+
_disableInitializers();
35+
}
36+
37+
function initialize(
38+
address _initialOwner,
39+
address _tokenContractAddress,
40+
address _tokenOwnerAddress,
41+
uint256 _limitTimestampToClaim,
42+
bytes32 _claimMerkleRoot
43+
) public initializer nonReentrant {
44+
__Ownable_init(_initialOwner);
45+
__UUPSUpgradeable_init();
46+
47+
tokenContractAddress = _tokenContractAddress;
48+
tokenOwnerAddress = _tokenOwnerAddress;
49+
limitTimestampToClaim = _limitTimestampToClaim;
50+
claimMerkleRoot = _claimMerkleRoot;
51+
}
52+
53+
function claim(
54+
uint256 amount,
55+
bytes32[] calldata merkleProof
56+
) public nonReentrant {
57+
require(
58+
!hasClaimed[msg.sender],
59+
"Account has already claimed the drop"
60+
);
61+
require(
62+
block.timestamp <= limitTimestampToClaim,
63+
"Drop is no longer claimable"
64+
);
65+
66+
bytes32 leaf = keccak256(
67+
bytes.concat(keccak256(abi.encode(msg.sender, amount)))
68+
);
69+
bool verifies = MerkleProof.verify(merkleProof, claimMerkleRoot, leaf);
70+
71+
require(verifies, "Invalid Merkle proof");
72+
73+
hasClaimed[msg.sender] = true;
74+
75+
bool success = IERC20(tokenContractAddress).transferFrom(
76+
tokenOwnerAddress,
77+
msg.sender,
78+
amount
79+
);
80+
81+
require(success, "Failed to transfer funds");
82+
83+
emit TokenClaimed(msg.sender, amount);
84+
}
85+
86+
function _authorizeUpgrade(
87+
address newImplementation
88+
) internal override onlyOwner {}
89+
}

0 commit comments

Comments
 (0)