diff --git a/src/strategies/aave-governance-power/README.md b/src/strategies/aave-governance-power/README.md index f091e23ba..ecba1688b 100644 --- a/src/strategies/aave-governance-power/README.md +++ b/src/strategies/aave-governance-power/README.md @@ -9,3 +9,12 @@ Allows to get Voting power or Proposition power from an Aave GovernanceStrategy | governanceStrategy | string | The Ethereum address of the GovernanceStrategy contract to measure voting or proposition power from an address at a block. | | | | powerType | string | Use `vote` for Voting Power or `proposition` for Proposition Power | | | | | | | | | + +## Params + +| Param | Type | Description | +| ----- | ------ | ----------- | +| governanceStrategy | string | The Ethereum address of the GovernanceStrategy contract to measure voting or proposition power from an address at a block. | +| powerType | string | Use `vote` for Voting Power or `proposition` for Proposition Power | +| decimals | number | The decimals of the governance token | +| symbol | string | The symbol of the governance token | diff --git a/src/strategies/aave-governance-power/examples.json b/src/strategies/aave-governance-power/examples.json index 76b6e2b5f..831abc62c 100644 --- a/src/strategies/aave-governance-power/examples.json +++ b/src/strategies/aave-governance-power/examples.json @@ -6,7 +6,7 @@ "params": { "governanceStrategy": "0xb7e383ef9b1e9189fc0f71fb30af8aa14377429e", "powerType": "vote", - "symbol": "Voting Power", + "symbol": "ABC", "decimals": 18 } }, diff --git a/src/strategies/aave-governance-power/index.ts b/src/strategies/aave-governance-power/index.ts index 0e0542f97..a7157abf3 100644 --- a/src/strategies/aave-governance-power/index.ts +++ b/src/strategies/aave-governance-power/index.ts @@ -10,26 +10,8 @@ export const version = '0.1.0'; */ const abi = [ - { - inputs: [ - { internalType: 'address', name: 'user', type: 'address' }, - { internalType: 'uint256', name: 'blockNumber', type: 'uint256' } - ], - name: 'getPropositionPowerAt', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { internalType: 'address', name: 'user', type: 'address' }, - { internalType: 'uint256', name: 'blockNumber', type: 'uint256' } - ], - name: 'getVotingPowerAt', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function' - } + 'function getPropositionPowerAt(address user, uint256 blockNumber) view returns (uint256)', + 'function getVotingPowerAt(address user, uint256 blockNumber) view returns (uint256)' ]; const powerTypesToMethod = { diff --git a/src/strategies/aave-governance-power/schema.json b/src/strategies/aave-governance-power/schema.json new file mode 100644 index 000000000..8eaf474db --- /dev/null +++ b/src/strategies/aave-governance-power/schema.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": ["e.g. ETH"], + "maxLength": 16 + }, + "governanceStrategy": { + "type": "string", + "title": "governanceStrategy", + "examples": ["e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "integer", + "title": "Decimals", + "examples": ["e.g. 18"] + }, + "powerType": { + "type": "string", + "title": "powerType", + "examples": ["e.g. vote"] + } + }, + "required": ["governanceStrategy", "powerType"], + "additionalProperties": false + } + } +} diff --git a/src/strategies/contract-call/README.md b/src/strategies/contract-call/README.md index 40becdc7b..d23d229ea 100644 --- a/src/strategies/contract-call/README.md +++ b/src/strategies/contract-call/README.md @@ -2,80 +2,43 @@ Allows any contract method to be used to calculate voter scores. +## Params + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| address | `string` | `undefined` | The address of the contract | +| symbol (optional) | `string` | `undefined` | The symbol of the token | +| decimals | `number` | `undefined` | The decimals of the output | +| methodABI | `object` | `undefined` | The ABI of the method to call | +| output (optional) | `string` | `undefined` | If the method return an array or object, the key to use as output | + ## Examples Can be used instead of the erc20-balance-of strategy, the space config will look like this: ```JSON { - "strategies": [ - ["contract-call", { - // token address - "address": "0x6887DF2f4296e8B772cb19479472A16E836dB9e0", - // token decimals - "decimals": 18, - // token symbol - "symbol": "DAI", - // ABI for balanceOf method - "methodABI": { - "constant": true, - "inputs": [{ - "internalType": "address", - "name": "account", - "type": "address" - }], - "name": "balanceOf", - "outputs": [{ - "internalType": "uint256", - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" + "address": "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82", + "symbol": "Cake", + "decimals": 18, + "methodABI": { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" } - }], - ] -} -``` - -You can call methods with multiple inputs in any contract: - -```JSON -{ - "strategies": [ - ["contract-call", { - // contract address - "address": "0x6887DF2f4296e8B772cb19479472A16E836dB9e0", - // output decimals - "decimals": 18, - // strategy symbol - "symbol": "mySCORE", - // arguments are passed to the method; "%{address}" is replaced with the voter's address; default value ["%{address}"] - "args": ["0x6887DF2f4296e8B772cb19479472A16E836dB9e0", "%{address}"], - // method ABI, output type should be uint256 - "methodABI": { - "constant": true, - "inputs": [{ - "internalType": "address", - "name": "_someAddress", - "type": "address" - }, { - "internalType": "address", - "name": "_voterAddress", - "type": "address" - }], - "name": "totalScoresFor", - "outputs": [{ - "internalType": "uint256", - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" } - }], - ] + ], + "stateMutability": "view", + "type": "function" + } } ``` diff --git a/src/strategies/contract-call/examples.json b/src/strategies/contract-call/examples.json index 246b5118a..1d2ebdd52 100644 --- a/src/strategies/contract-call/examples.json +++ b/src/strategies/contract-call/examples.json @@ -29,7 +29,11 @@ } }, "network": "56", - "addresses": ["0x009cF7bC57584b7998236eff51b98A168DceA9B0"], - "snapshot": 13839867 + "snapshot": 31246550, + "addresses": [ + "0x009cF7bC57584b7998236eff51b98A168DceA9B0", + "0x45c54210128a065de780C4B0Df3d16664f7f859e", + "0x0eD7e52944161450477ee417DE9Cd3a859b14fD0" + ] } ] diff --git a/src/strategies/contract-call/schema.json b/src/strategies/contract-call/schema.json new file mode 100644 index 000000000..0907c7a78 --- /dev/null +++ b/src/strategies/contract-call/schema.json @@ -0,0 +1,101 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": ["e.g. ETH"], + "maxLength": 16 + }, + "address": { + "type": "string", + "title": "Contract address", + "examples": ["e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "integer", + "title": "Decimals", + "examples": ["e.g. 18"] + }, + "methodABI": { + "type": "object", + "title": "Method ABI", + "properties": { + "name": { + "type": "string", + "title": "Name", + "examples": ["e.g. balanceOf"] + }, + "inputs": { + "type": "array", + "title": "Inputs", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name", + "examples": ["e.g. account"] + }, + "type": { + "type": "string", + "title": "Type", + "examples": ["e.g. address"] + }, + "internalType": { + "type": "string", + "title": "Internal type", + "examples": ["e.g. address"] + } + }, + "required": ["name", "type"], + "additionalProperties": false + } + }, + "outputs": { + "type": "array", + "title": "Outputs", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name", + "examples": ["e.g. balance"] + }, + "type": { + "type": "string", + "title": "Type", + "examples": ["e.g. uint256"] + }, + "internalType": { + "type": "string", + "title": "Internal type", + "examples": ["e.g. uint256"] + } + }, + "required": ["name", "type"], + "additionalProperties": false + } + } + } + }, + "output": { + "type": "string", + "title": "Output (Optional)", + "examples": ["e.g. balance"] + } + }, + "required": ["address", "methodABI"], + "additionalProperties": false + } + } +} diff --git a/src/strategies/delegation/README.md b/src/strategies/delegation/README.md index c1906e369..9afd52204 100644 --- a/src/strategies/delegation/README.md +++ b/src/strategies/delegation/README.md @@ -34,4 +34,4 @@ Here is an example of parameters: ] } -``` \ No newline at end of file +``` diff --git a/src/strategies/delegation/schema.json b/src/strategies/delegation/schema.json new file mode 100644 index 000000000..4bc194655 --- /dev/null +++ b/src/strategies/delegation/schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": [ + "e.g. UNI" + ], + "maxLength": 16 + }, + "strategies": { + "type": "array", + "title": "Strategies", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "params": { + "type": "object" + }, + "network": { + "type": "string", + "title": "Network (optional)" + } + }, + "required": [ + "name", + "params" + ] + }, + "minItems": 1, + "maxItems": 8, + "uniqueItems": true + }, + "delegationSpace": { + "type": "string", + "title": "Delegation space (optional)", + "examples": [ + "e.g. poh.eth" + ] + } + }, + "required": [ + "strategies" + ], + "additionalProperties": false + } + } +} diff --git a/src/strategies/erc20-balance-of-with-delegation/examples.json b/src/strategies/erc20-balance-of-with-delegation/examples.json index 065aca672..7d3344afa 100644 --- a/src/strategies/erc20-balance-of-with-delegation/examples.json +++ b/src/strategies/erc20-balance-of-with-delegation/examples.json @@ -7,7 +7,8 @@ "symbol": "POHD", "address": "0x1dAD862095d40d43c2109370121cf087632874dB", "decimals": 0, - "delegationSpace": "poh.eth" + "delegationSpace": "poh.eth", + "delegationNetwork": "1" } }, "network": "1", diff --git a/src/strategies/erc20-balance-of-with-delegation/schema.json b/src/strategies/erc20-balance-of-with-delegation/schema.json new file mode 100644 index 000000000..0bfbda5c6 --- /dev/null +++ b/src/strategies/erc20-balance-of-with-delegation/schema.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": ["e.g. POHD"], + "maxLength": 16 + }, + "address": { + "type": "string", + "title": "Contract address", + "examples": ["e.g. 0x1dAD862095d40d43c2109370121cf087632874dB"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "integer", + "title": "Decimals", + "examples": ["e.g. 18"], + "minimum": 0, + "maximum": 18 + }, + "delegationSpace": { + "type": "string", + "title": "Delegation space (optional)", + "examples": ["e.g. poh.eth"] + }, + "delegationNetwork": { + "type": "string", + "title": "Delegation network (optional)", + "examples": ["e.g. 1"] + } + }, + "required": ["address", "decimals"], + "additionalProperties": false + } + } +} diff --git a/src/strategies/erc20-balance-of/README.md b/src/strategies/erc20-balance-of/README.md index e0af42a1b..9a4c6ed8e 100644 --- a/src/strategies/erc20-balance-of/README.md +++ b/src/strategies/erc20-balance-of/README.md @@ -2,6 +2,8 @@ This is the most common strategy, it returns the balances of the voters for a specific ERC20 token. +It uses `balanceOf` function of the ERC20 contract to get the balance of the voters. + Here is an example of parameters: ```json diff --git a/src/strategies/erc20-votes/README.md b/src/strategies/erc20-votes/README.md new file mode 100644 index 000000000..e87c2e5a1 --- /dev/null +++ b/src/strategies/erc20-votes/README.md @@ -0,0 +1,11 @@ +# erc20-votes strategy + +This strategy gets voting power from compound like contracts, it uses `getVotes` function to get the voting power of an address. + +## Params + +| Param | Type | Description | +| --- | --- | --- | +|`address`|`string`|The address of the contract to get the voting power from| +|`symbol`|`string`|The symbol of the token| +|`decimals`|`number`|The decimals of the token| diff --git a/src/strategies/erc20-votes/examples.json b/src/strategies/erc20-votes/examples.json index 7c7d3d967..f1ac7e4cb 100644 --- a/src/strategies/erc20-votes/examples.json +++ b/src/strategies/erc20-votes/examples.json @@ -4,15 +4,16 @@ "strategy": { "name": "erc20-votes", "params": { - "address": "0xc00e94cb662c3520282e6f5717214004a7f26888", - "symbol": "ENS" + "address": "0x0187Ae64E905b4FE7Dd1568a5642fbEf05E96e71", + "symbol": "APE" } }, "network": "1", "addresses": [ + "0x020cA66C30beC2c4Fe3861a94E4DB4A498A35872", "0x2B384212EDc04Ae8bB41738D05BA20E33277bf33", "0xAC5720d6EE2d7872b88914C9c5Fa9BF38e72FaF6" ], - "snapshot": 12050071 + "snapshot": 17978995 } ] diff --git a/src/strategies/erc20-votes/schema.json b/src/strategies/erc20-votes/schema.json new file mode 100644 index 000000000..7debce991 --- /dev/null +++ b/src/strategies/erc20-votes/schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": [ + "e.g. ENS" + ], + "maxLength": 16 + }, + "address": { + "type": "string", + "title": "Contract address", + "examples": ["e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "integer", + "title": "Decimals", + "examples": [ + "e.g. 18" + ], + "minimum": 0, + "maximum": 18 + } + }, + "required": [ + "address" + ], + "additionalProperties": false + } + } +} diff --git a/src/strategies/erc20-with-balance/index.ts b/src/strategies/erc20-with-balance/index.ts index 8d29a46a1..335fc2f1d 100644 --- a/src/strategies/erc20-with-balance/index.ts +++ b/src/strategies/erc20-with-balance/index.ts @@ -1,3 +1,4 @@ +import { getAddress } from '@ethersproject/address'; import { strategy as erc20BalanceOfStrategy } from '../erc20-balance-of'; export const author = 'BenjaminLu'; @@ -21,7 +22,7 @@ export async function strategy( ); return Object.fromEntries( Object.entries(score).map((address: any) => [ - address[0], + getAddress(address[0]), address[1] > (options.minBalance || 0) ? 1 : 0 ]) ); diff --git a/src/strategies/erc20-with-balance/schema.json b/src/strategies/erc20-with-balance/schema.json new file mode 100644 index 000000000..2f2e09c2d --- /dev/null +++ b/src/strategies/erc20-with-balance/schema.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": [ + "e.g. ENS" + ], + "maxLength": 16 + }, + "address": { + "type": "string", + "title": "Contract address", + "examples": ["e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "integer", + "title": "Decimals", + "examples": [ + "e.g. 18" + ], + "minimum": 0, + "maximum": 18 + }, + "minBalance": { + "type": "integer", + "title": "Min balance", + "examples": [ + "e.g. 0" + ], + "minimum": 0 + } + }, + "required": [ + "address" + ], + "additionalProperties": false + } + } +} diff --git a/src/strategies/erc721-with-multiplier/README.md b/src/strategies/erc721-with-multiplier/README.md index 76155f51e..7a06edb78 100644 --- a/src/strategies/erc721-with-multiplier/README.md +++ b/src/strategies/erc721-with-multiplier/README.md @@ -2,7 +2,15 @@ This strategy return the balances of the voters for a specific ERC721 NFT with an arbitrary multiplier. -Here is an example of parameters: +## Params + +| Param | Type | Description | Default | +| --- | --- | --- | --- | +|`address`|`string`|The address of the ERC721 contract to get the balances from| | +|`multiplier`|`number`|The multiplier to apply to the balances| 1 | +|`symbol`|`string`|The symbol of the ERC721 token| | + +## Example ```json { diff --git a/src/strategies/erc721-with-multiplier/schema.json b/src/strategies/erc721-with-multiplier/schema.json new file mode 100644 index 000000000..4156346c3 --- /dev/null +++ b/src/strategies/erc721-with-multiplier/schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": ["e.g. DOODLE"], + "maxLength": 16 + }, + "address": { + "type": "string", + "title": "Contract address", + "examples": ["e.g. 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "multiplier": { + "type": "number", + "title": "Multiplier", + "examples": ["e.g. 2"], + "minimum": 1 + } + }, + "required": ["address"], + "additionalProperties": false + } + } +} diff --git a/src/strategies/erc721/README.md b/src/strategies/erc721/README.md index f3f08c154..387f06e43 100644 --- a/src/strategies/erc721/README.md +++ b/src/strategies/erc721/README.md @@ -2,6 +2,8 @@ This strategy return the balances of the voters for a specific ERC721 NFT. +It uses `balanceOf` function of the ERC721 contract to get the balance of the voters. + Here is an example of parameters: ```json diff --git a/src/strategies/hopr-stake-and-balance-qv/examples.json b/src/strategies/hopr-stake-and-balance-qv/examples.json index d56e72a4e..e11649691 100644 --- a/src/strategies/hopr-stake-and-balance-qv/examples.json +++ b/src/strategies/hopr-stake-and-balance-qv/examples.json @@ -6,16 +6,16 @@ "params": { "tokenAddress": "0xf5581dfefd8fb0e4aec526be659cfab1f8c781da", "symbol": "HOPR", - "season": 7, - "fallbackGnosisBlock": 27852687, - "subgraphStudioProdQueryApiKey": null, - "subgraphStudioDevAccountId": null, + "season": 8, + "fallbackGnosisBlock": 29720728, + "subgraphStudioProdQueryApiKey": "41cc40f462554e6a2ce0c1470d045f7c", + "subgraphStudioDevAccountId": 40439, "subgraphHostedAccountName": "hoprnet", "useStake": true, "useHoprOnGnosis": true, "useHoprOnMainnet": true, "subgraphStudioProdAllSeasonQueryId": "DrkbaCvNGVcNH1RghepLRy6NSHFi8Dmwp4T2LN3LqcjY", - "subgraphStudioDevAllSeasonVersion": "v0.0.9", + "subgraphStudioDevAllSeasonVersion": "v0.0.10", "subgraphStudioDevAllSeasonSubgraphName": "hopr-stake-all-seasons", "subgraphHostedAllSeasonSubgraphName": "hopr-stake-all-seasons", "subgraphStudioProdHoprOnGnosisQueryId": "njToE7kpetd3P9sJdYQPSq6yQjBs7w9DahQpBj6WAoD", @@ -28,21 +28,8 @@ "addresses": [ "0x04BBB7eA18EA570aE47d4489991645E4E49bBf37", "0x2aF80738aC01e7883d11c912dFe8322C129ae5C5", - "0x0bb43EFc1a613658177D8f67CcF9CFFD8B25b906", - "0x53e85186ebF5A7d4BD06324F7b9D8B3623EF0307", - "0x2DCDB99930E279f1e9Ad11F491163051432542A0", - "0x4326990033eCd87A5444383Cf8c715E696301910", - "0xEd6a59A7C1D5a88b7cb5eb877A7A6078A7e801C7", - "0xeFC05B0D0C8bE8D4Cb3a220ef582E9f7E6FBCd00", - "0xC7B169b108c5e75991C520AEA97140534291C81D", - "0x04Be52434EB64aDdF373137310551ac42013677c", - "0xBE8C93a8C18AF63aAB449994AFAc13E71240ccC4", - "0xf813773eBDD4759c1B780d745081f046A5B776fB", - "0x7F26C34Ed10bF66602009231bBFF24f2f84e9270", - "0x4abd7276C53279b3aBFFF2B5D8A47c0AFc84833B", - "0x3e1A12a6019ee26418F22B656926fE38F5e58C5f", - "0x7A27A4D91231aCB3282b410Cc784517B417FA0DA" + "0x263A13fbe5416661d8ff67C5D98624D1553900ae" ], - "snapshot": 17220270 + "snapshot": 18026902 } ] diff --git a/src/strategies/ticket/README.md b/src/strategies/ticket/README.md index 6cf92526a..f5bc04678 100644 --- a/src/strategies/ticket/README.md +++ b/src/strategies/ticket/README.md @@ -2,6 +2,8 @@ Ticket strategy gives one voting power per one address, you can also pass a `value` parameter to give more voting power to the voter. +For better sybil resistance, use this strategy with a voting validation. + ## Params | param | type | description | default | diff --git a/src/strategies/whitelist/README.md b/src/strategies/whitelist/README.md new file mode 100644 index 000000000..dca3a2881 --- /dev/null +++ b/src/strategies/whitelist/README.md @@ -0,0 +1,9 @@ +# Whitelist strategy + +Allows to whitelist addresses and give them `1` voting power. + +## Params + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| addresses | `string[]` | `[]` | List of addresses to whitelist | diff --git a/src/strategies/whitelist/index.ts b/src/strategies/whitelist/index.ts index 35967da2f..4a11efde8 100644 --- a/src/strategies/whitelist/index.ts +++ b/src/strategies/whitelist/index.ts @@ -1,3 +1,5 @@ +import { getAddress } from '@ethersproject/address'; + export const author = 'bonustrack'; export const version = '0.1.0'; @@ -5,7 +7,7 @@ export async function strategy(space, network, provider, addresses, options) { const whitelist = options?.addresses.map((address) => address.toLowerCase()); return Object.fromEntries( addresses.map((address) => [ - address, + getAddress(address), whitelist.includes(address.toLowerCase()) ? 1 : 0 ]) ); diff --git a/src/strategies/whitelist/schema.json b/src/strategies/whitelist/schema.json new file mode 100644 index 000000000..909d8cad6 --- /dev/null +++ b/src/strategies/whitelist/schema.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": ["e.g. UNI"], + "maxLength": 16 + }, + "addresses": { + "title": "Addresses", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["addresses"], + "additionalProperties": false + } + } +} diff --git a/test/strategy.test.ts b/test/strategy.test.ts index 081d1de12..6586b0b5f 100644 --- a/test/strategy.test.ts +++ b/test/strategy.test.ts @@ -226,7 +226,13 @@ describe.each(examples)( let schema; try { schema = require(`../src/strategies/${strategy}/schema.json`); - } catch (error) { + } catch (error: any) { + if (error.code !== 'MODULE_NOT_FOUND') { + console.log('Error loading schema', error.message); + throw error; + } else { + console.log('No schema found'); + } schema = null; } (schema ? it : it.skip)(