diff --git a/src/apps/spool-v2/assets/logo.png b/src/apps/spool-v2/assets/logo.png new file mode 100644 index 000000000..154bed7a3 Binary files /dev/null and b/src/apps/spool-v2/assets/logo.png differ diff --git a/src/apps/spool-v2/contracts/abis/spool-lens.json b/src/apps/spool-v2/contracts/abis/spool-lens.json new file mode 100644 index 000000000..c8bc0c8ab --- /dev/null +++ b/src/apps/spool-v2/contracts/abis/spool-lens.json @@ -0,0 +1,132 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "smartVault", + "type": "address" + } + ], + "name": "getSVTTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "address", + "name": "riskProvider", + "type": "address" + }, + { + "internalType": "address", + "name": "allocationProvider", + "type": "address" + } + ], + "name": "getSmartVaultAllocations", + "outputs": [ + { + "internalType": "uint256[][]", + "name": "allocations", + "type": "uint256[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "smartVault", + "type": "address" + }, + { + "internalType": "bool", + "name": "doFlush", + "type": "bool" + } + ], + "name": "getSmartVaultAssetBalances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "smartVault", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "nftIds", + "type": "uint256[]" + } + ], + "name": "getUserSVTBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "currentBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "smartVault", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "nftIds", + "type": "uint256[]" + } + ], + "name": "getUserSVTsfromNFTs", + "outputs": [ + { + "internalType": "uint256[]", + "name": "nftSvts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/spool-v2/contracts/abis/spool-staking.json b/src/apps/spool-v2/contracts/abis/spool-staking.json new file mode 100644 index 000000000..cec171051 --- /dev/null +++ b/src/apps/spool-v2/contracts/abis/spool-staking.json @@ -0,0 +1,810 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "contract IVoSPOOL", + "name": "_voSpool", + "type": "address" + }, + { + "internalType": "contract IVoSpoolRewards", + "name": "_voSpoolRewards", + "type": "address" + }, + { + "internalType": "contract IRewardDistributor", + "name": "_rewardDistributor", + "type": "address" + }, + { + "internalType": "contract ISpoolOwner", + "name": "_spoolOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "canStakeFor", + "type": "bool" + } + ], + "name": "CanStakeForSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "periodFinish", + "type": "uint32" + } + ], + "name": "PeriodFinishUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardCompounded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "RewardRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "leftover", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "periodFinish", + "type": "uint32" + } + ], + "name": "RewardUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "stakedFor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "stakedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "StakedFor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Unstaked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "VoRewardCompounded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "VoSpoolRewardPaid", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "rewardsDuration", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "addToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "allowFor", + "type": "address" + } + ], + "name": "allowUnstakeFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "canStakeFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "doCompoundVoSpoolRewards", + "type": "bool" + } + ], + "name": "compound", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "doClaimVoSpoolRewards", + "type": "bool" + } + ], + "name": "getActiveRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "doClaimVoSpoolRewards", + "type": "bool" + } + ], + "name": "getRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getUpdatedVoSpoolRewardAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_rewardsDuration", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recoverTo", + "type": "address" + } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "removeReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "rewardConfiguration", + "outputs": [ + { + "internalType": "uint32", + "name": "rewardsDuration", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "periodFinish", + "type": "uint32" + }, + { + "internalType": "uint192", + "name": "rewardRate", + "type": "uint192" + }, + { + "internalType": "uint32", + "name": "lastUpdateTime", + "type": "uint32" + }, + { + "internalType": "uint224", + "name": "rewardPerTokenStored", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardDistributor", + "outputs": [ + { + "internalType": "contract IRewardDistributor", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardTokens", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokensCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_canStakeFor", + "type": "bool" + } + ], + "name": "setCanStakeFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "stakeFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "stakedBy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "tokenBlacklist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "timestamp", + "type": "uint32" + } + ], + "name": "updatePeriodFinish", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "voSpool", + "outputs": [ + { + "internalType": "contract IVoSPOOL", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voSpoolRewards", + "outputs": [ + { + "internalType": "contract IVoSpoolRewards", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/spool-v2/contracts/abis/spool-vault.json b/src/apps/spool-v2/contracts/abis/spool-vault.json new file mode 100644 index 000000000..5ac084cfe --- /dev/null +++ b/src/apps/spool-v2/contracts/abis/spool-vault.json @@ -0,0 +1,815 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "baseUri", + "type": "string" + } + ], + "name": "BaseURIChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "assetGroupId", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOfFractional", + "outputs": [ + { + "internalType": "uint256", + "name": "fractionalBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfFractionalBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "fractionalBalances", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "nftIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "nftAmounts", + "type": "uint256[]" + } + ], + "name": "burnNFTs", + "outputs": [ + { + "internalType": "bytes[]", + "name": "metadata", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vaultShares", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "shares", + "type": "uint256[]" + } + ], + "name": "burnVaultShares", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "claimer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "claimShares", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "nftIds", + "type": "uint256[]" + } + ], + "name": "getMetadata", + "outputs": [ + { + "internalType": "bytes[]", + "name": "metadata", + "type": "bytes[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256[]", + "name": "assets", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "initiated", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "flushIndex", + "type": "uint256" + } + ], + "internalType": "struct DepositMetadata", + "name": "metadata", + "type": "tuple" + } + ], + "name": "mintDepositNFT", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vaultShares", + "type": "uint256" + } + ], + "name": "mintVaultShares", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "vaultShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "flushIndex", + "type": "uint256" + } + ], + "internalType": "struct WithdrawalMetadata", + "name": "metadata", + "type": "tuple" + } + ], + "name": "mintWithdrawalNFT", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "uri_", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFromSpender", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultName", + "outputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/spool-v2/contracts/abis/spool-vospool.json b/src/apps/spool-v2/contracts/abis/spool-vospool.json new file mode 100644 index 000000000..d8014ca64 --- /dev/null +++ b/src/apps/spool-v2/contracts/abis/spool-vospool.json @@ -0,0 +1,1173 @@ +[ + { + "inputs": [ + { + "internalType": "contract ISpoolOwner", + "name": "_spoolOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_firstTrancheEndTime", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "source", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Burned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "lastUpdatedTrancheIndex", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "totalMaturedVotingPower", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "totalMaturingAmount", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint56", + "name": "totalRawUnmaturedVotingPower", + "type": "uint56" + } + ], + "name": "GlobalGradualUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "source", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "burnAll", + "type": "bool" + } + ], + "name": "GradualBurned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "GradualMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "set", + "type": "bool" + } + ], + "name": "GradualMinterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Minted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "set", + "type": "bool" + } + ], + "name": "MinterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "lastUpdatedTrancheIndex", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "maturedVotingPower", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "maturingAmount", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint56", + "name": "rawUnmaturedVotingPower", + "type": "uint56" + } + ], + "name": "UserGradualUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "FULL_POWER_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULL_POWER_TRANCHES_COUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TRANCHE_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "burnAll", + "type": "bool" + } + ], + "name": "burnGradual", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "firstTrancheStartTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentTrancheIndex", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGlobalGradual", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "totalMaturedVotingPower", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "totalMaturingAmount", + "type": "uint48" + }, + { + "internalType": "uint56", + "name": "totalRawUnmaturedVotingPower", + "type": "uint56" + }, + { + "internalType": "uint16", + "name": "lastUpdatedTrancheIndex", + "type": "uint16" + } + ], + "internalType": "struct GlobalGradual", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastFinishedTrancheIndex", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextTrancheEndTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNotUpdatedGlobalGradual", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "totalMaturedVotingPower", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "totalMaturingAmount", + "type": "uint48" + }, + { + "internalType": "uint56", + "name": "totalRawUnmaturedVotingPower", + "type": "uint56" + }, + { + "internalType": "uint16", + "name": "lastUpdatedTrancheIndex", + "type": "uint16" + } + ], + "internalType": "struct GlobalGradual", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getNotUpdatedUserGradual", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "maturedVotingPower", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "maturingAmount", + "type": "uint48" + }, + { + "internalType": "uint56", + "name": "rawUnmaturedVotingPower", + "type": "uint56" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "arrayIndex", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "position", + "type": "uint8" + } + ], + "internalType": "struct UserTranchePosition", + "name": "oldestTranchePosition", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "arrayIndex", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "position", + "type": "uint8" + } + ], + "internalType": "struct UserTranchePosition", + "name": "latestTranchePosition", + "type": "tuple" + }, + { + "internalType": "uint16", + "name": "lastUpdatedTrancheIndex", + "type": "uint16" + } + ], + "internalType": "struct UserGradual", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalGradualVotingPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "trancheIndex", + "type": "uint256" + } + ], + "name": "getTrancheEndTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "getTrancheIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserGradual", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "maturedVotingPower", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "maturingAmount", + "type": "uint48" + }, + { + "internalType": "uint56", + "name": "rawUnmaturedVotingPower", + "type": "uint56" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "arrayIndex", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "position", + "type": "uint8" + } + ], + "internalType": "struct UserTranchePosition", + "name": "oldestTranchePosition", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "arrayIndex", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "position", + "type": "uint8" + } + ], + "internalType": "struct UserTranchePosition", + "name": "latestTranchePosition", + "type": "tuple" + }, + { + "internalType": "uint16", + "name": "lastUpdatedTrancheIndex", + "type": "uint16" + } + ], + "internalType": "struct UserGradual", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserGradualVotingPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "gradualMinters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "indexedGlobalTranches", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + } + ], + "internalType": "struct Tranche", + "name": "zero", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + } + ], + "internalType": "struct Tranche", + "name": "one", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + } + ], + "internalType": "struct Tranche", + "name": "two", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + } + ], + "internalType": "struct Tranche", + "name": "three", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + } + ], + "internalType": "struct Tranche", + "name": "four", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mintGradual", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gradualMinter", + "type": "address" + }, + { + "internalType": "bool", + "name": "_set", + "type": "bool" + } + ], + "name": "setGradualMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + }, + { + "internalType": "bool", + "name": "_set", + "type": "bool" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalInstantPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "updateUserVotingPower", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateVotingPower", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInstantPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userTranches", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + }, + { + "internalType": "uint16", + "name": "index", + "type": "uint16" + } + ], + "internalType": "struct UserTranche", + "name": "zero", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + }, + { + "internalType": "uint16", + "name": "index", + "type": "uint16" + } + ], + "internalType": "struct UserTranche", + "name": "one", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + }, + { + "internalType": "uint16", + "name": "index", + "type": "uint16" + } + ], + "internalType": "struct UserTranche", + "name": "two", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint48", + "name": "amount", + "type": "uint48" + }, + { + "internalType": "uint16", + "name": "index", + "type": "uint16" + } + ], + "internalType": "struct UserTranche", + "name": "three", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/spool-v2/contracts/abis/strategy-registry.json b/src/apps/spool-v2/contracts/abis/strategy-registry.json new file mode 100644 index 000000000..5c23a66e9 --- /dev/null +++ b/src/apps/spool-v2/contracts/abis/strategy-registry.json @@ -0,0 +1,801 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "ecosystemFeeReceiver", + "type": "address" + } + ], + "name": "EcosystemFeeReceiverSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feePct", + "type": "uint256" + } + ], + "name": "EcosystemFeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "wallet", + "type": "address" + } + ], + "name": "EmergencyWithdrawalWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "apy", + "type": "int256" + } + ], + "name": "StrategyApyUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dhwIndex", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "sharesMinted", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "assetsWithdrawn", + "type": "uint256[]" + }, + { + "internalType": "int256", + "name": "yieldPercentage", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "valueAtDhw", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSstsAtDhw", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct DhwInfo", + "name": "dhwInfo", + "type": "tuple" + } + ], + "name": "StrategyDhw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "strategy", + "type": "address" + } + ], + "name": "StrategyRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "strategy", + "type": "address" + } + ], + "name": "StrategyRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "assetsWithdrawn", + "type": "uint256[]" + } + ], + "name": "StrategySharesFastRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "assetsWithdrawn", + "type": "uint256[]" + } + ], + "name": "StrategySharesRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "treasuryFeeReceiver", + "type": "address" + } + ], + "name": "TreasuryFeeReceiverSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feePct", + "type": "uint256" + } + ], + "name": "TreasuryFeeSet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint256[][]", + "name": "amounts", + "type": "uint256[][]" + } + ], + "name": "addDeposits", + "outputs": [ + { + "internalType": "uint16a16", + "name": "strategyIndexes", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "strategyShares", + "type": "uint256[]" + } + ], + "name": "addWithdrawals", + "outputs": [ + { + "internalType": "uint16a16", + "name": "strategyIndexes", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "strategy", + "type": "address" + } + ], + "name": "assetRatioAtLastDhw", + "outputs": [ + { + "internalType": "uint256[]", + "name": "assetRatio", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint16a16", + "name": "dhwIndexes", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "strategyShares", + "type": "uint256[]" + } + ], + "name": "claimWithdrawals", + "outputs": [ + { + "internalType": "uint256[]", + "name": "assetsWithdrawn", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + } + ], + "name": "currentIndex", + "outputs": [ + { + "internalType": "uint256[]", + "name": "dhwIndexes", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "dhwIndex", + "type": "uint256" + } + ], + "name": "depositedAssets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "assets", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint16a16", + "name": "dhwIndexes", + "type": "uint256" + } + ], + "name": "dhwTimestamps", + "outputs": [ + { + "internalType": "uint256[]", + "name": "timestamps", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address[][]", + "name": "strategies", + "type": "address[][]" + }, + { + "components": [ + { + "internalType": "address", + "name": "swapTarget", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapCallData", + "type": "bytes" + } + ], + "internalType": "struct SwapInfo[][][]", + "name": "swapInfo", + "type": "tuple[][][]" + }, + { + "components": [ + { + "internalType": "address", + "name": "swapTarget", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapCallData", + "type": "bytes" + } + ], + "internalType": "struct SwapInfo[][][]", + "name": "compoundSwapInfo", + "type": "tuple[][][]" + }, + { + "internalType": "uint256[][][]", + "name": "strategySlippages", + "type": "uint256[][][]" + }, + { + "internalType": "int256[][]", + "name": "baseYields", + "type": "int256[][]" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[2][]", + "name": "exchangeRateSlippages", + "type": "uint256[2][]" + }, + { + "internalType": "uint256", + "name": "validUntil", + "type": "uint256" + } + ], + "internalType": "struct DoHardWorkParameterBag", + "name": "dhwParams", + "type": "tuple" + } + ], + "name": "doHardWork", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWithdrawalWallet", + "outputs": [ + { + "internalType": "address", + "name": "emergencyWithdrawalWallet", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint16a16", + "name": "dhwIndexes", + "type": "uint256" + } + ], + "name": "getDhwYield", + "outputs": [ + { + "internalType": "int256[]", + "name": "yields", + "type": "int256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "platformFees", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "ecosystemFeeReceiver", + "type": "address" + }, + { + "internalType": "uint96", + "name": "ecosystemFeePct", + "type": "uint96" + }, + { + "internalType": "address", + "name": "treasuryFeeReceiver", + "type": "address" + }, + { + "internalType": "uint96", + "name": "treasuryFeePct", + "type": "uint96" + } + ], + "internalType": "struct PlatformFees", + "name": "fees", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "strategyShares", + "type": "uint256[]" + }, + { + "internalType": "address[]", + "name": "assetGroup", + "type": "address[]" + }, + { + "internalType": "uint256[][]", + "name": "withdrawalSlippages", + "type": "uint256[][]" + } + ], + "internalType": "struct RedeemFastParameterBag", + "name": "redeemFastParams", + "type": "tuple" + } + ], + "name": "redeemFast", + "outputs": [ + { + "internalType": "uint256[]", + "name": "withdrawnAssets", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "shares", + "type": "uint256[]" + }, + { + "internalType": "uint256[][]", + "name": "withdrawalSlippages", + "type": "uint256[][]" + } + ], + "name": "redeemStrategyShares", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "internalType": "int256", + "name": "apy", + "type": "int256" + } + ], + "name": "registerStrategy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "strategy", + "type": "address" + } + ], + "name": "removeStrategy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "ecosystemFeePct", + "type": "uint96" + } + ], + "name": "setEcosystemFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "ecosystemFeeReceiver", + "type": "address" + } + ], + "name": "setEcosystemFeeReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "treasuryFeePct", + "type": "uint96" + } + ], + "name": "setTreasuryFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "treasuryFeeReceiver", + "type": "address" + } + ], + "name": "setTreasuryFeeReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "dhwIndex", + "type": "uint256" + } + ], + "name": "sharesRedeemed", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + } + ], + "name": "strategyAPYs", + "outputs": [ + { + "internalType": "int256[]", + "name": "apys", + "type": "int256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "strategies", + "type": "address[]" + }, + { + "internalType": "uint16a16", + "name": "dhwIndexes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetGroupLength", + "type": "uint256" + } + ], + "name": "strategyAtIndexBatch", + "outputs": [ + { + "components": [ + { + "internalType": "uint256[]", + "name": "exchangeRates", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "assetsDeposited", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "sharesMinted", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSSTs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStrategyValue", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "dhwYields", + "type": "int256" + } + ], + "internalType": "struct StrategyAtIndex[]", + "name": "states", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/spool-v2/contracts/index.ts b/src/apps/spool-v2/contracts/index.ts new file mode 100644 index 000000000..5dcfebdf6 --- /dev/null +++ b/src/apps/spool-v2/contracts/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export * from './viem.contract-factory'; diff --git a/src/apps/spool-v2/contracts/viem.contract-factory.ts b/src/apps/spool-v2/contracts/viem.contract-factory.ts new file mode 100644 index 000000000..541aef539 --- /dev/null +++ b/src/apps/spool-v2/contracts/viem.contract-factory.ts @@ -0,0 +1,35 @@ +import { Injectable, Inject } from '@nestjs/common'; + +import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; +import { Network } from '~types/network.interface'; + +import { + SpoolLens__factory, + SpoolStaking__factory, + SpoolVault__factory, + SpoolVospool__factory, + StrategyRegistry__factory, +} from './viem'; + +type ContractOpts = { address: string; network: Network }; + +@Injectable() +export class SpoolV2ViemContractFactory { + constructor(@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit) {} + + spoolLens({ address, network }: ContractOpts) { + return SpoolLens__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } + spoolStaking({ address, network }: ContractOpts) { + return SpoolStaking__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } + spoolVault({ address, network }: ContractOpts) { + return SpoolVault__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } + spoolVospool({ address, network }: ContractOpts) { + return SpoolVospool__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } + strategyRegistry({ address, network }: ContractOpts) { + return StrategyRegistry__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } +} diff --git a/src/apps/spool-v2/contracts/viem/SpoolLens.ts b/src/apps/spool-v2/contracts/viem/SpoolLens.ts new file mode 100644 index 000000000..05279d63c --- /dev/null +++ b/src/apps/spool-v2/contracts/viem/SpoolLens.ts @@ -0,0 +1,146 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const spoolLensAbi = [ + { + inputs: [ + { + internalType: 'address', + name: 'smartVault', + type: 'address', + }, + ], + name: 'getSVTTotalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'address', + name: 'riskProvider', + type: 'address', + }, + { + internalType: 'address', + name: 'allocationProvider', + type: 'address', + }, + ], + name: 'getSmartVaultAllocations', + outputs: [ + { + internalType: 'uint256[][]', + name: 'allocations', + type: 'uint256[][]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'smartVault', + type: 'address', + }, + { + internalType: 'bool', + name: 'doFlush', + type: 'bool', + }, + ], + name: 'getSmartVaultAssetBalances', + outputs: [ + { + internalType: 'uint256[]', + name: 'balances', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'smartVault', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'uint256[]', + name: 'nftIds', + type: 'uint256[]', + }, + ], + name: 'getUserSVTBalance', + outputs: [ + { + internalType: 'uint256', + name: 'currentBalance', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'smartVault', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'uint256[]', + name: 'nftIds', + type: 'uint256[]', + }, + ], + name: 'getUserSVTsfromNFTs', + outputs: [ + { + internalType: 'uint256[]', + name: 'nftSvts', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type SpoolLens = typeof spoolLensAbi; +export type SpoolLensContract = GetContractReturnType; + +export class SpoolLens__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: spoolLensAbi, publicClient: client }); + } +} diff --git a/src/apps/spool-v2/contracts/viem/SpoolStaking.ts b/src/apps/spool-v2/contracts/viem/SpoolStaking.ts new file mode 100644 index 000000000..28c85b863 --- /dev/null +++ b/src/apps/spool-v2/contracts/viem/SpoolStaking.ts @@ -0,0 +1,824 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const spoolStakingAbi = [ + { + inputs: [ + { + internalType: 'contract IERC20', + name: '_stakingToken', + type: 'address', + }, + { + internalType: 'contract IVoSPOOL', + name: '_voSpool', + type: 'address', + }, + { + internalType: 'contract IVoSpoolRewards', + name: '_voSpoolRewards', + type: 'address', + }, + { + internalType: 'contract IRewardDistributor', + name: '_rewardDistributor', + type: 'address', + }, + { + internalType: 'contract ISpoolOwner', + name: '_spoolOwner', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'canStakeFor', + type: 'bool', + }, + ], + name: 'CanStakeForSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint32', + name: 'periodFinish', + type: 'uint32', + }, + ], + name: 'PeriodFinishUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + ], + name: 'RewardAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'RewardCompounded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'RewardPaid', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'RewardRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'leftover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint32', + name: 'periodFinish', + type: 'uint32', + }, + ], + name: 'RewardUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Staked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'stakedFor', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'stakedBy', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'StakedFor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Unstaked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'VoRewardCompounded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'VoSpoolRewardPaid', + type: 'event', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'uint32', + name: 'rewardsDuration', + type: 'uint32', + }, + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'addToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'allowFor', + type: 'address', + }, + ], + name: 'allowUnstakeFor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'balances', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'canStakeFor', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'doCompoundVoSpoolRewards', + type: 'bool', + }, + ], + name: 'compound', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'earned', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'doClaimVoSpoolRewards', + type: 'bool', + }, + ], + name: 'getActiveRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20[]', + name: 'tokens', + type: 'address[]', + }, + { + internalType: 'bool', + name: 'doClaimVoSpoolRewards', + type: 'bool', + }, + ], + name: 'getRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getUpdatedVoSpoolRewardAmount', + outputs: [ + { + internalType: 'uint256', + name: 'rewards', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'lastTimeRewardApplicable', + outputs: [ + { + internalType: 'uint32', + name: '', + type: 'uint32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'uint32', + name: '_rewardsDuration', + type: 'uint32', + }, + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'notifyRewardAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'tokenAddress', + type: 'address', + }, + { + internalType: 'uint256', + name: 'tokenAmount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'recoverTo', + type: 'address', + }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'removeReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + name: 'rewardConfiguration', + outputs: [ + { + internalType: 'uint32', + name: 'rewardsDuration', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'periodFinish', + type: 'uint32', + }, + { + internalType: 'uint192', + name: 'rewardRate', + type: 'uint192', + }, + { + internalType: 'uint32', + name: 'lastUpdateTime', + type: 'uint32', + }, + { + internalType: 'uint224', + name: 'rewardPerTokenStored', + type: 'uint224', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardDistributor', + outputs: [ + { + internalType: 'contract IRewardDistributor', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'rewardPerToken', + outputs: [ + { + internalType: 'uint224', + name: '', + type: 'uint224', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'rewardTokens', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardTokensCount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'bool', + name: '_canStakeFor', + type: 'bool', + }, + ], + name: 'setCanStakeFor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'stakeFor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'stakedBy', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stakingToken', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + name: 'tokenBlacklist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalStaked', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'unstake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'uint32', + name: 'timestamp', + type: 'uint32', + }, + ], + name: 'updatePeriodFinish', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'voSpool', + outputs: [ + { + internalType: 'contract IVoSPOOL', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'voSpoolRewards', + outputs: [ + { + internalType: 'contract IVoSpoolRewards', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type SpoolStaking = typeof spoolStakingAbi; +export type SpoolStakingContract = GetContractReturnType; + +export class SpoolStaking__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: spoolStakingAbi, publicClient: client }); + } +} diff --git a/src/apps/spool-v2/contracts/viem/SpoolVault.ts b/src/apps/spool-v2/contracts/viem/SpoolVault.ts new file mode 100644 index 000000000..7c8fce631 --- /dev/null +++ b/src/apps/spool-v2/contracts/viem/SpoolVault.ts @@ -0,0 +1,829 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const spoolVaultAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'approved', + type: 'bool', + }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'baseUri', + type: 'string', + }, + ], + name: 'BaseURIChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'ids', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'values', + type: 'uint256[]', + }, + ], + name: 'TransferBatch', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'TransferSingle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'value', + type: 'string', + }, + { + indexed: true, + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + ], + name: 'URI', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'assetGroupId', + outputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'accounts', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'ids', + type: 'uint256[]', + }, + ], + name: 'balanceOfBatch', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + ], + name: 'balanceOfFractional', + outputs: [ + { + internalType: 'uint256', + name: 'fractionalBalance', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256[]', + name: 'ids', + type: 'uint256[]', + }, + ], + name: 'balanceOfFractionalBatch', + outputs: [ + { + internalType: 'uint256[]', + name: 'fractionalBalances', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'uint256[]', + name: 'nftIds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'nftAmounts', + type: 'uint256[]', + }, + ], + name: 'burnNFTs', + outputs: [ + { + internalType: 'bytes[]', + name: 'metadata', + type: 'bytes[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'uint256', + name: 'vaultShares', + type: 'uint256', + }, + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'shares', + type: 'uint256[]', + }, + ], + name: 'burnVaultShares', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'claimer', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'claimShares', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256[]', + name: 'nftIds', + type: 'uint256[]', + }, + ], + name: 'getMetadata', + outputs: [ + { + internalType: 'bytes[]', + name: 'metadata', + type: 'bytes[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'operator', + type: 'address', + }, + ], + name: 'isApprovedForAll', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256[]', + name: 'assets', + type: 'uint256[]', + }, + { + internalType: 'uint256', + name: 'initiated', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'flushIndex', + type: 'uint256', + }, + ], + internalType: 'struct DepositMetadata', + name: 'metadata', + type: 'tuple', + }, + ], + name: 'mintDepositNFT', + outputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'uint256', + name: 'vaultShares', + type: 'uint256', + }, + ], + name: 'mintVaultShares', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'vaultShares', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'flushIndex', + type: 'uint256', + }, + ], + internalType: 'struct WithdrawalMetadata', + name: 'metadata', + type: 'tuple', + }, + ], + name: 'mintWithdrawalNFT', + outputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256[]', + name: 'ids', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'amounts', + type: 'uint256[]', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'safeBatchTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'operator', + type: 'address', + }, + { + internalType: 'bool', + name: 'approved', + type: 'bool', + }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'string', + name: 'uri_', + type: 'string', + }, + ], + name: 'setBaseURI', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes4', + name: 'interfaceId', + type: 'bytes4', + }, + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFromSpender', + outputs: [ + { + internalType: 'bool', + name: 'success', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + ], + name: 'uri', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vaultName', + outputs: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type SpoolVault = typeof spoolVaultAbi; +export type SpoolVaultContract = GetContractReturnType; + +export class SpoolVault__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: spoolVaultAbi, publicClient: client }); + } +} diff --git a/src/apps/spool-v2/contracts/viem/SpoolVospool.ts b/src/apps/spool-v2/contracts/viem/SpoolVospool.ts new file mode 100644 index 000000000..2f07b5b1c --- /dev/null +++ b/src/apps/spool-v2/contracts/viem/SpoolVospool.ts @@ -0,0 +1,1187 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const spoolVospoolAbi = [ + { + inputs: [ + { + internalType: 'contract ISpoolOwner', + name: '_spoolOwner', + type: 'address', + }, + { + internalType: 'uint256', + name: '_firstTrancheEndTime', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'source', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Burned', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint16', + name: 'lastUpdatedTrancheIndex', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint48', + name: 'totalMaturedVotingPower', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint48', + name: 'totalMaturingAmount', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint56', + name: 'totalRawUnmaturedVotingPower', + type: 'uint56', + }, + ], + name: 'GlobalGradualUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'source', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bool', + name: 'burnAll', + type: 'bool', + }, + ], + name: 'GradualBurned', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'GradualMinted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'set', + type: 'bool', + }, + ], + name: 'GradualMinterSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Minted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'set', + type: 'bool', + }, + ], + name: 'MinterSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint16', + name: 'lastUpdatedTrancheIndex', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint48', + name: 'maturedVotingPower', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint48', + name: 'maturingAmount', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint56', + name: 'rawUnmaturedVotingPower', + type: 'uint56', + }, + ], + name: 'UserGradualUpdated', + type: 'event', + }, + { + inputs: [], + name: 'FULL_POWER_TIME', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'FULL_POWER_TRANCHES_COUNT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'TRANCHE_TIME', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'burnAll', + type: 'bool', + }, + ], + name: 'burnGradual', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'firstTrancheStartTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentTrancheIndex', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getGlobalGradual', + outputs: [ + { + components: [ + { + internalType: 'uint48', + name: 'totalMaturedVotingPower', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'totalMaturingAmount', + type: 'uint48', + }, + { + internalType: 'uint56', + name: 'totalRawUnmaturedVotingPower', + type: 'uint56', + }, + { + internalType: 'uint16', + name: 'lastUpdatedTrancheIndex', + type: 'uint16', + }, + ], + internalType: 'struct GlobalGradual', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getLastFinishedTrancheIndex', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getNextTrancheEndTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getNotUpdatedGlobalGradual', + outputs: [ + { + components: [ + { + internalType: 'uint48', + name: 'totalMaturedVotingPower', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'totalMaturingAmount', + type: 'uint48', + }, + { + internalType: 'uint56', + name: 'totalRawUnmaturedVotingPower', + type: 'uint56', + }, + { + internalType: 'uint16', + name: 'lastUpdatedTrancheIndex', + type: 'uint16', + }, + ], + internalType: 'struct GlobalGradual', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getNotUpdatedUserGradual', + outputs: [ + { + components: [ + { + internalType: 'uint48', + name: 'maturedVotingPower', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'maturingAmount', + type: 'uint48', + }, + { + internalType: 'uint56', + name: 'rawUnmaturedVotingPower', + type: 'uint56', + }, + { + components: [ + { + internalType: 'uint16', + name: 'arrayIndex', + type: 'uint16', + }, + { + internalType: 'uint8', + name: 'position', + type: 'uint8', + }, + ], + internalType: 'struct UserTranchePosition', + name: 'oldestTranchePosition', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint16', + name: 'arrayIndex', + type: 'uint16', + }, + { + internalType: 'uint8', + name: 'position', + type: 'uint8', + }, + ], + internalType: 'struct UserTranchePosition', + name: 'latestTranchePosition', + type: 'tuple', + }, + { + internalType: 'uint16', + name: 'lastUpdatedTrancheIndex', + type: 'uint16', + }, + ], + internalType: 'struct UserGradual', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTotalGradualVotingPower', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'trancheIndex', + type: 'uint256', + }, + ], + name: 'getTrancheEndTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'time', + type: 'uint256', + }, + ], + name: 'getTrancheIndex', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserGradual', + outputs: [ + { + components: [ + { + internalType: 'uint48', + name: 'maturedVotingPower', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'maturingAmount', + type: 'uint48', + }, + { + internalType: 'uint56', + name: 'rawUnmaturedVotingPower', + type: 'uint56', + }, + { + components: [ + { + internalType: 'uint16', + name: 'arrayIndex', + type: 'uint16', + }, + { + internalType: 'uint8', + name: 'position', + type: 'uint8', + }, + ], + internalType: 'struct UserTranchePosition', + name: 'oldestTranchePosition', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint16', + name: 'arrayIndex', + type: 'uint16', + }, + { + internalType: 'uint8', + name: 'position', + type: 'uint8', + }, + ], + internalType: 'struct UserTranchePosition', + name: 'latestTranchePosition', + type: 'tuple', + }, + { + internalType: 'uint16', + name: 'lastUpdatedTrancheIndex', + type: 'uint16', + }, + ], + internalType: 'struct UserGradual', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserGradualVotingPower', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'gradualMinters', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'indexedGlobalTranches', + outputs: [ + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + ], + internalType: 'struct Tranche', + name: 'zero', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + ], + internalType: 'struct Tranche', + name: 'one', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + ], + internalType: 'struct Tranche', + name: 'two', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + ], + internalType: 'struct Tranche', + name: 'three', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + ], + internalType: 'struct Tranche', + name: 'four', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'mintGradual', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'minters', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_gradualMinter', + type: 'address', + }, + { + internalType: 'bool', + name: '_set', + type: 'bool', + }, + ], + name: 'setGradualMinter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_minter', + type: 'address', + }, + { + internalType: 'bool', + name: '_set', + type: 'bool', + }, + ], + name: 'setMinter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalInstantPower', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'updateUserVotingPower', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'updateVotingPower', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'userInstantPower', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'userTranches', + outputs: [ + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + { + internalType: 'uint16', + name: 'index', + type: 'uint16', + }, + ], + internalType: 'struct UserTranche', + name: 'zero', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + { + internalType: 'uint16', + name: 'index', + type: 'uint16', + }, + ], + internalType: 'struct UserTranche', + name: 'one', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + { + internalType: 'uint16', + name: 'index', + type: 'uint16', + }, + ], + internalType: 'struct UserTranche', + name: 'two', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint48', + name: 'amount', + type: 'uint48', + }, + { + internalType: 'uint16', + name: 'index', + type: 'uint16', + }, + ], + internalType: 'struct UserTranche', + name: 'three', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type SpoolVospool = typeof spoolVospoolAbi; +export type SpoolVospoolContract = GetContractReturnType; + +export class SpoolVospool__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: spoolVospoolAbi, publicClient: client }); + } +} diff --git a/src/apps/spool-v2/contracts/viem/StrategyRegistry.ts b/src/apps/spool-v2/contracts/viem/StrategyRegistry.ts new file mode 100644 index 000000000..1d932441b --- /dev/null +++ b/src/apps/spool-v2/contracts/viem/StrategyRegistry.ts @@ -0,0 +1,815 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const strategyRegistryAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'ecosystemFeeReceiver', + type: 'address', + }, + ], + name: 'EcosystemFeeReceiverSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'feePct', + type: 'uint256', + }, + ], + name: 'EcosystemFeeSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'wallet', + type: 'address', + }, + ], + name: 'EmergencyWithdrawalWalletSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'strategy', + type: 'address', + }, + { + indexed: false, + internalType: 'int256', + name: 'apy', + type: 'int256', + }, + ], + name: 'StrategyApyUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'strategy', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'dhwIndex', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sharesMinted', + type: 'uint256', + }, + { + internalType: 'uint256[]', + name: 'assetsWithdrawn', + type: 'uint256[]', + }, + { + internalType: 'int256', + name: 'yieldPercentage', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'valueAtDhw', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSstsAtDhw', + type: 'uint256', + }, + ], + indexed: false, + internalType: 'struct DhwInfo', + name: 'dhwInfo', + type: 'tuple', + }, + ], + name: 'StrategyDhw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'strategy', + type: 'address', + }, + ], + name: 'StrategyRegistered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'strategy', + type: 'address', + }, + ], + name: 'StrategyRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'strategy', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'assetsWithdrawn', + type: 'uint256[]', + }, + ], + name: 'StrategySharesFastRedeemed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'strategy', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'assetsWithdrawn', + type: 'uint256[]', + }, + ], + name: 'StrategySharesRedeemed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'treasuryFeeReceiver', + type: 'address', + }, + ], + name: 'TreasuryFeeReceiverSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'feePct', + type: 'uint256', + }, + ], + name: 'TreasuryFeeSet', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint256[][]', + name: 'amounts', + type: 'uint256[][]', + }, + ], + name: 'addDeposits', + outputs: [ + { + internalType: 'uint16a16', + name: 'strategyIndexes', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'strategyShares', + type: 'uint256[]', + }, + ], + name: 'addWithdrawals', + outputs: [ + { + internalType: 'uint16a16', + name: 'strategyIndexes', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'strategy', + type: 'address', + }, + ], + name: 'assetRatioAtLastDhw', + outputs: [ + { + internalType: 'uint256[]', + name: 'assetRatio', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint16a16', + name: 'dhwIndexes', + type: 'uint256', + }, + { + internalType: 'uint256[]', + name: 'strategyShares', + type: 'uint256[]', + }, + ], + name: 'claimWithdrawals', + outputs: [ + { + internalType: 'uint256[]', + name: 'assetsWithdrawn', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + ], + name: 'currentIndex', + outputs: [ + { + internalType: 'uint256[]', + name: 'dhwIndexes', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'strategy', + type: 'address', + }, + { + internalType: 'uint256', + name: 'dhwIndex', + type: 'uint256', + }, + ], + name: 'depositedAssets', + outputs: [ + { + internalType: 'uint256[]', + name: 'assets', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint16a16', + name: 'dhwIndexes', + type: 'uint256', + }, + ], + name: 'dhwTimestamps', + outputs: [ + { + internalType: 'uint256[]', + name: 'timestamps', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address[][]', + name: 'strategies', + type: 'address[][]', + }, + { + components: [ + { + internalType: 'address', + name: 'swapTarget', + type: 'address', + }, + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'bytes', + name: 'swapCallData', + type: 'bytes', + }, + ], + internalType: 'struct SwapInfo[][][]', + name: 'swapInfo', + type: 'tuple[][][]', + }, + { + components: [ + { + internalType: 'address', + name: 'swapTarget', + type: 'address', + }, + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'bytes', + name: 'swapCallData', + type: 'bytes', + }, + ], + internalType: 'struct SwapInfo[][][]', + name: 'compoundSwapInfo', + type: 'tuple[][][]', + }, + { + internalType: 'uint256[][][]', + name: 'strategySlippages', + type: 'uint256[][][]', + }, + { + internalType: 'int256[][]', + name: 'baseYields', + type: 'int256[][]', + }, + { + internalType: 'address[]', + name: 'tokens', + type: 'address[]', + }, + { + internalType: 'uint256[2][]', + name: 'exchangeRateSlippages', + type: 'uint256[2][]', + }, + { + internalType: 'uint256', + name: 'validUntil', + type: 'uint256', + }, + ], + internalType: 'struct DoHardWorkParameterBag', + name: 'dhwParams', + type: 'tuple', + }, + ], + name: 'doHardWork', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyWithdrawalWallet', + outputs: [ + { + internalType: 'address', + name: 'emergencyWithdrawalWallet', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint16a16', + name: 'dhwIndexes', + type: 'uint256', + }, + ], + name: 'getDhwYield', + outputs: [ + { + internalType: 'int256[]', + name: 'yields', + type: 'int256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'platformFees', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'ecosystemFeeReceiver', + type: 'address', + }, + { + internalType: 'uint96', + name: 'ecosystemFeePct', + type: 'uint96', + }, + { + internalType: 'address', + name: 'treasuryFeeReceiver', + type: 'address', + }, + { + internalType: 'uint96', + name: 'treasuryFeePct', + type: 'uint96', + }, + ], + internalType: 'struct PlatformFees', + name: 'fees', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'strategyShares', + type: 'uint256[]', + }, + { + internalType: 'address[]', + name: 'assetGroup', + type: 'address[]', + }, + { + internalType: 'uint256[][]', + name: 'withdrawalSlippages', + type: 'uint256[][]', + }, + ], + internalType: 'struct RedeemFastParameterBag', + name: 'redeemFastParams', + type: 'tuple', + }, + ], + name: 'redeemFast', + outputs: [ + { + internalType: 'uint256[]', + name: 'withdrawnAssets', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'shares', + type: 'uint256[]', + }, + { + internalType: 'uint256[][]', + name: 'withdrawalSlippages', + type: 'uint256[][]', + }, + ], + name: 'redeemStrategyShares', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'strategy', + type: 'address', + }, + { + internalType: 'int256', + name: 'apy', + type: 'int256', + }, + ], + name: 'registerStrategy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'strategy', + type: 'address', + }, + ], + name: 'removeStrategy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint96', + name: 'ecosystemFeePct', + type: 'uint96', + }, + ], + name: 'setEcosystemFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'ecosystemFeeReceiver', + type: 'address', + }, + ], + name: 'setEcosystemFeeReceiver', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint96', + name: 'treasuryFeePct', + type: 'uint96', + }, + ], + name: 'setTreasuryFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'treasuryFeeReceiver', + type: 'address', + }, + ], + name: 'setTreasuryFeeReceiver', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'strategy', + type: 'address', + }, + { + internalType: 'uint256', + name: 'dhwIndex', + type: 'uint256', + }, + ], + name: 'sharesRedeemed', + outputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + ], + name: 'strategyAPYs', + outputs: [ + { + internalType: 'int256[]', + name: 'apys', + type: 'int256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'strategies', + type: 'address[]', + }, + { + internalType: 'uint16a16', + name: 'dhwIndexes', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'assetGroupLength', + type: 'uint256', + }, + ], + name: 'strategyAtIndexBatch', + outputs: [ + { + components: [ + { + internalType: 'uint256[]', + name: 'exchangeRates', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'assetsDeposited', + type: 'uint256[]', + }, + { + internalType: 'uint256', + name: 'sharesMinted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSSTs', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalStrategyValue', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'dhwYields', + type: 'int256', + }, + ], + internalType: 'struct StrategyAtIndex[]', + name: 'states', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type StrategyRegistry = typeof strategyRegistryAbi; +export type StrategyRegistryContract = GetContractReturnType; + +export class StrategyRegistry__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: strategyRegistryAbi, publicClient: client }); + } +} diff --git a/src/apps/spool-v2/contracts/viem/index.ts b/src/apps/spool-v2/contracts/viem/index.ts new file mode 100644 index 000000000..404621243 --- /dev/null +++ b/src/apps/spool-v2/contracts/viem/index.ts @@ -0,0 +1,15 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +export type { SpoolLens } from './SpoolLens'; +export type { SpoolStaking } from './SpoolStaking'; +export type { SpoolVault } from './SpoolVault'; +export type { SpoolVospool } from './SpoolVospool'; +export type { StrategyRegistry } from './StrategyRegistry'; + +export { SpoolLens__factory } from './SpoolLens'; +export { SpoolStaking__factory } from './SpoolStaking'; +export { SpoolVault__factory } from './SpoolVault'; +export { SpoolVospool__factory } from './SpoolVospool'; +export { StrategyRegistry__factory } from './StrategyRegistry'; diff --git a/src/apps/spool-v2/ethereum/spool-v2.constants.ts b/src/apps/spool-v2/ethereum/spool-v2.constants.ts new file mode 100644 index 000000000..5340b59ac --- /dev/null +++ b/src/apps/spool-v2/ethereum/spool-v2.constants.ts @@ -0,0 +1,208 @@ +import { gql } from 'graphql-request'; + +export const SPOOL_ADDRESS = '0x40803cea2b2a32bda1be61d3604af6a814e70976'; +export const VOSPOOL_ADDRESS = '0xaf56d16a7fe479f2fcd48ff567ff589cb2d2a0e9'; +export const STAKING_ADDRESS = '0xc3160c5cc63b6116dd182faa8393d3ad9313e213'; +export const SUBGRAPH_API_BASE_URL = 'https://api.studio.thegraph.com/query/41372/spool-v2_mainnet/version/latest'; +export const SUBGRAPH_V1_API_BASE_URL = 'https://api.thegraph.com/subgraphs/name/spoolfi/spool?source=zapper'; +export const SPOOL_LENS_ADDRESS = '0x8aa6174333f75421903b2b5c70ddf8da5d84f74f'; +export const STRATEGY_REGISTRY_ADDRESS = '0x554c6bcb54656390aca0a0af38ca954dbe653f15'; +export const APY_DECIMALS = '18'; + +export const SPOOL_STAKED_QUERY = gql` + query getStaking($address: String!) { + userSpoolStaking(id: $address) { + id + spoolStaked + } + } +`; + +export const REWARDS_QUERY = gql` + query { + smartVaultRewardTokens { + id + token { + id + name + symbol + decimals + } + isRemoved + endTime + startTime + } + } +`; + +export const VAULTS_AND_STRATEGIES_QUERY = gql` + { + smartVaults { + id + smartVaultStrategies { + id + isRemoved + strategy { + id + } + } + } + } +`; + +export const ASSET_GROUPS_QUERY = gql` + { + smartVaults { + assetGroup { + id + assetGroupTokens { + token { + id + decimals + } + } + } + } + } +`; + +export const STRATEGY_ALLOCATION_QUERY = gql` + { + smartVaults { + id + smartVaultStrategies { + id + allocation + isRemoved + strategy { + id + } + } + } + } +`; + +export const GLOBAL_FEES_QUERY = gql` + { + globals { + treasuryFee + ecosystemFee + } + } +`; + +export const FEES_QUERY = gql` + { + smartVaults { + id + smartVaultFees { + performanceFeePercentage + depositFeePercentage + managementFeePercentage + } + } + } +`; + +export const DEPOSITS_QUERY = gql` + { + smartVaults { + smartVaultFlushes { + SmartVaultWithdrawalNFTs { + svtWithdrawn + } + id + isExecuted + strategyDHWs { + isExecuted + id + } + } + } + } +`; + +export const REWARDS_APY_QUERY = gql` + query ($now: String!) { + smartVaults { + smartVaultRewardTokens(where: { endTime_gt: $now }) { + id + rewardRate + token { + decimals + id + } + } + id + } + } +`; + +export const USER_NFTS_QUERY = gql` + query ($address: String!, $smartVault: String!) { + user(id: $address) { + id + smartVaultDepositNFTs(where: { smartVault: $smartVault }) { + smartVault { + id + } + nftId + } + } + } +`; + +export const VAULTS_QUERY = gql` + query { + smartVaults { + id + assetGroup { + assetGroupTokens { + token { + id + } + } + } + id + name + riskTolerance + riskProvider { + id + } + smartVaultFees { + id + depositFeePercentage + managementFeePercentage + performanceFeePercentage + } + smartVaultStrategies { + id + isRemoved + allocation + strategy { + id + riskScores { + riskScore + riskProvider { + id + } + } + } + } + smartVaultRewardTokens { + id + token { + id + name + symbol + decimals + } + rewardRate + startTime + endTime + totalAmount + isRemoved + } + } + } +`; diff --git a/src/apps/spool-v2/ethereum/spool-v2.staking.contract-position-fetcher.ts b/src/apps/spool-v2/ethereum/spool-v2.staking.contract-position-fetcher.ts new file mode 100644 index 000000000..4d454a84b --- /dev/null +++ b/src/apps/spool-v2/ethereum/spool-v2.staking.contract-position-fetcher.ts @@ -0,0 +1,154 @@ +import { Inject } from '@nestjs/common'; +import { BigNumber } from 'ethers'; +import { parseEther } from 'ethers/lib/utils'; +import _ from 'lodash'; + +import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; +import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; +import { buildDollarDisplayItem, buildNumberDisplayItem } from '~app-toolkit/helpers/presentation/display-item.present'; +import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; +import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; +import { MetaType } from '~position/position.interface'; +import { isClaimable, isSupplied } from '~position/position.utils'; +import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher'; +import { + GetDataPropsParams, + GetDisplayPropsParams, + GetTokenBalancesParams, +} from '~position/template/contract-position.template.types'; + +import { SpoolV2ViemContractFactory } from '../contracts'; +import { SpoolStaking } from '../contracts/viem'; + +import { + REWARDS_QUERY, + SPOOL_ADDRESS, + SPOOL_STAKED_QUERY, + STAKING_ADDRESS, + SUBGRAPH_API_BASE_URL, + SUBGRAPH_V1_API_BASE_URL, + VOSPOOL_ADDRESS, +} from './spool-v2.constants'; +import { StakingReward, UserSpoolStaking } from './spool-v2.types'; + +type SpoolStakingDataProps = { + tvl: number; + spoolStaked: number; + totalAccVoSpool: number; +}; + +@PositionTemplate() +export class EthereumSpoolV2StakingContractPositionFetcher extends ContractPositionTemplatePositionFetcher< + SpoolStaking, + SpoolStakingDataProps +> { + groupLabel = 'Staking'; + + constructor( + @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, + @Inject(SpoolV2ViemContractFactory) protected readonly contractFactory: SpoolV2ViemContractFactory, + ) { + super(appToolkit); + } + + getContract(address: string) { + return this.contractFactory.spoolStaking({ address, network: this.network }); + } + + async getDefinitions() { + return [{ address: STAKING_ADDRESS }]; + } + + async getTokenDefinitions() { + const now = parseInt(String(new Date().getTime() / 1000)); + const stakingRewards = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: REWARDS_QUERY, + }); + + let rewardAddresses: string[] = []; + // SpoolStaking can emit arbitrary tokens; VoSpoolRewards always emits SPOOL + if (stakingRewards.stakingRewardTokens) { + rewardAddresses = _.uniq( + stakingRewards.stakingRewardTokens + .filter(reward => !reward.isRemoved && parseInt(reward.startTime) >= now && parseInt(reward.endTime) <= now) + .map(reward => reward.token.id) + .concat([SPOOL_ADDRESS]), + ); + } + + return [ + { metaType: MetaType.SUPPLIED, address: SPOOL_ADDRESS, network: this.network }, + { metaType: MetaType.VESTING, address: VOSPOOL_ADDRESS, network: this.network }, + ...rewardAddresses.map(address => ({ metaType: MetaType.CLAIMABLE, address, network: this.network })), + ]; + } + + async getDataProps({ multicall, contractPosition }: GetDataPropsParams) { + const [spoolToken, voSpoolToken] = contractPosition.tokens; + const spoolContract = this.appToolkit.globalViemContracts.erc20(spoolToken); + const voSpoolContract = this.contractFactory.spoolVospool(voSpoolToken); + + const totalStakedRaw = await multicall.wrap(spoolContract).read.balanceOf([STAKING_ADDRESS]); + const votingPowerRaw = await multicall.wrap(voSpoolContract).read.getTotalGradualVotingPower(); + + const totalAccVoSpool = Number(votingPowerRaw) / 10 ** voSpoolToken.decimals; + const spoolStaked = Number(totalStakedRaw) / 10 ** spoolToken.decimals; + const tvl = spoolStaked * spoolToken.price; + + return { tvl, spoolStaked, totalAccVoSpool }; + } + + async getLabel({ contractPosition }: GetDisplayPropsParams) { + return `${getLabelFromToken(contractPosition.tokens[0])} Staking`; + } + + async getStatsItems({ contractPosition }: GetDisplayPropsParams) { + return [ + { label: 'TVL', value: buildDollarDisplayItem(contractPosition.dataProps.tvl) }, + { label: 'SPOOL Staked', value: buildNumberDisplayItem(contractPosition.dataProps.spoolStaked) }, + { label: 'voSPOOL Accumulated', value: buildNumberDisplayItem(contractPosition.dataProps.totalAccVoSpool) }, + ]; + } + + async getTokenBalancesPerPosition({ + address, + contractPosition, + multicall, + }: GetTokenBalancesParams) { + const suppliedToken = contractPosition.tokens.find(isSupplied)!; + const rewardTokens = contractPosition.tokens.filter(isClaimable); + + const staking = this.contractFactory.spoolStaking({ address: STAKING_ADDRESS, network: this.network }); + const voSpool = this.contractFactory.spoolVospool({ address: VOSPOOL_ADDRESS, network: this.network }); + + const [votingPowerRaw, voSpoolRewards, ...tokenRewards] = await Promise.all([ + multicall.wrap(voSpool).read.getUserGradualVotingPower([address]), + multicall + .wrap(staking) + .simulate.getUpdatedVoSpoolRewardAmount({ account: address }) + .then(v => v.result), + ...rewardTokens.map(reward => multicall.wrap(staking).read.earned([reward.address, address])), + ]); + + const stakedSpool = await gqlFetch({ + endpoint: SUBGRAPH_V1_API_BASE_URL, + query: SPOOL_STAKED_QUERY, + variables: { address }, + }); + + const stakedAmount = parseEther(stakedSpool?.userSpoolStaking?.spoolStaked || '0').toString(); + + const rewardBalances = rewardTokens.map((token, idx) => { + // Add voSPOOL rewards (always in SPOOL) + const rewards = + token.address.toLowerCase() == suppliedToken.address.toLowerCase() + ? BigNumber.from(tokenRewards[idx]).add(voSpoolRewards) + : BigNumber.from(tokenRewards[idx]); + + return rewards.toString(); + }); + + return [stakedAmount, votingPowerRaw.toString(), ...rewardBalances]; + } +} diff --git a/src/apps/spool-v2/ethereum/spool-v2.types.ts b/src/apps/spool-v2/ethereum/spool-v2.types.ts new file mode 100644 index 000000000..b5585365c --- /dev/null +++ b/src/apps/spool-v2/ethereum/spool-v2.types.ts @@ -0,0 +1,291 @@ +import { BigNumber } from 'ethers'; + +export type SpoolVaults = { + smartVaults: VaultDetails[]; +}; + +export type VaultDetails = { + id: string; + name: string; + riskTolerance: string; + riskProvider: { + id: string; + }; + assetGroup: { + assetGroupTokens: { + token: { + id: string; + }; + }[]; + }; + smartVaultFees: { + depositFeePercentage: string; + managementFeePercentage: string; + performanceFeePercentage: string; + }; + smartVaultStrategies: { + id: string; + allocation: string; + isRemoved: boolean; + strategy: { + id: string; + riskScores: { + riskScore: string; + riskProvider: { + id: string; + }; + }[]; + }; + }[]; + smartVaultRewardTokens: { + id: string; + token: { + id: string; + name: string; + symbol: string; + decimals: number; + }; + rewardRate: number; + totalAmount: string; + isRemoved: number; + }[]; +}; + +export type Globals = { + globals: { + treasuryFee: string; + ecosystemFee: string; + }; +}; + +export type VaultsAnalytics = { + smartVaults: { + id: string; + tvr: string; + tvrUsd: string; + baseApy: string; + rewardsApy: string[]; + adjustedApy: string; + vaultAssets: BigNumber[]; + }[]; +}; + +export type StakingReward = { + stakingRewardTokens: { + id: string; + token: { + id: string; + name: string; + symbol: string; + decimals: number; + }; + isRemoved: boolean; + endTime: string; + startTime: string; + }[]; +}; + +export type UserSpoolStaking = { + userSpoolStaking: { + id: string; + spoolStaked: string; + }; +}; + +export interface RewardApyReturnType { + vaultId: string; + rewardTokens: { + id: string; + rewardRate: string; + decimals: number; + apy: string; + }[]; +} +export interface SmartVaultRewards { + smartVaultRewardTokens: RewardToken[]; + id: string; +} + +interface RewardToken { + id: string; + rewardRate: string; + token: { + decimals: number; + id: string; + }; +} + +export type rewardsApyQueryData = { + smartVaults: { + smartVaultRewardTokens: { + id: string; + rewardRate: string; + token: { + decimals: number; + id: string; + }; + }[]; + id: string; + }[]; +}; + +export type userNftQueryData = { + user: { + id: string; + smartVaultDepositNFTs: { + smartVault: { + id: string; + }; + nftId: string; + }[]; + }; +}; + +export type SpoolVaultDefinition = { + address: string; + name: string; + riskModel: string; + suppliedTokenAddresses: string[]; + rewardTokenAddresses: string[] | null; + strategyAddresses: string[]; + stats: { + riskTolerance: number; + tvr: string; + tvrUsd: string; + fees: number; + adjustedApy: number; + rewardsApy: string[]; + baseApy: number; + vaultAssets: BigNumber[]; + }; +}; + +export type SpoolVaultDataProps = { + totalValueRoutedUsd: string; + baseApy: number; + adjustedApy: number; + totalValueRoutedSvt: string; + rewardsApy: string[]; + strategies: string[]; + riskScore: string; + riskTolerance: number; + vaultAssets: BigNumber[]; +}; + +export interface TvrType { + vault: Vault; + tvr: BigNumber; +} + +export interface vaultQueryData { + smartVaults: { + id: string; + smartVaultStrategies: { + id: string; + isRemoved: boolean; + strategy: { + id: string; + }; + }[]; + }[]; +} + +export interface depositsQueryData { + smartVaults: { + smartVaultFlushes: { + SmartVaultWithdrawalNFTs: { + svtWithdrawn: string; + }[]; + id: string; + isExecuted: boolean; + strategyDHWs: { + isExecuted: boolean; + id: string; + }[]; + }[]; + }[]; +} + +export interface BaseApy { + vault: Vault; + baseApy: string; +} + +export interface RewardsApy { + vault: Vault; + rewardsApys: string[]; +} +export interface assetGroupsData { + smartVaults: { + assetGroup: { + id: string; + assetGroupTokens: { + token: { + id: string; + decimals: number; + }; + }[]; + }; + }[]; +} +export interface VaultAsset { + vault: Vault; + assets: BigNumber[]; +} + +export interface allocationData { + smartVaults: { + id: string; + smartVaultStrategies: { + id: string; + allocation: string; + isRemoved: boolean; + strategy: { + id: string; + }; + }[]; + }[]; +} +export interface AdjustedApy { + vault: Vault; + adjustedApy: string; +} +export interface TokenPrice { + token: string; + price: string; +} +export interface globalFeesData { + globals: { + treasuryFee: string; + ecosystemFee: string; + }[]; +} +export interface feesData { + smartVaults: { + id: string; + smartVaultFees: { + performanceFeePercentage: string; + depositFeePercentage: string; + managementFeePercentage: string; + }; + }[]; +} +export interface TvrUsd { + vault: Vault; + tvrUsd: string; +} + +export interface StrategyAllocation { + vault: Vault; + strategies: Strategy[]; + allocations: string[]; +} + +export interface Strategy { + id: string; +} + +export interface Vault { + id: string; + strategies: Strategy[]; +} diff --git a/src/apps/spool-v2/ethereum/spool-v2.vault.contract-position-fetcher.ts b/src/apps/spool-v2/ethereum/spool-v2.vault.contract-position-fetcher.ts new file mode 100644 index 000000000..2764a958a --- /dev/null +++ b/src/apps/spool-v2/ethereum/spool-v2.vault.contract-position-fetcher.ts @@ -0,0 +1,738 @@ +import { Inject } from '@nestjs/common'; +import { BigNumber, BigNumberish, ethers } from 'ethers'; + +import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; +import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; +import { + buildDollarDisplayItem, + buildPercentageDisplayItem, + buildStringDisplayItem, +} from '~app-toolkit/helpers/presentation/display-item.present'; +import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; +import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; +import { StrategyRegistryContract } from '~apps/spool-v2/contracts/viem/StrategyRegistry'; +import { MetaType } from '~position/position.interface'; +import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher'; +import { + GetDataPropsParams, + GetDisplayPropsParams, + GetTokenBalancesParams, + GetTokenDefinitionsParams, +} from '~position/template/contract-position.template.types'; + +import { SpoolV2ViemContractFactory } from '../contracts'; +import { SpoolVault } from '../contracts/viem'; + +import { + APY_DECIMALS, + ASSET_GROUPS_QUERY, + DEPOSITS_QUERY, + FEES_QUERY, + GLOBAL_FEES_QUERY, + REWARDS_APY_QUERY, + SPOOL_LENS_ADDRESS, + STRATEGY_ALLOCATION_QUERY, + STRATEGY_REGISTRY_ADDRESS, + SUBGRAPH_API_BASE_URL, + USER_NFTS_QUERY, + VAULTS_AND_STRATEGIES_QUERY, + VAULTS_QUERY, +} from './spool-v2.constants'; +import { + AdjustedApy, + allocationData, + assetGroupsData, + BaseApy, + depositsQueryData, + feesData, + globalFeesData, + Globals, + RewardApyReturnType, + RewardsApy, + rewardsApyQueryData, + SmartVaultRewards, + SpoolVaultDataProps, + SpoolVaultDefinition, + SpoolVaults, + Strategy, + StrategyAllocation, + TokenPrice, + TvrType, + TvrUsd, + userNftQueryData, + Vault, + VaultAsset, + VaultDetails, + vaultQueryData, + VaultsAnalytics, +} from './spool-v2.types'; + +const riskModels = { '0xc216ad6280f4fa92a5159ef383a1206d432481c8': 'Spool Labs' }; + +@PositionTemplate() +export class EthereumSpoolV2VaultContractPositionFetcher extends ContractPositionTemplatePositionFetcher< + SpoolVault, + SpoolVaultDataProps, + SpoolVaultDefinition +> { + groupLabel = 'Vaults'; + + constructor( + @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, + @Inject(SpoolV2ViemContractFactory) protected readonly spoolV2ContractFactory: SpoolV2ViemContractFactory, + ) { + super(appToolkit); + } + + getContract(_address: string) { + return this.spoolV2ContractFactory.spoolVault({ address: _address, network: this.network }); + } + + async getDataProps({ definition }: GetDataPropsParams) { + return { + totalValueRoutedSvt: definition.stats.tvr, + totalValueRoutedUsd: definition.stats.tvrUsd, + baseApy: definition.stats.baseApy, + adjustedApy: definition.stats.adjustedApy, + rewardsApy: definition.stats.rewardsApy, + strategies: definition.strategyAddresses, + riskScore: this.getRiskScoreString(definition.stats.riskTolerance), + riskTolerance: definition.stats.riskTolerance, + vaultAssets: definition.stats.vaultAssets, + }; + } + + async getDefinitions() { + const vaultsData = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: VAULTS_QUERY, + }); + + const fees = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: GLOBAL_FEES_QUERY, + }); + + const vaultAnalytics = await this.getVaultsAnalytics(); + + return vaultsData.smartVaults.map(vault => ({ + address: vault.id.toLowerCase(), + name: vault.name, + riskModel: vault.riskProvider ? vault.riskProvider.id : '', + suppliedTokenAddresses: vault.assetGroup.assetGroupTokens.map(agt => agt.token.id.toLowerCase()), + rewardTokenAddresses: + vault.smartVaultRewardTokens.length > 0 + ? vault.smartVaultRewardTokens.map(rt => rt.token.id.toLowerCase()) + : null, + strategyAddresses: vault.smartVaultStrategies.map(s => s.strategy.id.toLowerCase()), + stats: this.getVaultStats( + vault, + vaultAnalytics.smartVaults.find(va => va.id == vault.id), + fees, + ), + })); + } + async getTokenBalancesPerPosition({ + address, + contractPosition, + }: GetTokenBalancesParams): Promise { + const spoolLens = await this.spoolV2ContractFactory.spoolLens({ + address: SPOOL_LENS_ADDRESS, + network: this.network, + }); + + const userSvtBalance = await spoolLens.read.getUserSVTBalance([ + contractPosition.address, + address, + await this.getUserDepositNFTs(address, contractPosition.address), + ]); + await userSvtBalance; + const userSvtBalanceString = userSvtBalance.toString(); + const tvrSvt = contractPosition.dataProps.totalValueRoutedSvt; + const vaultAssets = contractPosition.dataProps.vaultAssets; + if (vaultAssets.length == 0 || tvrSvt == '0') return new Array(0); + const percentage = parseFloat(userSvtBalanceString) / parseFloat(tvrSvt); + return vaultAssets.map(va => { + const calculated = percentage * parseFloat(ethers.utils.formatEther(va)); + // below the threshold + if (calculated < 1) { + return ethers.constants.Zero; + } + return ethers.utils.parseEther((percentage * parseFloat(ethers.utils.formatEther(va))).toString()); + }); + } + + async getUserDepositNFTs(address: string, smartVault: string): Promise { + const res = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: USER_NFTS_QUERY, + variables: { address, smartVault }, + }); + return res.user.smartVaultDepositNFTs.map(nft => BigInt(nft.nftId)); + } + async getTokenDefinitions({ definition }: GetTokenDefinitionsParams) { + return [ + ...definition.suppliedTokenAddresses.map(address => ({ + metaType: MetaType.SUPPLIED, + address, + network: this.network, + })), + ]; + } + + async getLabel({ definition }: GetDisplayPropsParams) { + return definition.name; + } + + async getSecondaryLabel({ + contractPosition, + }: GetDisplayPropsParams) { + return contractPosition.tokens.map(token => getLabelFromToken(token)).join(', '); + } + async getStatsItems({ definition }: GetDisplayPropsParams) { + return [ + { label: 'APY', value: buildPercentageDisplayItem(definition.stats.adjustedApy) }, + { label: 'TVR', value: buildDollarDisplayItem(Number(definition.stats.tvrUsd)) }, + { label: 'Risk Model', value: buildStringDisplayItem(riskModels[definition.riskModel]) }, + { + label: 'Risk Appetite', + value: buildStringDisplayItem( + `${this.getRiskScoreString(definition.stats.riskTolerance)} (${this.mapRiskToRange( + definition.stats.riskTolerance, + )})`, + ), + }, + { + label: 'Reward Tokens', + value: buildStringDisplayItem( + definition.rewardTokenAddresses?.map(address => address.toString()).join(', '), + ), + }, + ]; + } + /** + * Calculate APY, TVR (total value routed) and fees. + * @param vault + * @param vaultAnalytics + * @param platformFees + */ + getVaultStats( + vault: VaultDetails, + vaultAnalytics: + | { + id: string; + tvr: string; + baseApy: string; + rewardsApy: string[]; + adjustedApy: string; + tvrUsd: string; + vaultAssets: BigNumber[]; + } + | undefined, + platformFees: Globals, + ) { + const fees = + parseFloat(platformFees.globals.ecosystemFee) + + parseFloat(platformFees.globals.treasuryFee) + + parseFloat(vault.smartVaultFees.performanceFeePercentage) + + parseFloat(vault.smartVaultFees.managementFeePercentage); + + let tvr = '0'; + let tvrUsd = '0'; + let adjustedApy = 0.0; + let rewardsApys = ['0']; + let baseApy = 0.0; + let vaultAssets = [BigNumber.from(0)]; + if (vaultAnalytics) { + tvr = vaultAnalytics.tvr; + tvrUsd = vaultAnalytics.tvrUsd; + adjustedApy = parseFloat(vaultAnalytics.adjustedApy) * 100; + rewardsApys = vaultAnalytics.rewardsApy; + baseApy = parseFloat(vaultAnalytics.baseApy) * 100; + vaultAssets = vaultAnalytics.vaultAssets; + } + + const riskTolerance = Number(vault.riskTolerance); + + return { + riskTolerance: riskTolerance, + tvr: tvr, + tvrUsd: tvrUsd, + fees: fees, + adjustedApy: adjustedApy, + rewardsApy: rewardsApys, + baseApy: baseApy, + vaultAssets: vaultAssets, + }; + } + + /** + * Fetch vault analytics + */ + async getVaultsAnalytics(): Promise { + const vaults = await this.getVaults(); + + const tvrSvts = await this.getTvrSvts(vaults); + const baseApys = await this.getBaseApys(vaults); + const tvrUsds = await this.getTvrUsds(vaults); + const rewardsApys = await this.getRewardsApys(vaults, tvrUsds); + const adjustedApys = await this.getAdjustedApys(vaults, baseApys, rewardsApys); + const vaultAssets: VaultAsset[] = await this.getVaultAssets(vaults); + const smartVaults = vaults.map(vault => { + const tvrUsd = tvrUsds.find(tvrUsd => tvrUsd.vault.id == vault.id)?.tvrUsd; + const tvr = tvrSvts.find(tvrSvt => tvrSvt.vault.id == vault.id)?.tvr; + const baseApy = baseApys.find(baseApy => baseApy.vault.id == vault.id)?.baseApy; + const rewardsApy = rewardsApys.find(rewardsApy => rewardsApy.vault.id == vault.id)?.rewardsApys; + const adjustedApy = adjustedApys.find(adjustedApy => adjustedApy.vault.id == vault.id)?.adjustedApy; + const vaultAsset = vaultAssets.find(vaultAsset => vaultAsset.vault.id == vault.id); + if (!tvrUsd || !tvr || !baseApy || !rewardsApy || !adjustedApy || !vaultAsset) { + throw new Error('Missing data for vault analytics'); + } + return { + id: vault.id, + tvr: tvr.toString(), + tvrUsd: tvrUsd.toString(), + baseApy: baseApy, + rewardsApy: rewardsApy, + adjustedApy: adjustedApy, + vaultAssets: vaultAsset.assets, + }; + }); + return { + smartVaults: smartVaults, + }; + } + + async getVaults(): Promise { + const data = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: VAULTS_AND_STRATEGIES_QUERY, + }); + if (data === undefined) { + throw new Error('No data returned from queryVaultData'); + } + return this.processVaultData(data); + } + + processVaultData(vaultQueryData: vaultQueryData): Vault[] { + const vaults: Vault[] = []; + for (const vault of vaultQueryData.smartVaults) { + const tempVault: Vault = { id: '', strategies: [] }; + tempVault.id = vault.id.toLowerCase(); + for (const strategy of vault.smartVaultStrategies) { + tempVault.strategies.push({ + id: strategy.strategy.id.toLowerCase(), + }); + } + vaults.push(tempVault); + } + return vaults; + } + + async getTokenPrices(assetGroupsData: assetGroupsData): Promise { + const tokenPrices: TokenPrice[] = []; + for (const smartVault of assetGroupsData.smartVaults) { + for (const token of smartVault.assetGroup.assetGroupTokens) { + const baseToken = await this.appToolkit.getBaseTokenPrice({ + network: this.network, + address: token.token.id, + }); + if (baseToken === null) { + tokenPrices.push({ token: token.token.id, price: '0' }); + } else { + tokenPrices.push({ token: token.token.id, price: baseToken.price.toString() }); + } + } + } + return tokenPrices; + } + + async getTvrUsds(vaults: Vault[]): Promise { + const assetGroupsData = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: ASSET_GROUPS_QUERY, + }); + if (assetGroupsData === undefined) { + throw new Error('No data returned from queryAssetGroupData'); + } + const vaultAssets: VaultAsset[] = await this.getVaultAssets(vaults); + const prices: TokenPrice[] = await this.getTokenPrices(assetGroupsData); + return this.processTvrUsds(vaults, assetGroupsData, vaultAssets, prices); + } + + async getVaultAssets(vaults: Vault[]): Promise { + const spoolLens = this.spoolV2ContractFactory.spoolLens({ address: SPOOL_LENS_ADDRESS, network: this.network }); + const vaultAssets: VaultAsset[] = []; + for (const vault of vaults) { + const assetsBigint: readonly bigint[] = (await spoolLens.simulate.getSmartVaultAssetBalances([vault.id, false])) + .result; + const assets: BigNumber[] = assetsBigint.map(asset => ethers.BigNumber.from(asset)); + vaultAssets.push({ vault: vault, assets: assets }); + } + return vaultAssets; + } + + processTvrUsds( + vaults: Vault[], + assetGroupData: assetGroupsData, + vaultAssets: VaultAsset[], + prices: TokenPrice[], + ): TvrUsd[] { + const tvrUsds: TvrUsd[] = []; + for (const vault of vaults) { + let sum = 0; + for (const assetAmount of vaultAssets[vaults.indexOf(vault)].assets) { + const token = + assetGroupData.smartVaults[vaults.indexOf(vault)].assetGroup.assetGroupTokens[ + vaultAssets[vaults.indexOf(vault)].assets.indexOf(assetAmount) + ].token; + const tokenId = token.id; + const tokenDecimals = token.decimals; + const assetAmountFormatted = Number(ethers.utils.formatUnits(assetAmount, tokenDecimals)); + const tokenPrice = prices.find(tokenPrice => tokenPrice.token == tokenId); + if (tokenPrice == undefined) { + continue; + } + sum += assetAmountFormatted * parseFloat(tokenPrice.price); + } + tvrUsds.push({ vault: vault, tvrUsd: sum.toString() }); + } + return tvrUsds; + } + + async getBaseApys(vaults: Vault[]): Promise { + const decimals = APY_DECIMALS; + + const strategyRegistry = this.spoolV2ContractFactory.strategyRegistry({ + address: STRATEGY_REGISTRY_ADDRESS, + network: this.network, + }); + const strategyAllocations = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: STRATEGY_ALLOCATION_QUERY, + }); + if (strategyAllocations === undefined) { + throw new Error('No data returned from getAllocations'); + } + const strategiesRetn = this.getUniqueStrategyAddresses(vaults); + const stratAPYs = await this.getStrategyApys(strategiesRetn, strategyRegistry); + return this.processBaseApyData(vaults, strategyAllocations, stratAPYs, decimals); + } + + getUniqueStrategyAddresses(vaults: Vault[]): Strategy[] { + const strategiesRetn: Strategy[] = []; + for (const vault of vaults) { + for (const strategy of vault.strategies) { + if (!strategiesRetn.includes(strategy)) { + strategiesRetn.push(strategy); + } + } + } + return strategiesRetn; + } + + async getStrategyApys( + strategyAddresses: Strategy[], + strategyRegistry: StrategyRegistryContract, + ): Promise> { + const strategyIds = strategyAddresses.map(strategy => strategy.id); + const stratAPYsBigint: readonly bigint[] = await strategyRegistry.read.strategyAPYs([strategyIds]); + const stratAPYs: BigNumber[] = stratAPYsBigint.map(stratApy => ethers.BigNumber.from(stratApy)); + const mapReturn = new Map(); + for (const stratApy of stratAPYs) { + mapReturn.set(strategyIds[stratAPYs.indexOf(stratApy)], stratApy); + } + return mapReturn; + } + + processBaseApyData( + vaults: Vault[], + strategyAllocationDatas: allocationData, + strategyAPYs: Map, + decimals: string, + ): BaseApy[] { + const strategyAllocations: StrategyAllocation[] = []; + for (const vault of vaults) { + const allocations: string[] = []; + const strategies: Strategy[] = []; + for (const strategyAllocationData of strategyAllocationDatas.smartVaults) { + if (vault.id == strategyAllocationData.id) { + for (const strategyAllocationDataStrategy of strategyAllocationData.smartVaultStrategies) { + if (!strategyAllocationDataStrategy.isRemoved) { + allocations.push(strategyAllocationDataStrategy.allocation); + } else { + allocations.push('0'); + } + strategies.push({ + id: strategyAllocationDataStrategy.strategy.id.toLowerCase(), + }); + } + } + } + strategyAllocations.push({ + vault: vault, + allocations: allocations, + strategies: strategies, + }); + } + const apys: BigNumber[] = []; + for (const vault of vaults) { + apys[vaults.indexOf(vault)] = ethers.constants.Zero; + for (const strategy of vault.strategies) { + const strategyAPY = strategyAPYs.get(strategy.id); + if (strategyAPY == undefined) { + throw new Error('Strategy APY is undefined'); + } + const x = BigNumber.from( + strategyAllocations[vaults.indexOf(vault)].allocations[vault.strategies.indexOf(strategy)], + ); + apys[vaults.indexOf(vault)] = apys[vaults.indexOf(vault)].add(strategyAPY.mul(x)); + } + } + const baseApys: BaseApy[] = []; + + for (const vault of vaults) { + baseApys.push({ + vault: vault, + baseApy: ((Number(apys[vaults.indexOf(vault)]) / Math.pow(10, Number.parseInt(decimals))) * 100).toString(), + }); + } + + return baseApys; + } + async getRewardsApys(vaults: Vault[], tvrUsds: TvrUsd[]): Promise { + const rewardApysFirstPart = await this.getRewardApys(); + return this.processRewardsApys(rewardApysFirstPart, vaults, tvrUsds); + } + async getRewardApys(): Promise { + const now = Math.floor(Date.now() / 1000).toString(); + const res = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: REWARDS_APY_QUERY, + variables: { now }, + }); + + const data = res.smartVaults as SmartVaultRewards[]; + + return await Promise.all( + data + .filter(vault => vault.smartVaultRewardTokens.length > 0) + .map(async vault => { + return { + vaultId: vault.id, + rewardTokens: await Promise.all( + vault.smartVaultRewardTokens.map(async reward => { + const baseToken = await this.appToolkit.getBaseTokenPrice({ + network: this.network, + address: reward.token.id as string, + }); + let apy = '0'; + if (baseToken != undefined) { + apy = ( + parseFloat( + BigNumber.from(reward.rewardRate) + .div(BigNumber.from(10).pow(reward.token.decimals)) + .mul(BigNumber.from(60)) + .mul(BigNumber.from(60)) + .mul(BigNumber.from(24)) + .mul(BigNumber.from(365)) + .toString(), + ) * baseToken.price + ).toString(); + } + return { + id: reward.token.id, + rewardRate: reward.rewardRate, + decimals: reward.token.decimals, + apy: apy, + }; + }), + ), + }; + }), + ); + } + + processRewardsApys(data: RewardApyReturnType[], vaults: Vault[], tvrUsds: TvrUsd[]): RewardsApy[] { + const decimals = APY_DECIMALS; + const calculationHelper = new Map(); + const result: string[][] = []; + for (const rewardManagerApy of data) { + const vaultAddress = rewardManagerApy.vaultId; + if (calculationHelper.get(vaultAddress) == undefined) { + calculationHelper.set(vaultAddress, []); + } + const insertHelper = calculationHelper.get(vaultAddress); + for (const rewardToken of rewardManagerApy.rewardTokens) { + if (insertHelper != null) { + insertHelper.push(BigNumber.from(BigInt(parseFloat(rewardToken.apy)))); + calculationHelper.set(vaultAddress, insertHelper); + } + } + } + + for (const vault of vaults) { + result[vaults.indexOf(vault)] = []; + for (const rewardManagerApy of data) { + if (vault.id == rewardManagerApy.vaultId) { + const calculationHelperValues = calculationHelper.get(vault.id); + if (calculationHelperValues == undefined) { + throw new Error('calculationHelperValues is undefined'); + } + for (const apy of calculationHelperValues) { + if (tvrUsds[vaults.indexOf(vault)].tvrUsd == '0') { + result[vaults.indexOf(vault)].push('0'); + continue; + } + result[vaults.indexOf(vault)].push( + ( + Number( + apy + .mul(BigNumber.from(10).pow(Number.parseInt(decimals))) + .div(BigNumber.from(tvrUsds[vaults.indexOf(vault)].tvrUsd.split('.')[0])) + .div(BigNumber.from(10).pow(Number.parseInt(decimals))), + ) / Math.pow(10, 18) + ).toString(), + ); + } + } + } + } + + const rewardsApys: RewardsApy[] = []; + for (const vault of vaults) { + rewardsApys[vaults.indexOf(vault)] = { + vault: vault, + rewardsApys: result[vaults.indexOf(vault)], + }; + } + return rewardsApys; + } + + async getAdjustedApys(vaults: Vault[], baseApys: BaseApy[], rewardsApys: RewardsApy[]): Promise { + const globalFeesData = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: GLOBAL_FEES_QUERY, + }); + + const feesData = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: FEES_QUERY, + }); + + if (globalFeesData === undefined) { + throw new Error('No data returned from queryGlobalFeesData'); + } + if (feesData === undefined) { + throw new Error('No data returned from queryFeesData'); + } + return this.processAdjustedApys(vaults, baseApys, rewardsApys, globalFeesData, feesData); + } + + processAdjustedApys( + vaults: Vault[], + baseApys: BaseApy[], + rewardsApys: RewardsApy[], + globalFeesData: globalFeesData, + feesData: feesData, + ): AdjustedApy[] { + const adjustedApys: AdjustedApy[] = []; + + const globalFee = + parseInt(globalFeesData.globals[0].treasuryFee) + parseInt(globalFeesData.globals[0].ecosystemFee); + for (const vault of vaults) { + let apySum = 0; + + const fees = feesData.smartVaults.find(v => v.id == vault.id); + if (fees == undefined) { + throw new Error('No fees found for vault ' + vault.id); + } + const feesSmartVaultFees = fees.smartVaultFees; + + const baseApy = baseApys.find(apy => apy.vault.id == vault.id); + if (baseApy == undefined) { + throw new Error('No baseApy found for vault ' + vault.id); + } + const baseApyData = Number(baseApy.baseApy); + + apySum = + baseApyData * + ((100 - + (parseFloat(feesSmartVaultFees.managementFeePercentage) + + parseFloat(feesSmartVaultFees.performanceFeePercentage) + + globalFee)) / + 100); + + const rewardApy = rewardsApys.find(apy => apy.vault.id == vault.id); + if (rewardApy != undefined) { + for (const apy of rewardApy.rewardsApys) { + apySum += Number(apy); + } + } + + adjustedApys.push({ vault: vault, adjustedApy: apySum.toString() }); + } + return adjustedApys; + } + + async getTvrSvts(vaults: Vault[]): Promise { + const smartVaultDeposits = await gqlFetch({ + endpoint: SUBGRAPH_API_BASE_URL, + query: DEPOSITS_QUERY, + }); + + return this.processTvrSvts(vaults, smartVaultDeposits); + } + + async processTvrSvts(vaults: Vault[], smartVaultDeposits: depositsQueryData | undefined): Promise { + const spoolLens = this.spoolV2ContractFactory.spoolLens({ address: SPOOL_LENS_ADDRESS, network: this.network }); + const tvrs: TvrType[] = []; + if (smartVaultDeposits == undefined) { + return tvrs; + } + const tvrCalculationsBigint: readonly bigint[] = await Promise.all( + vaults.map(vault => spoolLens.read.getSVTTotalSupply([vault.id])), + ); + const tvrCalculations: BigNumber[] = tvrCalculationsBigint.map(asset => ethers.BigNumber.from(asset)); + + for (const vault of smartVaultDeposits.smartVaults) { + for (const smartVaultDeposit of vault.smartVaultFlushes) { + if (smartVaultDeposit.isExecuted && !smartVaultDeposit.strategyDHWs[0].isExecuted) { + for (const flush of vault.smartVaultFlushes) { + if (smartVaultDeposit.id == flush.id) { + for (const smartVaultWithdrawalNft of flush.SmartVaultWithdrawalNFTs) { + tvrCalculations[smartVaultDeposits.smartVaults.indexOf(vault)] = tvrCalculations[ + smartVaultDeposits.smartVaults.indexOf(vault) + ].add(smartVaultWithdrawalNft.svtWithdrawn); + } + } + } + } + } + } + for (const vault of vaults) { + tvrs.push({ + vault: vault, + tvr: tvrCalculations[vaults.indexOf(vault)], + }); + } + return tvrs; + } + + getRiskScoreString(riskTolerance: number) { + const risk = this.mapRiskToRange(riskTolerance); + switch (true) { + case risk > 5: + return 'Risk Seeking'; + case risk === 5: + return 'Risk Neutral'; + default: + return 'Risk Averse'; + } + } + mapRiskToRange(risk: number) { + const [inMin, inMax] = [-10, 10]; + const [outMin, outMax] = [0, 10]; + return ((risk - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin; + } +} diff --git a/src/apps/spool-v2/ethereum/spool-v2.vo-spool.token-fetcher.ts b/src/apps/spool-v2/ethereum/spool-v2.vo-spool.token-fetcher.ts new file mode 100644 index 000000000..b8ba77089 --- /dev/null +++ b/src/apps/spool-v2/ethereum/spool-v2.vo-spool.token-fetcher.ts @@ -0,0 +1,44 @@ +import { Inject } from '@nestjs/common'; + +import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; +import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; +import { AppTokenTemplatePositionFetcher } from '~position/template/app-token.template.position-fetcher'; + +import { SpoolV2ViemContractFactory } from '../contracts'; +import { SpoolVospool } from '../contracts/viem'; + +import { VOSPOOL_ADDRESS } from './spool-v2.constants'; +@PositionTemplate() +export class EthereumSpoolV2VoSpoolTokenFetcher extends AppTokenTemplatePositionFetcher { + groupLabel = 'voSPOOL'; + isExcludedFromBalances = true; + isExcludedFromExplore = true; + isExcludedFromTvl = true; + + constructor( + @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, + @Inject(SpoolV2ViemContractFactory) protected readonly contractFactory: SpoolV2ViemContractFactory, + ) { + super(appToolkit); + } + + getContract(address: string) { + return this.contractFactory.spoolVospool({ address, network: this.network }); + } + + async getAddresses(): Promise { + return [VOSPOOL_ADDRESS]; + } + + async getUnderlyingTokenDefinitions() { + return []; + } + + async getPricePerShare() { + return [1]; + } + + async getPrice() { + return 0; // Valueless token + } +} diff --git a/src/apps/spool-v2/spool-v2.module.ts b/src/apps/spool-v2/spool-v2.module.ts new file mode 100644 index 000000000..663b05a63 --- /dev/null +++ b/src/apps/spool-v2/spool-v2.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common'; + +import { AbstractApp } from '../../../../studio/src/app/app.dynamic-module'; + +import { SpoolV2ViemContractFactory } from './contracts'; +import { EthereumSpoolV2StakingContractPositionFetcher } from './ethereum/spool-v2.staking.contract-position-fetcher'; +import { EthereumSpoolV2VaultContractPositionFetcher } from './ethereum/spool-v2.vault.contract-position-fetcher'; +import { EthereumSpoolV2VoSpoolTokenFetcher } from './ethereum/spool-v2.vo-spool.token-fetcher'; + +@Module({ + providers: [ + EthereumSpoolV2StakingContractPositionFetcher, + EthereumSpoolV2VaultContractPositionFetcher, + EthereumSpoolV2VoSpoolTokenFetcher, + SpoolV2ViemContractFactory, + ], +}) +export class SpoolV2AppModule extends AbstractApp() {}