Schnoodle is a progressive DeFi dog-themed meme token with multisig and DAO governance. The first of its kind.
- Node.js
- Visual Studio Code
- Solidity extension
- PowerShell 7 or later
- Local blockchain (use Truffle Develop or Ganache)
Follow these steps only once per remote blockchain:
- Set up Gnosis Safe and Zodiac Reality Module using this tutorial. Integrate into the Schnoodle Snapshot space (which was created using this guide).
- Update
governance.proposers
andgovernance.executors
inmigrations-config.[chain].js
with Safe address (tutorial here if required).
⚠️ ImportantEnsure that
core.symlinks
is true before cloning the repo. Usegit config --get core.symlinks
to check. Run your Git client in administrator mode to allow symlinks to be created.
- Populate the secrets.json file (see Secrets below).
- Execute
npm i
. - In Visual Studio Code, open each Solidity file in the contracts folder corresponding to the ABI files listed in Nethereum.Generator.json, and press F5 ('Solidity: Compile Contract' command).
- If target network is local, execute
truffle develop
in a separate terminal. - If target network is remote, check the gas price, and adjust the
gasPrice
value in truffle-config.js accordingly. - Execute
.\Migrate.ps1 <network> $true $true
where<network>
is the target network per thenetworks
property in truffle-config.js.
- For
mnemonic
, use any account that has some native test tokens. - For
infuraProjectId
, register an Infura account, then create a project and get the project ID. - For
etherscanApiKey
, register an Etherscan account, then create an API key. - For
bscscanApiKey
, register a BscScan account, then create an API key.
- After migration, note the 'To' contract address of the
create_0_1
internal transaction of theSchnoodleTimelockFactory
Contract Creation transaction. Verify theSchnoodleTimelock
contract using this address. - Add liquidity to Uniswap V2, and note the liquidity token address (UNI-V2 token) from the corresponding transaction.
- Create a timelock contract to lock the full amount of the liquidity token held by the beneficiary wallet.
Follow these steps to timelock tokens:
- Call
create
onSchnoodleTimelockFactory
specifying the contract address of the token to be locked, the beneficiary, and the release time as a Unix timestamp. - Once the transaction has been mined, note the 'To' contract address of the
create_0
internal transaction. Verify that this is theSchnoodleTimelock
clone address. - Transfer the desired amount of tokens to be locked from the token contract address to the
SchnoodleTimelock
clone address. - After timelock elapsed, go to
SchnoodleTimelock
clone address, and callrelease
.
- Perform a contract interaction with
TransparentUpgradeableProxy
to call a function (e.g.,changeFeePercent
,changeEleemosynary
,maintenance
,configure
).
- Execute
.\Migrate.ps1 <network>
where<network>
is the target network per thenetworks
property in truffle-config.js. - Perform a contract interaction with
ProxyAdmin
to callupgrade
usingproxy
andimplementation
parameters outputted in step 1.
Follow the timelock process if the contract owner is SchnoodleGovernance
which is typically set during deployment. Otherwise, follow the DAO process directly. If there are no multisig owners, or they have been removed, ownership of a contract may be transferred to the Gnosis Safe address by calling transferOwnership
on the contract using the timelock process.
- Go to the contract address to be interacted with and call the desired function.
- Copy the HEX DATA from MetaMask and reject the transaction.
- Follow steps 27 to 30 from here using the DAO process to interact with
SchnoodleGovernance
either 1) optionally for theexecute
step, or 2) if there is no multisig.
- Go to Snapshot space settings and ensure
address
in strategy is theTransparentUpgradeableProxy
contract address. - Go to Snapshot space new proposal and add a 'Contract Interaction' transaction:
to
is the contract address to be interacted with.function
is the function to be called.- Set the parameters as required.
- After voting is closed, anyone may trigger the following actions on the plugin:
- Request execution to put the question on Reality.eth for 24 hours.
- Set the outcome with a bond (in ETH). The outcome should resolve in accordance with the vote in (game) theory.
- After the question outcome is finalised and it is in favour, the upgrade transaction may be triggered by anyone to be executed on the interaction contract.
- If the proposal is malicious, it may be vetoed during the 24-hour cooldown period via Gnosis Safe by calling
markProposalAsInvalid
on the Reality Module.- The
proposalId
andtxHashes
values may be found from theInput Data
of the relevantAdd Proposal
transaction on the Reality Module contract.
- The
Refer to here.
If your clone path has spaces, this is due to a known bug. Avoid spaces in your clone path.