Using:
- slides
forgecommands don't show the output well.jqcommands combined withspongeare used to output the contract addresses to the screen and changing the.envrcfile.
- Use
Ctrl-Eto run thebashsnippets. slides README.mdto run the slides in the terminal.
- direnv
direnv allowordirenv reloaddoesn'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
Nowners. | | - Each owner can create transactions
- to execute them
Mowners 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_ADDRESSNOTE: 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_WALLETtoVESTING_WALLET
- [Release ERC20]
cp .envrc.example .envrcSet the env variables in the .envrc file:
DEPLOYER_PRIVATE_KEYDEPLOYER_ADDRESSSEPOLIA_URL
Set the env variable in the .envrc file:
INITIAL_SUPPLY
direnv allowIf changes are made, the variables have to be reloaded:
direnv reloadNOTE: 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 --broadcastjq '.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 .envrcSTART_TIME=$(date +%s) forge script script/Deploy.s.sol:DeployVesting --rpc-url $SEPOLIA_URL --broadcastjq '.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 .envrcecho $VESTING_CONTRACT_ADDRESScast call $VESTING_CONTRACT_ADDRESS "releasable(address)(uint256)" $ERC20_CONTRACT_ADDRESS --rpc-url $SEPOLIA_URLcast balance --erc20 $ERC20_CONTRACT_ADDRESS $BENEFICIARY_ADDRESS --rpc-url $SEPOLIA_URLcast send $VESTING_CONTRACT_ADDRESS "release(address)" $ERC20_CONTRACT_ADDRESS --rpc-url $SEPOLIA_URL --private-key $BENEFICIARY_PRIVATE_KEYcast balance --erc20 $ERC20_CONTRACT_ADDRESS $BENEFICIARY_ADDRESS --rpc-url $SEPOLIA_URL