diff --git a/src/strategies/cgpt-voting-power/README.md b/src/strategies/cgpt-voting-power/README.md new file mode 100644 index 000000000..b5026060d --- /dev/null +++ b/src/strategies/cgpt-voting-power/README.md @@ -0,0 +1,23 @@ +# cgpt-voting-power: Voting Power by Contract for ChainGPT DAO + +This strategy determines the voting power of DAO users based on the `getVotingPower` function of a specified contract. + +## Configuration + +The strategy requires the following parameters: + +- `address`: The contract address where the `getVotingPower` function is defined. +- `decimals`: The number of decimals used by the token. + +An optional parameter is: + +- `symbol`: The token symbol (for informational purposes or UI display). + +Here is an example of parameters: + +```json +{ + "address": "0xf97f22eddcaf2e891f0d528bda6113874f292b91", + "symbol": "CGPT", + "decimals": 18 +} diff --git a/src/strategies/cgpt-voting-power/examples.json b/src/strategies/cgpt-voting-power/examples.json new file mode 100644 index 000000000..c7d5ca0fa --- /dev/null +++ b/src/strategies/cgpt-voting-power/examples.json @@ -0,0 +1,36 @@ +{ + "name": "Example Query", + "strategy": { + "name": "cgpt-voting-power", + "params": { + "address": "0xf97f22eddcaf2e891f0d528bda6113874f292b91", + "decimals": 18 + } + }, + "network": "1", + "addresses": [ + "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", + "0x53d284357ec70cE289D6D64134DfAc8E511c8a3D" + ], + "snapshot": 12419867, + "example": { + "input": { + "space": {}, + "network": "1", + "provider": {}, + "addresses": [ + "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", + "0x53d284357ec70cE289D6D64134DfAc8E511c8a3D" + ], + "options": { + "address": "0xf97f22eddcaf2e891f0d528bda6113874f292b91", + "decimals": 18 + }, + "snapshot": 12419867 + }, + "output": { + "0x742d35Cc6634C0532925a3b844Bc454e4438f44e": 1000, + "0x53d284357ec70cE289D6D64134DfAc8E511c8a3D": 2000 + } + } +} diff --git a/src/strategies/cgpt-voting-power/index.ts b/src/strategies/cgpt-voting-power/index.ts new file mode 100644 index 000000000..cc9288cbe --- /dev/null +++ b/src/strategies/cgpt-voting-power/index.ts @@ -0,0 +1,40 @@ +import { BigNumberish } from '@ethersproject/bignumber'; +import { formatUnits } from '@ethersproject/units'; +import { Multicaller } from '../../utils'; + +export const author = 'ChainGPT'; +export const version = '0.1.0'; + +const abi = [ + { + "inputs": [{"internalType": "address", "name": "user", "type": "address"}], + "name": "getVotingPower", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" + } +]; + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +): Promise> { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + + const multi = new Multicaller(network, provider, abi, { blockTag }); + addresses.forEach((address) => + multi.call(address, options.address, 'getVotingPower', [address]) + ); + const result: Record = await multi.execute(); + + return Object.fromEntries( + Object.entries(result).map(([address, votingPower]) => [ + address, + parseFloat(formatUnits(votingPower, options.decimals)) + ]) + ); +} diff --git a/src/strategies/cgpt-voting-power/schema.json b/src/strategies/cgpt-voting-power/schema.json new file mode 100644 index 000000000..bf37d6680 --- /dev/null +++ b/src/strategies/cgpt-voting-power/schema.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "cgpt-voting-power", + "type": "object", + "properties": { + "address": { + "type": "string", + "title": "Contract Address", + "pattern": "^0x[a-fA-F0-9]{40}$" + }, + "symbol": { + "type": "string", + "title": "CGPT", + "minLength": 1, + "maxLength": 10 + }, + "decimals": { + "type": "integer", + "title": "Decimals", + "default": 18, + "minimum": 0, + "maximum": 77 + } + }, + "required": ["address", "decimals"], + "additionalProperties": false +}