From 664279b1e6456d9ffdec9816a81917ad12ef5b83 Mon Sep 17 00:00:00 2001 From: MJ Date: Thu, 21 Sep 2023 17:04:42 -0600 Subject: [PATCH] Notes Strategy Creation --- src/strategies/monsta-dce/README.md | 24 +++++++++++ src/strategies/monsta-dce/examples.json | 21 +++++++++ src/strategies/monsta-dce/index.ts | 57 +++++++++++++++++++++++++ src/strategies/monsta-dce/schema.json | 35 +++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 src/strategies/monsta-dce/README.md create mode 100644 src/strategies/monsta-dce/examples.json create mode 100644 src/strategies/monsta-dce/index.ts create mode 100644 src/strategies/monsta-dce/schema.json diff --git a/src/strategies/monsta-dce/README.md b/src/strategies/monsta-dce/README.md new file mode 100644 index 000000000..bcf1f3b18 --- /dev/null +++ b/src/strategies/monsta-dce/README.md @@ -0,0 +1,24 @@ +# Monsta DCE Strategy + +This custom voting strategy, known as the Monsta DCE Strategy, is designed to determine voting power based on specific criteria. Users must meet certain requirements to have voting power in a snapshot vote. + +## Strategy Overview + +The Monsta DCE Strategy requires users to hold at least one ERC721 token and have a minimum balance of 5,000,000 of a specified ERC20 token. If users meet these conditions, they will be granted voting power. Otherwise, they will have no voting power. + +## Parameters + +- ERC721 Token Address: The address of the ERC721 token contract. +- ERC20 Token Address: The address of the ERC20 token contract. +- ERC20 Token Decimals: The number of decimal places used by the ERC20 token. + +## Example Setup + +Here is an example setup for the Monsta DCE Strategy: + +```json +{ + "erc721Address": "0x371a31Bf669Df23628E9D8858CB4b4620B491D83", + "erc20Address": "0x8A5d7FCD4c90421d21d30fCC4435948aC3618B2f", + "erc20Decimals": 18 +} diff --git a/src/strategies/monsta-dce/examples.json b/src/strategies/monsta-dce/examples.json new file mode 100644 index 000000000..456b54f22 --- /dev/null +++ b/src/strategies/monsta-dce/examples.json @@ -0,0 +1,21 @@ +[ + { + "name": "Monsta DCE Strategy Example", + "strategy": { + "name": "monsta-dce", + "params": { + "erc721Address": "0x371a31Bf669Df23628E9D8858CB4b4620B491D83", + "erc20Address": "0x8A5d7FCD4c90421d21d30fCC4435948aC3618B2f", + "erc20Decimals": 18 + } + }, + "network": "1", + "addresses": [ + "0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11", + "0xeF8305E140ac520225DAf050e2f71d5fBcC543e7", + "0x1E1A51E25f2816335cA436D65e9Af7694BE232ad" + // Add more addresses here for testing if needed + ], + "snapshot": 11437846 + } +] diff --git a/src/strategies/monsta-dce/index.ts b/src/strategies/monsta-dce/index.ts new file mode 100644 index 000000000..05507804e --- /dev/null +++ b/src/strategies/monsta-dce/index.ts @@ -0,0 +1,57 @@ +import { BigNumberish, utils } from 'ethers'; +import { Multicaller } from '../../utils'; + +export const author = 'Crypt0MJ'; +export const version = '1.0.0'; +export const strategyName = 'monsta-dce-strategy'; + +const erc20Abi = [ + 'function balanceOf(address account) external view returns (uint256)', +]; + +const erc721Abi = [ + 'function balanceOf(address owner) external view returns (uint256)', +]; + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +): Promise> { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + const multi = new Multicaller(network, provider); + + const erc20Balances = await multi.all( + addresses.map((address) => [ + options.erc20Address, + 'balanceOf', + [address], + { blockTag }, + ]) + ); + + const erc721Balances = await multi.all( + addresses.map((address) => [ + options.erc721Address, + 'balanceOf', + [address], + { blockTag }, + ]) + ); + + const votingPower = {}; + addresses.forEach((address, index) => { + const erc20Balance = utils.formatUnits(erc20Balances[index], options.erc20Decimals); + const erc721Balance = erc721Balances[index]; + if (parseFloat(erc20Balance) >= 5000000 && parseFloat(erc721Balance) >= 1) { + votingPower[address] = 1; // You can customize the voting power as needed. + } else { + votingPower[address] = 0; // No voting power if requirements are not met. + } + }); + + return votingPower; +} diff --git a/src/strategies/monsta-dce/schema.json b/src/strategies/monsta-dce/schema.json new file mode 100644 index 000000000..03f8a87f0 --- /dev/null +++ b/src/strategies/monsta-dce/schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Monsta DCE Strategy", + "type": "object", + "properties": { + "erc721Address": { + "type": "string", + "title": "ERC721 Contract Address", + "examples": ["e.g. 0x371a31Bf669Df23628E9D8858CB4b4620B491D83"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "erc20Address": { + "type": "string", + "title": "ERC20 Contract Address", + "examples": ["e.g. 0x8A5d7FCD4c90421d21d30fCC4435948aC3618B2f"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "erc20Decimals": { + "type": "number", + "title": "ERC20 Decimals", + "examples": ["e.g. 18"] + } + }, + "required": ["erc721Address", "erc20Address", "erc20Decimals"], + "additionalProperties": false + } + } +} \ No newline at end of file