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)
The following shared services should be set up only once per blockchain (except local):
- Gnosis Safe
- Create Safe on Gnosis Safe (mainnet) or equivalent testnet (e.g., Rinkeby).
- Update
governance.proposers
andgovernance.executors
inmigrations-config.[chain].js
with Safe address (tutorial here if required).
- Snapshot / SafeSnap
- Create a Snapshot space here using this guide.
- Deploy and enable a SafeSnap DAO module instance with a default template as per the 'Setting up the module' instructions here.
- Integrate the DAO module instance into Snapshot by adding the SafeSnap plugin to Snapshot space settings with config
{ "address": "<DAO module address>" }
.
- 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. - Execute
.\Migrate.ps1 <network> $true $true
where<network>
is the target network per thenetworks
property in truffle-config.js.
- 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.
Contract interaction is via either 1) multisig (SafeSnap optional) if SchnoodleGovernance
is the contract owner, or 2) SafeSnap (DAO) directly if the Gnosis Safe address is the contract owner. The contract owner may be set during deployment or by calling transferOwnership
on the contract. A multisig contract can be made into a DAO contract by following the multisig process using the transferOwnership
function.
- 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 and 28 from here.
- Follow steps 29 and 30 from here per either of the following scenarios:
- Multisig only: After timelock elapsed.
- DAO: Interact with
SchnoodleGovernance
via the SafeSnap process instead of directly.
- 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
markProposalInvalid
on the DAO module contract address.- The
proposalId
andtxHashes
values may be found from theInput Data
of the relevantAdd Proposal
transaction on the DAO module contract.
- The