Using:
- slides
forge
commands don't show the output well.jq
commands combined withsponge
are used to output the contract addresses to the screen and changing the.envrc
file.
- Use
Ctrl-E
to run thebash
snippets. slides README.md
to run the slides in the terminal.
- direnv
direnv allow
ordirenv reload
doesn't work directly when runningslides
.
- Gradual Token Release: Tokens are released over time, not all at once. | |
- Encourages Long-Term Commitment: Stakeholders are motivated to stay with the project. | |
- Reduces Market Risks: Prevents sudden sell-offs that can destabilize prices. | |
- Builds Credibility: Shows transparency, attracting more investors and partners. | |
- Flexible Schedules: Can include linear vesting or cliff vesting options.
Tokenomics
- Real Case: OP - Unlock Schedule & Tokenomics
- Multi Sig wallets are
contracts
. | | - We have
N
owners. | | - Each owner can create transactions
- to execute them
M
owners have to "sign" it.
- to execute them
- Shared Responsibility |
- Adaptable to Team Structures |
- Risk Mitigation
- Reduced Risk of Human Error
- Protection Against Threats:
- Unavailability of Signers |
- Multiple Points of Attack |
- Hard to Manage |
- Complexity in Interacting with Smart Contracts
- Difficulty in Executing Transactions
There are two easy
ways to deploy a multi-signature wallet.
The hard
way involves directly interacting with the contracts.
Using Safe's CLI:
docker run -it safeglobal/safe-cli safe-creator \
https://ethereum-sepolia-rpc.publicnode.com \
$DEPLOYER_PRIVATE_KEY \
--threshold 1 \
--owners $DEPLOYER_ADDRESS
NOTE: It's interactive.
Using the web app:
- [Create Safe Wallet]
- [Create ERC20] -> [Mint to Safe Wallet]
- [Create Vesting Wallet]
- [Propose multisig TX sending some ERC20] from
SAFE_WALLET
toVESTING_WALLET
- [Release ERC20]
cp .envrc.example .envrc
Set the env variables in the .envrc
file:
DEPLOYER_PRIVATE_KEY
DEPLOYER_ADDRESS
SEPOLIA_URL
Set the env variable in the .envrc
file:
INITIAL_SUPPLY
direnv allow
If changes are made, the variables have to be reloaded:
direnv reload
NOTE: If running it as a slide
, you have to close and reopen the slide after running the command.
forge script script/Deploy.s.sol:DeployToken --rpc-url $SEPOLIA_URL --broadcast
jq '.transactions[0].contractAddress' broadcast/Deploy.s.sol/11155111/run-latest.json | awk '{print "Contract Address: \033[0;32m" $0 "\033[0m"}'
Use the output to set ERC20_CONTRACT_ADDRESS
in the .envrc
.
The following command does this automatically:
awk -v new_value="$(jq -r '.transactions[0].contractAddress' broadcast/Deploy.s.sol/11155111/run-latest.json)" '/^export ERC20_CONTRACT_ADDRESS=/ {print "export ERC20_CONTRACT_ADDRESS=" new_value; next} 1' .envrc | sponge .envrc
START_TIME=$(date +%s) forge script script/Deploy.s.sol:DeployVesting --rpc-url $SEPOLIA_URL --broadcast
jq '.transactions[0].contractAddress' broadcast/Deploy.s.sol/11155111/run-latest.json | awk '{print "Contract Address: \033[0;32m" $0 "\033[0m"}'
Use the output to set the VESTING_CONTRACT_ADDRESS
in the .envrc
.
The following command does this automatically:
awk -v new_value="$(jq -r '.transactions[0].contractAddress' broadcast/Deploy.s.sol/11155111/run-latest.json)" '/^export VESTING_CONTRACT_ADDRESS=/ {print "export VESTING_CONTRACT_ADDRESS=" new_value; next} 1' .envrc | sponge .envrc
echo $VESTING_CONTRACT_ADDRESS
cast call $VESTING_CONTRACT_ADDRESS "releasable(address)(uint256)" $ERC20_CONTRACT_ADDRESS --rpc-url $SEPOLIA_URL
cast balance --erc20 $ERC20_CONTRACT_ADDRESS $BENEFICIARY_ADDRESS --rpc-url $SEPOLIA_URL
cast send $VESTING_CONTRACT_ADDRESS "release(address)" $ERC20_CONTRACT_ADDRESS --rpc-url $SEPOLIA_URL --private-key $BENEFICIARY_PRIVATE_KEY
cast balance --erc20 $ERC20_CONTRACT_ADDRESS $BENEFICIARY_ADDRESS --rpc-url $SEPOLIA_URL