Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 71 additions & 28 deletions claim_contracts/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
.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

.PHONY: help \
calldata-update-merkle-root calldata-update-limit-timestamp calldata-approve-spending calldata-unpause calldata-pause \
deploy-token deploy-token-sepolia deploy-token-mainnet \
deploy-claimable-local deploy-claimable-sepolia deploy-claimable-base-sepolia deploy-claimable-mainnet \
update_token_proxy upgrade-token enable-claimability \
approve-claimable claimable-update-root claimable-get-root claimable-update-timestamp claimable-get-timestamp claimable-pause claimable-unpause \
upgrade-aligned-token-implementation \
test-token test-claim test-claimed test-airdrop \
deploy-example


# ============================================================================
# Configuration — override any of these on the command line, e.g.
# make deploy-claimable-sepolia DEPLOYER_PRIVATE_KEY=0x... ETHERSCAN_API_KEY=...
# (ETHERSCAN_API_KEY, KEYSTORE_PATH, MERKLE_ROOT, TIMESTAMP, CLAIM_PROXY_ADDRESS,
# LIMIT_TIMESTAMP, etc. have no default and are passed in per invocation.)
# ============================================================================

# RPC endpoints (per network)
RPC_URL ?= http://localhost:8545
SEPOLIA_RPC_URL ?= https://ethereum-sepolia-rpc.publicnode.com
BASE_SEPOLIA_RPC_URL ?= https://sepolia.base.org
MAINNET_RPC_URL ?= https://ethereum-rpc.publicnode.com

# Signing keys (anvil defaults, for local use)
DEPLOYER_PRIVATE_KEY ?= 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
DISTRIBUTOR_PRIVATE_KEY ?= 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
OWNER_PRIVATE_KEY ?= 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a

# Deploy config + contract addresses (anvil defaults)
CONFIG ?= example
AIRDROP ?= 0xBC9129Dc0487fc2E169941C75aABC539f208fb01
TOKEN ?= 0x2E983A1Ba5e8b38AAAeC4B440B9dDcFBf72E15d1
APPROVE_AMOUNT ?= 2600000000000000000000000000

# Test inputs — require 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 ')
Comment on lines +37 to +38

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low — Both variables hit the same URL but as separate $(shell ...) calls. With = (recursive expansion), Make re-runs each shell command every time the variable is referenced, so test-claim makes two separate HTTP requests to the proof API for the same CLAIMER. A single call that captures both fields would be more reliable.

Additionally, note these variables are already flagged via the test-claim TODO comment as outdated (wrong ABI, wrong endpoint). Consider removing them along with test-claim instead of moving them to the top-level.


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}'
Expand All @@ -23,36 +59,32 @@ calldata-pause: ## 💾 Calldata for the method `pause` to use in a transaction

# Deployments

RPC_URL?=http://localhost:8545
DEPLOYER_PRIVATE_KEY?=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
CONFIG?=example
deploy-token: ## 🚀 Deploy the token contract
cd script && \
forge script DeployAlignedToken.s.sol \
--sig "run(string)" \
$(CONFIG) \
--private-key $(DEPLOYER_PRIVATE_KEY) \
--rpc-url $(RPC_URL) \
--broadcast \
--verbosity 3
--broadcast

deploy-token-testnet: ## 🚀 Deploy the token contract
deploy-token-sepolia: ## 🚀 Deploy the token contract in Sepolia
cd script && \
forge script DeployAlignedToken.s.sol \
--sig "run(string)" sepolia \
--private-key $(DEPLOYER_PRIVATE_KEY) \
--rpc-url $(RPC_URL) \
--rpc-url $(SEPOLIA_RPC_URL) \
--broadcast \
--verify \
--etherscan-api-key $(ETHERSCAN_API_KEY)

deploy-token-prod: ## 🚀 Deploy the token contract
deploy-token-mainnet: ## 🚀 Deploy the token contract in Mainnet
cd script && \
forge script DeployAlignedToken.s.sol \
--sig "run(string)" \
$(PROD_CONFIG) \
mainnet \
--keystore $(KEYSTORE_PATH) \
--rpc-url $(PROD_RPC_URL) \
--rpc-url $(MAINNET_RPC_URL) \
--broadcast \
--verbosity 3

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowdeploy-token-mainnet is missing --verify --etherscan-api-key $(ETHERSCAN_API_KEY), unlike every other network-deployment target (deploy-token-sepolia, deploy-claimable-sepolia, deploy-claimable-base-sepolia, deploy-claimable-mainnet). An unverified mainnet token contract is hard to audit after the fact.

Suggested change
--verbosity 3
deploy-token-mainnet: ## 🚀 Deploy the token contract in Mainnet
cd script && \
forge script DeployAlignedToken.s.sol \
--sig "run(string)" \
mainnet \
--keystore $(KEYSTORE_PATH) \
--rpc-url $(MAINNET_RPC_URL) \
--broadcast \
--verify \
--etherscan-api-key $(ETHERSCAN_API_KEY) \
--verbosity 3


Expand All @@ -64,12 +96,22 @@ deploy-claimable-local: ## 🚀 Deploy the airdrop contract in localnet
--rpc-url http://localhost:8545 \
--broadcast

