From 023e9898d6d678df32d417ccb2ed5834904bd05d Mon Sep 17 00:00:00 2001 From: tkowalczyk Date: Thu, 4 Jan 2024 10:03:14 +0100 Subject: [PATCH] contract-call-view strategy added --- src/strategies/contract-call-view/README.md | 52 ++++++++ .../contract-call-view/examples.json | 123 ++++++++++++++++++ src/strategies/contract-call-view/index.ts | 39 ++++++ src/strategies/index.ts | 2 + 4 files changed, 216 insertions(+) create mode 100644 src/strategies/contract-call-view/README.md create mode 100644 src/strategies/contract-call-view/examples.json create mode 100644 src/strategies/contract-call-view/index.ts diff --git a/src/strategies/contract-call-view/README.md b/src/strategies/contract-call-view/README.md new file mode 100644 index 000000000..26ea5e446 --- /dev/null +++ b/src/strategies/contract-call-view/README.md @@ -0,0 +1,52 @@ +# Contract call view strategy + +Allows any contract function to be used to calculate voter scores, even those one which return multiple values. + +## Examples + +Can be used instead of the `contract-call` strategy, the space config will look like this: + +```JSON +{ + "strategies": [ + ["contract-call-view", { + // contract address + "address": "0x5cA0F33f1ebD140def87721291FF313A9141F79e", + // decimals + "decimals": 18, + // index of value returned by function + "outputIndexToReturn": "1", + // ABI for view function + "methodABI": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "lastStakeTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "waitingRewards", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + }], + ] +} +``` \ No newline at end of file diff --git a/src/strategies/contract-call-view/examples.json b/src/strategies/contract-call-view/examples.json new file mode 100644 index 000000000..deb4afc4d --- /dev/null +++ b/src/strategies/contract-call-view/examples.json @@ -0,0 +1,123 @@ +[ + { + "name": "Example call to view function on staking contract", + "strategy": { + "name": "contract-call-view", + "params": { + "address": "0x5cA0F33f1ebD140def87721291FF313A9141F79e", + "decimals": 18, + "outputIndexToReturn": "1", + "methodABI": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "lastStakeTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "waitingRewards", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + } + }, + "network": "42161", + "addresses": [ + "0xf790b80B562EaB0c17181c637a4738a17e339255", + "0x0AC635d504c6795F508106f528D608d917A69022", + "0xc84622c0257Ec795D42407a913E6F4EbA7794550" + ], + "snapshot": 166777036 + }, + { + "name": "Example call to view function on lockup contract", + "strategy": { + "name": "contract-call-view", + "params": { + "address": "0xe8eb2675C7f44eE9395f58AeDd89f75834AB0dac", + "decimals": 18, + "outputIndexToReturn": "0", + "methodABI": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "stakedBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + } + }, + "network": "42161", + "addresses": [ + "0x7343bC5Be4ca81199EA4CBf987Bd520f83aC1fFf", + "0x87c5A7AAA44Db939A728cF05E31b8411A14b2579", + "0xa33A46408c871c0C4D172E8036DfCDCB19e6f226" + ], + "snapshot": 166777036 + }, + { + "name": "Example call to view function on vesting contract", + "strategy": { + "name": "contract-call-view", + "params": { + "address": "0xEd992b95d54Cbcc1bD416B95a4050468Ef5eb68F", + "decimals": 18, + "outputIndexToReturn": "0", + "methodABI": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userTotal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + } + }, + "network": "42161", + "addresses": [ + "0xA192092036526d84D7c3BFb51a3a3a68E160EFE3", + "0xcC6eA51321b9525F9eB1b29011F6621A5E5633BD", + "0xa15d3C3A330C9a3884202Ed49d49f26ED7d9f6eC" + ], + "snapshot": 166777036 + } +] \ No newline at end of file diff --git a/src/strategies/contract-call-view/index.ts b/src/strategies/contract-call-view/index.ts new file mode 100644 index 000000000..606826fe4 --- /dev/null +++ b/src/strategies/contract-call-view/index.ts @@ -0,0 +1,39 @@ +import { formatUnits } from '@ethersproject/units'; +import { multicall } from '../../utils'; + +export const author = 'tkowalczyk'; +export const version = '0.1.0'; + +function parseOutput(options, value) { + return value.toString().includes(',') + ? parseFloat(formatUnits(value.toString().split(',')[options.outputIndexToReturn], options.decimals)) + : parseFloat(formatUnits(value.toString(), options.decimals)) +} + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +) { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + const response = await multicall( + network, + provider, + [options.methodABI], + addresses.map((address: any) => [ + options.address, + options.methodABI.name, + [address] + ]), + { blockTag } + ); + return Object.fromEntries( + response.map((value, i) => [ + addresses[i], + parseOutput(options, value) + ]) + ); +} diff --git a/src/strategies/index.ts b/src/strategies/index.ts index a4b38341b..106100bef 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -11,6 +11,7 @@ import * as antiWhale from './anti-whale'; import * as balancer from './balancer'; import * as balancerSmartPool from './balancer-smart-pool'; import * as contractCall from './contract-call'; +import * as contractCallView from './contract-call-view'; import * as dfynFarms from './dfyn-staked-in-farms'; import * as dfynVaults from './dfyn-staked-in-vaults'; import * as vDfynVault from './balance-in-vdfyn-vault'; @@ -428,6 +429,7 @@ const strategies = { 'balance-in-vdfyn-vault': vDfynVault, 'erc20-received': erc20Received, 'contract-call': contractCall, + 'contract-call-view': contractCallView, defiplaza: defiplaza, 'dfyn-staked-in-farms': dfynFarms, 'dfyn-staked-in-vaults': dfynVaults,