-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
39 changed files
with
1,283 additions
and
212 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Compiler files | ||
cache/ | ||
out/ | ||
|
||
# Ignores development broadcast logs | ||
!/broadcast | ||
/broadcast/*/31337/ | ||
/broadcast/**/dry-run/ | ||
|
||
# Docs | ||
docs/ | ||
|
||
# Dotenv file | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
.PHONY: help deploy-aligned-token-implementation deploy-aligned-token-proxy deploy-claimable-airdrop-implementation deploy-claimable-airdrop-proxy upgrade-aligned-token-implementation aligned-token-proxy-deploy-data aligned-token-init-data aligned-token-upgrade-data aligned-token-create2 aligned-token-proxy-create2 | ||
|
||
|
||
help: ## 📚 Show help for each of the Makefile recipes | ||
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' | ||
|
||
# Deployments | ||
|
||
RPC_URL?=http://localhost:8545 | ||
PRIVATE_KEY?=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d | ||
|
||
deploy-all: ## 🚀 Deploy all contracts | ||
cd script && forge script DeployAll.s.sol --private-key $(PRIVATE_KEY) --rpc-url $(RPC_URL) --broadcast | ||
|
||
CONFIG?=example | ||
deploy-token: ## 🚀 Deploy the token contract | ||
cd script && \ | ||
forge script DeployAlignedToken.s.sol \ | ||
--sig "run(string)" \ | ||
$(CONFIG) \ | ||
--private-key $(PRIVATE_KEY) \ | ||
--rpc-url $(RPC_URL) \ | ||
--broadcast | ||
|
||
MINT?="1 ether" | ||
OWNER?=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 | ||
BENEFICIARY1?=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 | ||
BENEFICIARY2?=0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC | ||
BENEFICIARY3?=0x90F79bf6EB2c4f870365E785982E1f101E93b906 | ||
|
||
CLAIM_TIME_LIMIT?=1632960000 | ||
MERKLE_ROOT?=0x90076b5fb9a6c81d9fce83dfd51760987b8c49e7c861ea25b328e6e63d2cd3df | ||
TOKEN_OWNER?=$(OWNER) | ||
|
||
deploy-proxy-admin: ## 🚀 Deploy the ProxyAdmin contract | ||
cd script/proxy_admin && \ | ||
forge script DeployProxyAdmin.s.sol \ | ||
--sig "run(address)" \ | ||
$(OWNER) \ | ||
--rpc-url $(RPC_URL) \ | ||
--private-key $(PRIVATE_KEY) \ | ||
--broadcast | ||
|
||
deploy-aligned-token-implementation: ## 🚀 Deploy the AlignedToken implementation contract | ||
cd script/aligned_token && \ | ||
forge script DeployAlignedTokenImplementation.s.sol \ | ||
--rpc-url $(RPC_URL) \ | ||
--private-key $(PRIVATE_KEY) \ | ||
--broadcast | ||
|
||
deploy-aligned-token-proxy: ## 🚀 Deploy the AlignedToken proxy contract | ||
cd script/aligned_token && \ | ||
forge script DeployAlignedTokenProxy.s.sol \ | ||
--sig "run(address,address,address,address,address,address,uint256)" \ | ||
$(PROXY_ADMIN) $(IMPLEMENTATION) $(OWNER) $(BENEFICIARY1) $(BENEFICIARY2) $(BENEFICIARY3) $(MINT) \ | ||
--rpc-url $(RPC_URL) \ | ||
--private-key $(PRIVATE_KEY) \ | ||
--broadcast | ||
|
||
deploy-claimable-airdrop-implementation: ## 🚀 Deploy the ClaimableAirdrop implementation contract | ||
cd script/claimable_airdrop && \ | ||
forge script DeployClaimableAirdropImplementation.s.sol \ | ||
--rpc-url $(RPC_URL) \ | ||
--private-key $(PRIVATE_KEY) \ | ||
--broadcast | ||
|
||
deploy-claimable-airdrop-proxy: ## 🚀 Deploy the ClaimableAirdrop proxy contract | ||
cd script/claimable_airdrop && \ | ||
forge script DeployClaimableAirdropProxy.s.sol \ | ||
--sig "run(address,address,address,address,address,uint256,bytes32)" \ | ||
$(PROXY_ADMIN) $(IMPLEMENTATION) $(OWNER) $(TOKEN) $(BENEFICIARY1) $(CLAIM_TIME_LIMIT) $(MERKLE_ROOT) \ | ||
--rpc-url $(RPC_URL) \ | ||
--private-key $(PRIVATE_KEY) \ | ||
--broadcast | ||
|
||
# Upgrades | ||
|
||
upgrade-aligned-token-implementation: ## 🚀 Upgrade the AlignedToken implementation contract | ||
cd script/aligned_token && \ | ||
forge script UpgradeAlignedTokenImplementation.s.sol \ | ||
--sig "function run(address,address,uint256,address,address,address,address,uint256)" \ | ||
$(PROXY) $(IMPLEMENTATION) $(VERSION) $(OWNER) $(BENEFICIARY1) $(BENEFICIARY2) $(BENEFICIARY3) $(MINT)\ | ||
--rpc-url $(RPC_URL) \ | ||
--private-key $(PRIVATE_KEY) \ | ||
--broadcast | ||
|
||
# Deployment Data | ||
|
||
aligned-token-proxy-deploy-data: ## 🚀 Generate the deployment data for the AlignedToken proxy contract | ||
cd script/aligned_token && \ | ||
forge script AlignedTokenProxyDeploymentData.s.sol \ | ||
--sig "run(address,uint256, address,address,address,address,uint256)" \ | ||
$(IMPLEMENTATION) $(VERSION) $(OWNER) $(BENEFICIARY1) $(BENEFICIARY2) $(BENEFICIARY3) $(MINT) | ||
|
||
aligned-token-init-data: ## 🚀 Generate the init data for the AlignedToken proxy contract | ||
cd script/aligned_token && \ | ||
forge script AlignedTokenInitData.s.sol \ | ||
--sig "run(address,uint256, address,address,address,address,uint256)" \ | ||
$(IMPLEMENTATION) $(VERSION) $(OWNER) $(BENEFICIARY1) $(BENEFICIARY2) $(BENEFICIARY3) $(MINT) | ||
|
||
aligned-token-upgrade-data: ## 🚀 Generate the upgrade data for the AlignedToken proxy contract | ||
cd script/aligned_token && \ | ||
forge script AlignedTokenUpgradeData.s.sol \ | ||
--sig "run(address,uint256, address,address,address,address,uint256)" \ | ||
$(IMPLEMENTATION) $(VERSION) $(OWNER) $(BENEFICIARY1) $(BENEFICIARY2) $(BENEFICIARY3) $(MINT) | ||
|
||
SALT?=0x0000000000000000000000000000000000000000000000000000000000000000 | ||
# Sepolia Safe CreateCall contract. | ||
DEPLOYER?=0x9b35Af71d77eaf8d7e40252370304687390A1A52 | ||
|
||
aligned-token-create2: ## 🚀 Generate the create2 data for the AlignedToken proxy contract | ||
cd script/aligned_token && \ | ||
forge script AlignedTokenCreate2.s.sol \ | ||
--sig "run(uint256,bytes32,address)" \ | ||
$(VERSION) $(SALT) $(DEPLOYER) | ||
|
||
aligned-token-proxy-create2: ## 🚀 Generate the create2 data for the AlignedToken proxy contract | ||
cd script/aligned_token && \ | ||
forge script AlignedTokenCreate2.s.sol \ | ||
--sig "run(address,uint256, address,address,address,address,uint256,bytes32,address)" \ | ||
$(IMPLEMENTATION) $(VERSION) $(OWNER) $(BENEFICIARY1) $(BENEFICIARY2) $(BENEFICIARY3) $(MINT) $(SALT) $(DEPLOYER | ||
|
||
# Misc | ||
|
||
approve: | ||
cd script && \ | ||
forge script ApproveERC20.s.sol \ | ||
--sig "run(address,address,uint256)" \ | ||
$(TOKEN) $(AIRDROP) $(AMOUNT) \ | ||
--rpc-url $(RPC_URL) \ | ||
--private-key $(HOLDER_PRIVATE_KEY) \ | ||
--broadcast | ||
|
||
# Test targets | ||
|
||
test-token: | ||
cast call $(ADDRESS) "name()(string)" --rpc-url $(RPC_URL) | ||
cast call $(ADDRESS) "totalSupply()(uint256)" --rpc-url $(RPC_URL) | ||
|
||
# The following target needs the proof API running on localhost:4000 | ||
AMOUNT_TO_CLAIM=$(shell curl -S -H "Content-Type: application/json" http://localhost:4000/api/proof/\$(CLAIMER) | jq -r .amount) | ||
MERKLE_PROOF_TO_CLAIM=$(shell curl -S -H "Content-Type: application/json" http://localhost:4000/api/proof/\$(CLAIMER) | jq .proof | tr -d '"\n ') | ||
test-claim: | ||
cast send $(AIRDROP) --private-key $(CLAIMER_PRIVATE_KEY) "claim(uint256,bytes32[])" $(AMOUNT_TO_CLAIM) "$(MERKLE_PROOF_TO_CLAIM)" --rpc-url $(RPC_URL) | ||
|
||
test-claimed: | ||
cast call $(AIRDROP) "hasClaimed(address)(bool)" $(CLAIMER) --rpc-url $(RPC_URL) | ||
cast balance --erc20 $(TOKEN) $(CLAIMER) --rpc-url $(RPC_URL) | ||
|
||
OWNER_PRIVATE_KEY?=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 | ||
|
||
test-pause: | ||
cast send $(AIRDROP) --private-key $(OWNER_PRIVATE_KEY) "pause()" --rpc-url $(RPC_URL) | ||
|
||
test-unpause: | ||
cast send $(AIRDROP) --private-key $(OWNER_PRIVATE_KEY) "unpause()" --rpc-url $(RPC_URL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
## AlignedToken | ||
|
||
## Requirements | ||
|
||
- Foundry | ||
|
||
## Local deploying | ||
|
||
To deploy the contracts, set the following environment variables: | ||
|
||
- `DEPLOYER_PRIVATE_KEY`: The private key of the account that's going to deploy the contracts. | ||
- `SAFE_ADDRESS`: The address of the safe that's going to own the Proxy admin that in turn owns the token and airdrop contracts. | ||
- `OWNER1_ADDRESS`, `OWNER2_ADDRESS`, and `OWNER3_ADDRESS`: The three owners of the token. | ||
- `MINT_AMOUNT`: The amount to mint to each account (the contract actually supports minting different amounts of the token to each owner, but in the deploy script we simplified it). | ||
- `RPC_URL`: The url of the network to deploy to. | ||
- `CLAIM_TIME_LIMIT`: The claim time limit timestamp. | ||
- `MERKLE_ROOT`: The merkle root of all valid token claims. | ||
|
||
Example: | ||
``` | ||
export DEPLOYER_PRIVATE_KEY=<deployer_private_key> | ||
export SAFE_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 | ||
export OWNER1_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 | ||
export OWNER2_ADDRESS=0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC | ||
export OWNER3_ADDRESS=0x90F79bf6EB2c4f870365E785982E1f101E93b906 | ||
export MINT_AMOUNT=100 | ||
export RPC_URL=http://localhost:8545 | ||
export CLAIM_TIME_LIMIT=2733247661 | ||
export MERKLE_ROOT=0x90076b5fb9a6c81d9fce83dfd51760987b8c49e7c861ea25b328e6e63d2cd3df | ||
``` | ||
|
||
Then run the following script: | ||
|
||
``` | ||
./deployClaim.sh | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
|
||
forge --version >/dev/null 2>&1 | ||
if [ $? != 0 ]; then | ||
echo "Error: Please make sure you have forge installed and in your PATH" | ||
exit 2 | ||
fi | ||
|
||
safe=${SAFE_ADDRESS:-$1} | ||
owner1=${OWNER1_ADDRESS:-$2} | ||
owner2=${OWNER2_ADDRESS:-$3} | ||
owner3=${OWNER3_ADDRESS:-$4} | ||
mint_amount=${MINT_AMOUNT:-$5} | ||
rpc_url=${RPC_URL:-$6} | ||
claim_time_limit=${CLAIM_TIME_LIMIT:-2733247661} | ||
merkle_root=${MERKLE_ROOT:-$7} | ||
|
||
cd script && forge script DeployScript $safe $owner1 $owner2 $owner3 $mint_amount $claim_time_limit $merkle_root --sig "run(address,address,address,address,uint256,uint256,bytes32)" --fork-url $rpc_url --broadcast |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[profile.default] | ||
src = "src" | ||
out = "out" | ||
libs = ["lib"] | ||
optimizer = true | ||
optimizer_runs = 999_999 | ||
|
||
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options | ||
fs_permissions = [ | ||
{ access = "read-write", path = "script-out/" }, | ||
{ access = "read", path = "script-config/" }, | ||
] |
Submodule openzeppelin-contracts
added at
69c8de
Submodule openzeppelin-contracts-upgradeable
added at
fa5253
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/ | ||
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"safe": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", | ||
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
"deployer": "0x4e59b44847b379578588920cA78FbF26c0B4956C", | ||
"foundation": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", | ||
"claimSupplier": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", | ||
"claimSupplierPrivateKey": "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", | ||
"limitTimestampToClaim": 2733427549, | ||
"claimMerkleRoot": "0x90076b5fb9a6c81d9fce83dfd51760987b8c49e7c861ea25b328e6e63d2cd3df" | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import "../src/AlignedToken.sol"; | ||
import "../src/ClaimableAirdrop.sol"; | ||
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; | ||
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; | ||
import "forge-std/Script.sol"; | ||
import {Utils} from "./Utils.sol"; | ||
|
||
contract DeployAlignedToken is Script { | ||
function run(string memory config) public { | ||
string memory root = vm.projectRoot(); | ||
string memory path = string.concat( | ||
root, | ||
"/script-config/config.", | ||
config, | ||
".json" | ||
); | ||
string memory config_json = vm.readFile(path); | ||
|
||
address _safe = stdJson.readAddress(config_json, ".safe"); | ||
bytes32 _salt = stdJson.readBytes32(config_json, ".salt"); | ||
address _deployer = stdJson.readAddress(config_json, ".deployer"); | ||
address _foundation = stdJson.readAddress(config_json, ".foundation"); | ||
address _claimSupplier = stdJson.readAddress( | ||
config_json, | ||
".claimSupplier" | ||
); | ||
|
||
ProxyAdmin _proxyAdmin = deployProxyAdmin(_safe, _salt, _deployer); | ||
|
||
console.log( | ||
"Proxy Admin deployed at address:", | ||
address(_proxyAdmin), | ||
"with owner:", | ||
_safe | ||
); | ||
|
||
TransparentUpgradeableProxy _tokenProxy = deployAlignedTokenProxy( | ||
address(_proxyAdmin), | ||
_salt, | ||
_deployer, | ||
_foundation, | ||
_claimSupplier | ||
); | ||
|
||
console.log( | ||
string.concat( | ||
"Aligned Token Proxy deployed at address:", | ||
vm.toString(address(_tokenProxy)), | ||
"with proxy admin:", | ||
vm.toString(address(_proxyAdmin)), | ||
"and owner:", | ||
vm.toString(_safe) | ||
) | ||
); | ||
|
||
console.log( | ||
"Remember that the foundation must accept the ownership of the contract after deployment in another transaction." | ||
); | ||
} | ||
|
||
function deployProxyAdmin( | ||
address _safe, | ||
bytes32 _salt, | ||
address _deployer | ||
) internal returns (ProxyAdmin) { | ||
bytes memory _proxyAdminDeploymentData = Utils.proxyAdminDeploymentData( | ||
_safe | ||
); | ||
address _proxyAdminCreate2Address = Utils.deployWithCreate2( | ||
_proxyAdminDeploymentData, | ||
_salt, | ||
_deployer | ||
); | ||
|
||
return ProxyAdmin(_proxyAdminCreate2Address); | ||
} | ||
|
||
function deployAlignedTokenProxy( | ||
address _proxyAdmin, | ||
bytes32 _salt, | ||
address _deployer, | ||
address _foundation, | ||
address _claim | ||
) internal returns (TransparentUpgradeableProxy) { | ||
vm.broadcast(); | ||
AlignedToken _token = new AlignedToken(); | ||
|
||
bytes memory _alignedTokenDeploymentData = Utils | ||
.alignedTokenProxyDeploymentData( | ||
_proxyAdmin, | ||
address(_token), | ||
_foundation, | ||
_claim | ||
); | ||
address _alignedTokenProxy = Utils.deployWithCreate2( | ||
_alignedTokenDeploymentData, | ||
_salt, | ||
_deployer | ||
); | ||
return TransparentUpgradeableProxy(payable(_alignedTokenProxy)); | ||
} | ||
} |
Oops, something went wrong.