deploy-claimable-testnet: ## 🚀 Deploy the airdrop contract in Sepolia
deploy-claimable-sepolia: ## 🚀 Deploy the airdrop contract in Sepolia
cd script && \
forge script DeployClaimableAirdrop.s.sol \
--sig "run(string)" sepolia \
--private-key $(DEPLOYER_PRIVATE_KEY) \
--rpc-url $(RPC_URL) \
--rpc-url $(SEPOLIA_RPC_URL) \
--broadcast \
--verify \
--etherscan-api-key $(ETHERSCAN_API_KEY)

deploy-claimable-base-sepolia: ## 🚀 Deploy the airdrop contract in Base Sepolia
cd script && \
forge script DeployClaimableAirdrop.s.sol \
--sig "run(string)" base-sepolia \
--private-key $(DEPLOYER_PRIVATE_KEY) \
--rpc-url $(BASE_SEPOLIA_RPC_URL) \
--broadcast \
--verify \
--etherscan-api-key $(ETHERSCAN_API_KEY)
Expand All @@ -79,40 +121,41 @@ deploy-claimable-mainnet: ## 🚀 Deploy the airdrop contract in Mainnet
forge script DeployClaimableAirdrop.s.sol \
--sig "run(string)" mainnet \
--keystore $(KEYSTORE_PATH) \
--rpc-url https://eth.llamarpc.com \
--rpc-url $(MAINNET_RPC_URL) \
--broadcast \
--verify \
--etherscan-api-key $(ETHERSCAN_API_KEY)


# TODO: broken — reads script-out/deployed_token_addresses.json (never generated by the deploy
# scripts) and treats $(CONFIG) as a file path. Fix or remove.
update_token_proxy:
@NEW_TOKEN_PROXY=$$(jq -r '.tokenProxy' "script-out/deployed_token_addresses.json") && \
jq --arg new_proxy "$$NEW_TOKEN_PROXY" '.tokenProxy = $$new_proxy' $(CONFIG) > $(CONFIG).tmp \
&& mv $(CONFIG).tmp $(CONFIG)

# TODO: broken — runs UpgradeToken.s.sol, which does not exist in script/. Fix or remove
# (see the README "Upgrades" section, which expects the upgrade script to be written ad-hoc).
upgrade-token: ## 🚀 Upgrade the token contract
cd script && \
forge script UpgradeToken.s.sol \
--sig "run(string)" \
$(CONFIG) \
--private-key $(PRIVATE_KEY) \
--private-key $(DEPLOYER_PRIVATE_KEY) \
--rpc-url $(RPC_URL) \
--broadcast \
--verbosity 3

# Miscellaneous

DISTRIBUTOR_PRIVATE_KEY?=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
OWNER_PRIVATE_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
AIRDROP=0xBC9129Dc0487fc2E169941C75aABC539f208fb01
TOKEN=0x2E983A1Ba5e8b38AAAeC4B440B9dDcFBf72E15d1
enable-claimability: claimable-update-root claimable-update-timestamp approve-claimable claimable-unpause ## 🚀 Run every tx needed to start claiming (set root, set deadline, approve, unpause)

approve-claimable: ## 🚀 Approve the ClaimableAirdrop contract to spend the token
cast send \
--rpc-url $(RPC_URL) \
--private-key $(DISTRIBUTOR_PRIVATE_KEY) \
$(TOKEN) \
'approve(address,uint256)' $(AIRDROP) 2600000000000000000000000000
'approve(address,uint256)' $(AIRDROP) $(APPROVE_AMOUNT)

claimable-update-root: ## 🚀 Update the merkle root of the ClaimableAirdrop contract
cast send \
Expand Down Expand Up @@ -154,13 +197,15 @@ claimable-unpause:

# Upgrades

# TODO: broken — script/aligned_token/UpgradeAlignedTokenImplementation.s.sol doesn't exist and
# --sig has a stray leading "function". Fix or remove.
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) \
--private-key $(DEPLOYER_PRIVATE_KEY) \
--broadcast

# Test targets
Expand All @@ -170,21 +215,19 @@ test-token:
cast call $(ADDRESS) "symbol()(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 ')
# TODO: outdated — claim is now claim(uint256 amount,uint256 validFrom,bytes32[] proof) and the
# proof comes from the web app's /api/wallets/<address>, not /api/proof/<claimer>. Fix.
test-claim:
cast send $(AIRDROP) --private-key $(CLAIMER_PRIVATE_KEY) "claim(uint256,bytes32[])" $(AMOUNT_TO_CLAIM) "$(MERKLE_PROOF_TO_CLAIM)" --rpc-url $(RPC_URL)

# TODO: outdated — hasClaimed is now hasClaimed(bytes32 leaf), not hasClaimed(address). Fix.
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-airdrop:
cast call $(AIRDROP) "paused()(bool)" --rpc-url $(RPC_URL)
cast call $(AIRDROP) "owner()(address)" --rpc-url $(RPC_URL)

# Requires MERKLE_ROOT, TIMESTAMP
deploy-example: deploy-token deploy-claimable-local claimable-update-root claimable-update-timestamp approve-claimable claimable-unpause
deploy-example: deploy-token deploy-claimable-local enable-claimability
Loading
Loading