diff --git a/src/apps/kwenta/contracts/abis/kwenta-perp.json b/src/apps/kwenta/contracts/abis/kwenta-perp.json new file mode 100644 index 000000000..f87ae7579 --- /dev/null +++ b/src/apps/kwenta/contracts/abis/kwenta-perp.json @@ -0,0 +1,783 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_marketState", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_resolver", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "CacheUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerNominated", + "type": "event" + }, + { + "constant": false, + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "accessibleMargin", + "outputs": [ + { + "internalType": "uint256", + "name": "marginAccessible", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "accruedFunding", + "outputs": [ + { + "internalType": "int256", + "name": "funding", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "assetPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "baseAsset", + "outputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "canLiquidate", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "currentFundingRate", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "currentFundingVelocity", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "int256", + "name": "sizeDelta", + "type": "int256" + } + ], + "name": "fillPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "fundingLastRecomputed", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "fundingSequence", + "outputs": [ + { + "internalType": "int128", + "name": "", + "type": "int128" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "fundingSequenceLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isResolverCached", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "liquidationFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "liquidationPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketKey", + "outputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketSize", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketSizes", + "outputs": [ + { + "internalType": "uint256", + "name": "long", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "short", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketSkew", + "outputs": [ + { + "internalType": "int128", + "name": "", + "type": "int128" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketState", + "outputs": [ + { + "internalType": "contract IPerpsV2MarketState", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "nominateNewOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "nominatedOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "notionalValue", + "outputs": [ + { + "internalType": "int256", + "name": "value", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "int256", + "name": "sizeDelta", + "type": "int256" + }, + { + "internalType": "enum IPerpsV2MarketBaseTypes.OrderType", + "name": "orderType", + "type": "uint8" + } + ], + "name": "orderFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "positions", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "lastFundingIndex", + "type": "uint64" + }, + { + "internalType": "uint128", + "name": "margin", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "lastPrice", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "size", + "type": "int128" + } + ], + "internalType": "struct IPerpsV2MarketBaseTypes.Position", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "int256", + "name": "sizeDelta", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "tradePrice", + "type": "uint256" + }, + { + "internalType": "enum IPerpsV2MarketBaseTypes.OrderType", + "name": "orderType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "postTradeDetails", + "outputs": [ + { + "internalType": "uint256", + "name": "margin", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "size", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liqPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "enum IPerpsV2MarketBaseTypes.Status", + "name": "status", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "profitLoss", + "outputs": [ + { + "internalType": "int256", + "name": "pnl", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "rebuildCache", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "remainingMargin", + "outputs": [ + { + "internalType": "uint256", + "name": "marginRemaining", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "resolver", + "outputs": [ + { + "internalType": "contract AddressResolver", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "resolverAddressesRequired", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "addresses", + "type": "bytes32[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "unrecordedFunding", + "outputs": [ + { + "internalType": "int256", + "name": "funding", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/kwenta/contracts/viem.contract-factory.ts b/src/apps/kwenta/contracts/viem.contract-factory.ts index b263a13b7..ababf46dc 100644 --- a/src/apps/kwenta/contracts/viem.contract-factory.ts +++ b/src/apps/kwenta/contracts/viem.contract-factory.ts @@ -6,6 +6,7 @@ import { Network } from '~types/network.interface'; import { KwentaAccountResolver__factory, KwentaEscrow__factory, + KwentaPerp__factory, KwentaStaking__factory, KwentaStakingV2__factory, } from './viem'; @@ -22,6 +23,9 @@ export class KwentaViemContractFactory { kwentaEscrow({ address, network }: ContractOpts) { return KwentaEscrow__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); } + kwentaPerp({ address, network }: ContractOpts) { + return KwentaPerp__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } kwentaStaking({ address, network }: ContractOpts) { return KwentaStaking__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); } diff --git a/src/apps/kwenta/contracts/viem/KwentaPerp.ts b/src/apps/kwenta/contracts/viem/KwentaPerp.ts new file mode 100644 index 000000000..82a7bd3de --- /dev/null +++ b/src/apps/kwenta/contracts/viem/KwentaPerp.ts @@ -0,0 +1,797 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const kwentaPerpAbi = [ + { + inputs: [ + { + internalType: 'address', + name: '_marketState', + type: 'address', + }, + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + { + internalType: 'address', + name: '_resolver', + type: 'address', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'name', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + ], + name: 'CacheUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerNominated', + type: 'event', + }, + { + constant: false, + inputs: [], + name: 'acceptOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'accessibleMargin', + outputs: [ + { + internalType: 'uint256', + name: 'marginAccessible', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'accruedFunding', + outputs: [ + { + internalType: 'int256', + name: 'funding', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'assetPrice', + outputs: [ + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'baseAsset', + outputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'canLiquidate', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'currentFundingRate', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'currentFundingVelocity', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'int256', + name: 'sizeDelta', + type: 'int256', + }, + ], + name: 'fillPrice', + outputs: [ + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'fundingLastRecomputed', + outputs: [ + { + internalType: 'uint32', + name: '', + type: 'uint32', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'fundingSequence', + outputs: [ + { + internalType: 'int128', + name: '', + type: 'int128', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'fundingSequenceLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isResolverCached', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'liquidationFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'liquidationPrice', + outputs: [ + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketDebt', + outputs: [ + { + internalType: 'uint256', + name: 'debt', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketKey', + outputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketSize', + outputs: [ + { + internalType: 'uint128', + name: '', + type: 'uint128', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketSizes', + outputs: [ + { + internalType: 'uint256', + name: 'long', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'short', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketSkew', + outputs: [ + { + internalType: 'int128', + name: '', + type: 'int128', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketState', + outputs: [ + { + internalType: 'contract IPerpsV2MarketState', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + name: 'nominateNewOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'nominatedOwner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'notionalValue', + outputs: [ + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'int256', + name: 'sizeDelta', + type: 'int256', + }, + { + internalType: 'enum IPerpsV2MarketBaseTypes.OrderType', + name: 'orderType', + type: 'uint8', + }, + ], + name: 'orderFee', + outputs: [ + { + internalType: 'uint256', + name: 'fee', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'positions', + outputs: [ + { + components: [ + { + internalType: 'uint64', + name: 'id', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'lastFundingIndex', + type: 'uint64', + }, + { + internalType: 'uint128', + name: 'margin', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'lastPrice', + type: 'uint128', + }, + { + internalType: 'int128', + name: 'size', + type: 'int128', + }, + ], + internalType: 'struct IPerpsV2MarketBaseTypes.Position', + name: '', + type: 'tuple', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'int256', + name: 'sizeDelta', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'tradePrice', + type: 'uint256', + }, + { + internalType: 'enum IPerpsV2MarketBaseTypes.OrderType', + name: 'orderType', + type: 'uint8', + }, + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'postTradeDetails', + outputs: [ + { + internalType: 'uint256', + name: 'margin', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'size', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liqPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fee', + type: 'uint256', + }, + { + internalType: 'enum IPerpsV2MarketBaseTypes.Status', + name: 'status', + type: 'uint8', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'profitLoss', + outputs: [ + { + internalType: 'int256', + name: 'pnl', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'rebuildCache', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'remainingMargin', + outputs: [ + { + internalType: 'uint256', + name: 'marginRemaining', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'resolver', + outputs: [ + { + internalType: 'contract AddressResolver', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'resolverAddressesRequired', + outputs: [ + { + internalType: 'bytes32[]', + name: 'addresses', + type: 'bytes32[]', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'unrecordedFunding', + outputs: [ + { + internalType: 'int256', + name: 'funding', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type KwentaPerp = typeof kwentaPerpAbi; +export type KwentaPerpContract = GetContractReturnType; + +export class KwentaPerp__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: kwentaPerpAbi, publicClient: client }); + } +} diff --git a/src/apps/kwenta/contracts/viem/index.ts b/src/apps/kwenta/contracts/viem/index.ts index 98aeb8245..ee1fa21ca 100644 --- a/src/apps/kwenta/contracts/viem/index.ts +++ b/src/apps/kwenta/contracts/viem/index.ts @@ -4,10 +4,12 @@ export type { KwentaAccountResolver } from './KwentaAccountResolver'; export type { KwentaEscrow } from './KwentaEscrow'; +export type { KwentaPerp } from './KwentaPerp'; export type { KwentaStakingV2 } from './KwentaStakingV2'; export type { KwentaStaking } from './KwentaStaking'; export { KwentaAccountResolver__factory } from './KwentaAccountResolver'; export { KwentaEscrow__factory } from './KwentaEscrow'; +export { KwentaPerp__factory } from './KwentaPerp'; export { KwentaStakingV2__factory } from './KwentaStakingV2'; export { KwentaStaking__factory } from './KwentaStaking'; diff --git a/src/apps/kwenta/optimism/kwenta.perp-v1-cross-margin.contract-position-fetcher.ts b/src/apps/kwenta/optimism/kwenta.perp-v1-cross-margin.contract-position-fetcher.ts index 2acfc472b..d0e218c8b 100644 --- a/src/apps/kwenta/optimism/kwenta.perp-v1-cross-margin.contract-position-fetcher.ts +++ b/src/apps/kwenta/optimism/kwenta.perp-v1-cross-margin.contract-position-fetcher.ts @@ -1,10 +1,27 @@ +import { Inject } from '@nestjs/common'; import { gql } from 'graphql-request'; +import { sumBy } from 'lodash'; +import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; import { ZERO_ADDRESS } from '~app-toolkit/constants/address'; import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; +import { drillBalance } from '~app-toolkit/helpers/drill-balance.helper'; +import { getAppAssetImage } from '~app-toolkit/helpers/presentation/image.present'; import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; +import { SynthetixPerp } from '~apps/synthetix/contracts/viem'; +import { ContractType } from '~position/contract.interface'; +import { ContractPositionBalance } from '~position/position-balance.interface'; +import { MetaType } from '~position/position.interface'; +import { + GetDisplayPropsParams, + GetTokenBalancesParams, + GetTokenDefinitionsParams, + UnderlyingTokenDefinition, +} from '~position/template/contract-position.template.types'; +import { CustomContractPositionTemplatePositionFetcher } from '~position/template/custom-contract-position.template.position-fetcher'; -import { OptimismSynthetixPerpV1ContractPositionFetcher } from '../../synthetix/optimism/synthetix.perp-v1.contract-position-fetcher'; +import { KwentaViemContractFactory } from '../contracts'; +import { KwentaPerp } from '../contracts/viem'; type GetCrossMarginAccounts = { crossMarginAccounts: { @@ -21,11 +38,38 @@ const getCrossMarginAccountsQuery = gql` `; @PositionTemplate() -export class OptimismKwentaPerpV1CrossMarginContractPositionFetcher extends OptimismSynthetixPerpV1ContractPositionFetcher { - groupLabel = 'PerpV1 cross-margin'; - useCustomMarketLogos = true; +export class OptimismKwentaPerpV1CrossMarginContractPositionFetcher extends CustomContractPositionTemplatePositionFetcher { + groupLabel = 'Perp V1 Cross-Margin'; - async getAccountAddress(address: string): Promise { + constructor( + @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, + @Inject(KwentaViemContractFactory) protected readonly contractFactory: KwentaViemContractFactory, + ) { + super(appToolkit); + } + + getContract(address: string) { + return this.contractFactory.kwentaPerp({ address, network: this.network }); + } + + async getDefinitions() { + return []; // Resolve from Synthetix + } + + async getLabel(_params: GetDisplayPropsParams): Promise { + throw new Error('Method not implemented.'); + } + + async getTokenDefinitions(_params: GetTokenDefinitionsParams): Promise { + throw new Error('Method not implemented.'); + } + + async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams) { + const remainingMargin = await contract.read.remainingMargin([address]); + return [remainingMargin[0]]; + } + + async getMarginAccountAddress(address: string): Promise { const crossMarginAccountsFromSubgraph = await gqlFetch({ endpoint: 'https://api.thegraph.com/subgraphs/name/kwenta/optimism-main?source=zapper', query: getCrossMarginAccountsQuery, @@ -38,4 +82,57 @@ export class OptimismKwentaPerpV1CrossMarginContractPositionFetcher extends Opti return crossMarginAccountsFromSubgraph.crossMarginAccounts[0].id; } + + async getBalances(address: string): Promise { + const multicall = this.appToolkit.getViemMulticall(this.network); + if (address === ZERO_ADDRESS) return []; + + const marginAccountAddress = await this.getMarginAccountAddress(address); + if (marginAccountAddress === ZERO_ADDRESS) return []; + + const contractPositions = await this.appToolkit.getAppContractPositions({ + appId: 'synthetix', + network: this.network, + groupIds: ['perp-v1'], + }); + + const balances = await Promise.all( + contractPositions.map(async contractPosition => { + const contract = multicall.wrap(this.getContract(contractPosition.address)); + const balancesRaw = await this.getTokenBalancesPerPosition({ + address: marginAccountAddress, + contract, + contractPosition, + multicall, + }); + + const allTokens = contractPosition.tokens.map((cp, idx) => + drillBalance(cp, balancesRaw[idx]?.toString() ?? '0', { isDebt: cp.metaType === MetaType.BORROWED }), + ); + + const tokens = allTokens.filter(v => Math.abs(v.balanceUSD) > 0.01); + const balanceUSD = sumBy(tokens, t => t.balanceUSD); + + const balance: ContractPositionBalance = { + type: ContractType.POSITION, + address: marginAccountAddress, + network: this.network, + appId: this.appId, + groupId: this.groupId, + groupLabel: this.groupLabel, + tokens, + dataProps: contractPosition.dataProps, + displayProps: { + ...contractPosition.displayProps, + images: [getAppAssetImage(this.appId, `s${contractPosition.dataProps.asset}`)], + }, + balanceUSD, + }; + + return balance; + }), + ); + + return balances; + } } diff --git a/src/apps/kwenta/optimism/kwenta.perp-v2-smart-margin.contract-position-fetcher.ts b/src/apps/kwenta/optimism/kwenta.perp-v2-smart-margin.contract-position-fetcher.ts index ff830dedc..f20768c12 100644 --- a/src/apps/kwenta/optimism/kwenta.perp-v2-smart-margin.contract-position-fetcher.ts +++ b/src/apps/kwenta/optimism/kwenta.perp-v2-smart-margin.contract-position-fetcher.ts @@ -1,38 +1,122 @@ import { Inject } from '@nestjs/common'; +import { sumBy } from 'lodash'; import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; import { ZERO_ADDRESS } from '~app-toolkit/constants/address'; import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; +import { drillBalance } from '~app-toolkit/helpers/drill-balance.helper'; +import { getAppAssetImage } from '~app-toolkit/helpers/presentation/image.present'; +import { ContractType } from '~position/contract.interface'; +import { ContractPositionBalance } from '~position/position-balance.interface'; +import { MetaType } from '~position/position.interface'; +import { + GetDisplayPropsParams, + GetTokenBalancesParams, + GetTokenDefinitionsParams, + UnderlyingTokenDefinition, +} from '~position/template/contract-position.template.types'; +import { CustomContractPositionTemplatePositionFetcher } from '~position/template/custom-contract-position.template.position-fetcher'; -import { SynthetixViemContractFactory } from '../../synthetix/contracts'; -import { OptimismSynthetixPerpV2ContractPositionFetcher } from '../../synthetix/optimism/synthetix.perp-v2.contract-position-fetcher'; import { KwentaViemContractFactory } from '../contracts'; +import { KwentaPerp } from '../contracts/viem'; @PositionTemplate() -export class OptimismKwentaPerpV2SmartMarginContractPositionFetcher extends OptimismSynthetixPerpV2ContractPositionFetcher { - groupLabel = 'PerpV2 smart-margin'; - useCustomMarketLogos = true; +export class OptimismKwentaPerpV2SmartMarginContractPositionFetcher extends CustomContractPositionTemplatePositionFetcher { + groupLabel = 'Perp V2 Smart-Margin'; kwentaAccountResolverAddress = '0x8234f990b149ae59416dc260305e565e5dafeb54'; constructor( @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, - @Inject(SynthetixViemContractFactory) protected readonly synthetixContractFactory: SynthetixViemContractFactory, - @Inject(KwentaViemContractFactory) protected readonly kwentaContractFactory: KwentaViemContractFactory, + @Inject(KwentaViemContractFactory) protected readonly contractFactory: KwentaViemContractFactory, ) { - super(appToolkit, synthetixContractFactory); + super(appToolkit); } - async getAccountAddress(address: string): Promise { + getContract(address: string) { + return this.contractFactory.kwentaPerp({ address, network: this.network }); + } + + async getDefinitions() { + return []; // Resolve from Synthetix + } + + async getLabel(_params: GetDisplayPropsParams): Promise { + throw new Error('Method not implemented.'); + } + + async getTokenDefinitions(_params: GetTokenDefinitionsParams): Promise { + throw new Error('Method not implemented.'); + } + + async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams) { + const remainingMargin = await contract.read.remainingMargin([address]); + return [remainingMargin[0]]; + } + + async getMarginAccountAddress(address: string): Promise { const multicall = this.appToolkit.getViemMulticall(this.network); - const accountResolver = this.kwentaContractFactory.kwentaAccountResolver({ + const accountResolver = this.contractFactory.kwentaAccountResolver({ address: this.kwentaAccountResolverAddress, network: this.network, }); + const mcAccountResolver = multicall.wrap(accountResolver); const accountsOwned = await mcAccountResolver.read.getAccountsOwnedBy([address]); - if (accountsOwned.length === 0) { - return ZERO_ADDRESS; - } + if (accountsOwned.length === 0) return ZERO_ADDRESS; + return accountsOwned[0]; } + + async getBalances(address: string): Promise { + const multicall = this.appToolkit.getViemMulticall(this.network); + if (address === ZERO_ADDRESS) return []; + + const marginAccountAddress = await this.getMarginAccountAddress(address); + if (marginAccountAddress === ZERO_ADDRESS) return []; + + const contractPositions = await this.appToolkit.getAppContractPositions({ + appId: 'synthetix', + network: this.network, + groupIds: ['perp-v2'], + }); + + const balances = await Promise.all( + contractPositions.map(async contractPosition => { + const contract = multicall.wrap(this.getContract(contractPosition.address)); + const balancesRaw = await this.getTokenBalancesPerPosition({ + address: marginAccountAddress, + contract, + contractPosition, + multicall, + }); + + const allTokens = contractPosition.tokens.map((cp, idx) => + drillBalance(cp, balancesRaw[idx]?.toString() ?? '0', { isDebt: cp.metaType === MetaType.BORROWED }), + ); + + const tokens = allTokens.filter(v => Math.abs(v.balanceUSD) > 0.01); + const balanceUSD = sumBy(tokens, t => t.balanceUSD); + + const balance: ContractPositionBalance = { + type: ContractType.POSITION, + address: marginAccountAddress, + network: this.network, + appId: this.appId, + groupId: this.groupId, + groupLabel: this.groupLabel, + tokens, + dataProps: contractPosition.dataProps, + displayProps: { + ...contractPosition.displayProps, + images: [getAppAssetImage(this.appId, `s${contractPosition.dataProps.asset}`)], + }, + balanceUSD, + }; + + return balance; + }), + ); + + return balances; + } } diff --git a/src/apps/polynomial/contracts/abis/polynomial-perp.json b/src/apps/polynomial/contracts/abis/polynomial-perp.json new file mode 100644 index 000000000..f87ae7579 --- /dev/null +++ b/src/apps/polynomial/contracts/abis/polynomial-perp.json @@ -0,0 +1,783 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_marketState", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_resolver", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "CacheUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerNominated", + "type": "event" + }, + { + "constant": false, + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "accessibleMargin", + "outputs": [ + { + "internalType": "uint256", + "name": "marginAccessible", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "accruedFunding", + "outputs": [ + { + "internalType": "int256", + "name": "funding", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "assetPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "baseAsset", + "outputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "canLiquidate", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "currentFundingRate", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "currentFundingVelocity", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "int256", + "name": "sizeDelta", + "type": "int256" + } + ], + "name": "fillPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "fundingLastRecomputed", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "fundingSequence", + "outputs": [ + { + "internalType": "int128", + "name": "", + "type": "int128" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "fundingSequenceLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isResolverCached", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "liquidationFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "liquidationPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketKey", + "outputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketSize", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketSizes", + "outputs": [ + { + "internalType": "uint256", + "name": "long", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "short", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketSkew", + "outputs": [ + { + "internalType": "int128", + "name": "", + "type": "int128" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "marketState", + "outputs": [ + { + "internalType": "contract IPerpsV2MarketState", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "nominateNewOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "nominatedOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "notionalValue", + "outputs": [ + { + "internalType": "int256", + "name": "value", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "int256", + "name": "sizeDelta", + "type": "int256" + }, + { + "internalType": "enum IPerpsV2MarketBaseTypes.OrderType", + "name": "orderType", + "type": "uint8" + } + ], + "name": "orderFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "positions", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "lastFundingIndex", + "type": "uint64" + }, + { + "internalType": "uint128", + "name": "margin", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "lastPrice", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "size", + "type": "int128" + } + ], + "internalType": "struct IPerpsV2MarketBaseTypes.Position", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "int256", + "name": "sizeDelta", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "tradePrice", + "type": "uint256" + }, + { + "internalType": "enum IPerpsV2MarketBaseTypes.OrderType", + "name": "orderType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "postTradeDetails", + "outputs": [ + { + "internalType": "uint256", + "name": "margin", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "size", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liqPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "enum IPerpsV2MarketBaseTypes.Status", + "name": "status", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "profitLoss", + "outputs": [ + { + "internalType": "int256", + "name": "pnl", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "rebuildCache", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "remainingMargin", + "outputs": [ + { + "internalType": "uint256", + "name": "marginRemaining", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "resolver", + "outputs": [ + { + "internalType": "contract AddressResolver", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "resolverAddressesRequired", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "addresses", + "type": "bytes32[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "unrecordedFunding", + "outputs": [ + { + "internalType": "int256", + "name": "funding", + "type": "int256" + }, + { + "internalType": "bool", + "name": "invalid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/polynomial/contracts/abis/polynomial-smart-wallet-index.json b/src/apps/polynomial/contracts/abis/polynomial-smart-wallet-index.json new file mode 100644 index 000000000..2bb892f03 --- /dev/null +++ b/src/apps/polynomial/contracts/abis/polynomial-smart-wallet-index.json @@ -0,0 +1,151 @@ +[ + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "origin", "type": "address" } + ], + "name": "LogAccountCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "_newAccount", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "_check", "type": "address" } + ], + "name": "LogNewAccount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "accountVersion", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "check", "type": "address" } + ], + "name": "LogNewCheck", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "master", "type": "address" }], + "name": "LogNewMaster", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "master", "type": "address" }], + "name": "LogUpdateMaster", + "type": "event" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "account", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_newAccount", "type": "address" }, + { "internalType": "address", "name": "_check", "type": "address" } + ], + "name": "addNewAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" }, + { "internalType": "uint256", "name": "accountVersion", "type": "uint256" }, + { "internalType": "address", "name": "_origin", "type": "address" } + ], + "name": "build", + "outputs": [{ "internalType": "address", "name": "_account", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" }, + { "internalType": "uint256", "name": "accountVersion", "type": "uint256" }, + { "internalType": "address[]", "name": "_targets", "type": "address[]" }, + { "internalType": "bytes[]", "name": "_datas", "type": "bytes[]" }, + { "internalType": "address", "name": "_origin", "type": "address" } + ], + "name": "buildWithCast", + "outputs": [{ "internalType": "address", "name": "_account", "type": "address" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "accountVersion", "type": "uint256" }, + { "internalType": "address", "name": "_newCheck", "type": "address" } + ], + "name": "changeCheck", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_newMaster", "type": "address" }], + "name": "changeMaster", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "check", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "version", "type": "uint256" }, + { "internalType": "address", "name": "query", "type": "address" } + ], + "name": "isClone", + "outputs": [{ "internalType": "bool", "name": "result", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "list", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_master", "type": "address" }, + { "internalType": "address", "name": "_list", "type": "address" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "setBasics", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [], "name": "updateMaster", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "versionCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/apps/polynomial/contracts/viem.contract-factory.ts b/src/apps/polynomial/contracts/viem.contract-factory.ts index 8bef8c038..0876fc349 100644 --- a/src/apps/polynomial/contracts/viem.contract-factory.ts +++ b/src/apps/polynomial/contracts/viem.contract-factory.ts @@ -6,8 +6,10 @@ import { Network } from '~types/network.interface'; import { PolynomialAccountResolver__factory, PolynomialCoveredCall__factory, + PolynomialPerp__factory, PolynomialPutSelling__factory, PolynomialResolver__factory, + PolynomialSmartWalletIndex__factory, PolynomialVaultToken__factory, } from './viem'; @@ -23,12 +25,18 @@ export class PolynomialViemContractFactory { polynomialCoveredCall({ address, network }: ContractOpts) { return PolynomialCoveredCall__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); } + polynomialPerp({ address, network }: ContractOpts) { + return PolynomialPerp__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } polynomialPutSelling({ address, network }: ContractOpts) { return PolynomialPutSelling__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); } polynomialResolver({ address, network }: ContractOpts) { return PolynomialResolver__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); } + polynomialSmartWalletIndex({ address, network }: ContractOpts) { + return PolynomialSmartWalletIndex__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); + } polynomialVaultToken({ address, network }: ContractOpts) { return PolynomialVaultToken__factory.connect(address, this.appToolkit.getViemNetworkProvider(network)); } diff --git a/src/apps/polynomial/contracts/viem/PolynomialPerp.ts b/src/apps/polynomial/contracts/viem/PolynomialPerp.ts new file mode 100644 index 000000000..fe4ca5090 --- /dev/null +++ b/src/apps/polynomial/contracts/viem/PolynomialPerp.ts @@ -0,0 +1,797 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const polynomialPerpAbi = [ + { + inputs: [ + { + internalType: 'address', + name: '_marketState', + type: 'address', + }, + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + { + internalType: 'address', + name: '_resolver', + type: 'address', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'name', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + ], + name: 'CacheUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerNominated', + type: 'event', + }, + { + constant: false, + inputs: [], + name: 'acceptOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'accessibleMargin', + outputs: [ + { + internalType: 'uint256', + name: 'marginAccessible', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'accruedFunding', + outputs: [ + { + internalType: 'int256', + name: 'funding', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'assetPrice', + outputs: [ + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'baseAsset', + outputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'canLiquidate', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'currentFundingRate', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'currentFundingVelocity', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'int256', + name: 'sizeDelta', + type: 'int256', + }, + ], + name: 'fillPrice', + outputs: [ + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'fundingLastRecomputed', + outputs: [ + { + internalType: 'uint32', + name: '', + type: 'uint32', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'fundingSequence', + outputs: [ + { + internalType: 'int128', + name: '', + type: 'int128', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'fundingSequenceLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isResolverCached', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'liquidationFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'liquidationPrice', + outputs: [ + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketDebt', + outputs: [ + { + internalType: 'uint256', + name: 'debt', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketKey', + outputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketSize', + outputs: [ + { + internalType: 'uint128', + name: '', + type: 'uint128', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketSizes', + outputs: [ + { + internalType: 'uint256', + name: 'long', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'short', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketSkew', + outputs: [ + { + internalType: 'int128', + name: '', + type: 'int128', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'marketState', + outputs: [ + { + internalType: 'contract IPerpsV2MarketState', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + name: 'nominateNewOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'nominatedOwner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'notionalValue', + outputs: [ + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'int256', + name: 'sizeDelta', + type: 'int256', + }, + { + internalType: 'enum IPerpsV2MarketBaseTypes.OrderType', + name: 'orderType', + type: 'uint8', + }, + ], + name: 'orderFee', + outputs: [ + { + internalType: 'uint256', + name: 'fee', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'positions', + outputs: [ + { + components: [ + { + internalType: 'uint64', + name: 'id', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'lastFundingIndex', + type: 'uint64', + }, + { + internalType: 'uint128', + name: 'margin', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'lastPrice', + type: 'uint128', + }, + { + internalType: 'int128', + name: 'size', + type: 'int128', + }, + ], + internalType: 'struct IPerpsV2MarketBaseTypes.Position', + name: '', + type: 'tuple', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'int256', + name: 'sizeDelta', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'tradePrice', + type: 'uint256', + }, + { + internalType: 'enum IPerpsV2MarketBaseTypes.OrderType', + name: 'orderType', + type: 'uint8', + }, + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'postTradeDetails', + outputs: [ + { + internalType: 'uint256', + name: 'margin', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'size', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liqPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fee', + type: 'uint256', + }, + { + internalType: 'enum IPerpsV2MarketBaseTypes.Status', + name: 'status', + type: 'uint8', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'profitLoss', + outputs: [ + { + internalType: 'int256', + name: 'pnl', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'rebuildCache', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'remainingMargin', + outputs: [ + { + internalType: 'uint256', + name: 'marginRemaining', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'resolver', + outputs: [ + { + internalType: 'contract AddressResolver', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'resolverAddressesRequired', + outputs: [ + { + internalType: 'bytes32[]', + name: 'addresses', + type: 'bytes32[]', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'unrecordedFunding', + outputs: [ + { + internalType: 'int256', + name: 'funding', + type: 'int256', + }, + { + internalType: 'bool', + name: 'invalid', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type PolynomialPerp = typeof polynomialPerpAbi; +export type PolynomialPerpContract = GetContractReturnType; + +export class PolynomialPerp__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: polynomialPerpAbi, publicClient: client }); + } +} diff --git a/src/apps/polynomial/contracts/viem/PolynomialSmartWalletIndex.ts b/src/apps/polynomial/contracts/viem/PolynomialSmartWalletIndex.ts new file mode 100644 index 000000000..01642afcc --- /dev/null +++ b/src/apps/polynomial/contracts/viem/PolynomialSmartWalletIndex.ts @@ -0,0 +1,359 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { getContract, GetContractReturnType, PublicClient } from 'viem'; + +export const polynomialSmartWalletIndexAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'origin', + type: 'address', + }, + ], + name: 'LogAccountCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_newAccount', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: '_check', + type: 'address', + }, + ], + name: 'LogNewAccount', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'accountVersion', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'check', + type: 'address', + }, + ], + name: 'LogNewCheck', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'master', + type: 'address', + }, + ], + name: 'LogNewMaster', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'master', + type: 'address', + }, + ], + name: 'LogUpdateMaster', + type: 'event', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'account', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newAccount', + type: 'address', + }, + { + internalType: 'address', + name: '_check', + type: 'address', + }, + ], + name: 'addNewAccount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + { + internalType: 'uint256', + name: 'accountVersion', + type: 'uint256', + }, + { + internalType: 'address', + name: '_origin', + type: 'address', + }, + ], + name: 'build', + outputs: [ + { + internalType: 'address', + name: '_account', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + { + internalType: 'uint256', + name: 'accountVersion', + type: 'uint256', + }, + { + internalType: 'address[]', + name: '_targets', + type: 'address[]', + }, + { + internalType: 'bytes[]', + name: '_datas', + type: 'bytes[]', + }, + { + internalType: 'address', + name: '_origin', + type: 'address', + }, + ], + name: 'buildWithCast', + outputs: [ + { + internalType: 'address', + name: '_account', + type: 'address', + }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'accountVersion', + type: 'uint256', + }, + { + internalType: 'address', + name: '_newCheck', + type: 'address', + }, + ], + name: 'changeCheck', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newMaster', + type: 'address', + }, + ], + name: 'changeMaster', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'check', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'version', + type: 'uint256', + }, + { + internalType: 'address', + name: 'query', + type: 'address', + }, + ], + name: 'isClone', + outputs: [ + { + internalType: 'bool', + name: 'result', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'list', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'master', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_master', + type: 'address', + }, + { + internalType: 'address', + name: '_list', + type: 'address', + }, + { + internalType: 'address', + name: '_account', + type: 'address', + }, + ], + name: 'setBasics', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'updateMaster', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'versionCount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; + +export type PolynomialSmartWalletIndex = typeof polynomialSmartWalletIndexAbi; +export type PolynomialSmartWalletIndexContract = GetContractReturnType; + +export class PolynomialSmartWalletIndex__factory { + static connect(address: string, client: PublicClient) { + return getContract({ address, abi: polynomialSmartWalletIndexAbi, publicClient: client }); + } +} diff --git a/src/apps/polynomial/contracts/viem/index.ts b/src/apps/polynomial/contracts/viem/index.ts index a52b05d4a..b30613d60 100644 --- a/src/apps/polynomial/contracts/viem/index.ts +++ b/src/apps/polynomial/contracts/viem/index.ts @@ -4,12 +4,16 @@ export type { PolynomialAccountResolver } from './PolynomialAccountResolver'; export type { PolynomialCoveredCall } from './PolynomialCoveredCall'; +export type { PolynomialPerp } from './PolynomialPerp'; export type { PolynomialPutSelling } from './PolynomialPutSelling'; export type { PolynomialResolver } from './PolynomialResolver'; +export type { PolynomialSmartWalletIndex } from './PolynomialSmartWalletIndex'; export type { PolynomialVaultToken } from './PolynomialVaultToken'; export { PolynomialAccountResolver__factory } from './PolynomialAccountResolver'; export { PolynomialCoveredCall__factory } from './PolynomialCoveredCall'; +export { PolynomialPerp__factory } from './PolynomialPerp'; export { PolynomialPutSelling__factory } from './PolynomialPutSelling'; export { PolynomialResolver__factory } from './PolynomialResolver'; +export { PolynomialSmartWalletIndex__factory } from './PolynomialSmartWalletIndex'; export { PolynomialVaultToken__factory } from './PolynomialVaultToken'; diff --git a/src/apps/polynomial/optimism/polynomial.perp.contract-position-fetcher.ts b/src/apps/polynomial/optimism/polynomial.perp.contract-position-fetcher.ts index f807375d6..cbd43b500 100644 --- a/src/apps/polynomial/optimism/polynomial.perp.contract-position-fetcher.ts +++ b/src/apps/polynomial/optimism/polynomial.perp.contract-position-fetcher.ts @@ -1,27 +1,109 @@ import { Inject } from '@nestjs/common'; +import { sumBy } from 'lodash'; import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; +import { ZERO_ADDRESS } from '~app-toolkit/constants/address'; import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; +import { drillBalance } from '~app-toolkit/helpers/drill-balance.helper'; +import { KwentaPerp } from '~apps/kwenta/contracts/viem'; +import { ContractType } from '~position/contract.interface'; +import { ContractPositionBalance } from '~position/position-balance.interface'; +import { MetaType } from '~position/position.interface'; +import { + GetDisplayPropsParams, + GetTokenBalancesParams, + GetTokenDefinitionsParams, + UnderlyingTokenDefinition, +} from '~position/template/contract-position.template.types'; +import { CustomContractPositionTemplatePositionFetcher } from '~position/template/custom-contract-position.template.position-fetcher'; -import { SynthetixViemContractFactory } from '../../synthetix/contracts'; -import { OptimismSynthetixPerpV2ContractPositionFetcher } from '../../synthetix/optimism/synthetix.perp-v2.contract-position-fetcher'; import { PolynomialAccountResolver } from '../common/polynomial.account-resolver'; import { PolynomialViemContractFactory } from '../contracts'; @PositionTemplate() -export class OptimismPolynomialPerpContractPositionFetcher extends OptimismSynthetixPerpV2ContractPositionFetcher { +export class OptimismPolynomialPerpContractPositionFetcher extends CustomContractPositionTemplatePositionFetcher { groupLabel = 'Perp'; constructor( @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, - @Inject(SynthetixViemContractFactory) protected readonly synthetixContractFactory: SynthetixViemContractFactory, - @Inject(PolynomialViemContractFactory) protected readonly polynomialContractFactory: PolynomialViemContractFactory, + @Inject(PolynomialViemContractFactory) protected readonly contractFactory: PolynomialViemContractFactory, @Inject(PolynomialAccountResolver) protected readonly polynomialAccountResolver: PolynomialAccountResolver, ) { - super(appToolkit, synthetixContractFactory); + super(appToolkit); } - async getAccountAddress(address: string): Promise { + getContract(address: string) { + return this.contractFactory.polynomialPerp({ address, network: this.network }); + } + + async getDefinitions() { + return []; // Resolve from Synthetix + } + + async getLabel(_params: GetDisplayPropsParams): Promise { + throw new Error('Method not implemented.'); + } + + async getTokenDefinitions(_params: GetTokenDefinitionsParams): Promise { + throw new Error('Method not implemented.'); + } + + async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams) { + const remainingMargin = await contract.read.remainingMargin([address]); + return [remainingMargin[0]]; + } + + async getMarginAccountAddress(address: string): Promise { return this.polynomialAccountResolver.getSmartWalletAddress(address); } + + async getBalances(address: string): Promise { + const multicall = this.appToolkit.getViemMulticall(this.network); + if (address === ZERO_ADDRESS) return []; + + const marginAccountAddress = await this.getMarginAccountAddress(address); + if (marginAccountAddress === ZERO_ADDRESS) return []; + + const contractPositions = await this.appToolkit.getAppContractPositions({ + appId: 'synthetix', + network: this.network, + groupIds: ['perp-v2'], + }); + + const balances = await Promise.all( + contractPositions.map(async contractPosition => { + const contract = multicall.wrap(this.getContract(contractPosition.address)); + const balancesRaw = await this.getTokenBalancesPerPosition({ + address: marginAccountAddress, + contract, + contractPosition, + multicall, + }); + + const allTokens = contractPosition.tokens.map((cp, idx) => + drillBalance(cp, balancesRaw[idx]?.toString() ?? '0', { isDebt: cp.metaType === MetaType.BORROWED }), + ); + + const tokens = allTokens.filter(v => Math.abs(v.balanceUSD) > 0.01); + const balanceUSD = sumBy(tokens, t => t.balanceUSD); + + const balance: ContractPositionBalance = { + type: ContractType.POSITION, + address: marginAccountAddress, + network: this.network, + appId: this.appId, + groupId: this.groupId, + groupLabel: this.groupLabel, + tokens, + dataProps: contractPosition.dataProps, + displayProps: contractPosition.displayProps, + balanceUSD, + }; + + return balance; + }), + ); + + return balances; + } } diff --git a/src/apps/polynomial/optimism/polynomial.smart-wallet.contract-position-fetcher.ts b/src/apps/polynomial/optimism/polynomial.smart-wallet.contract-position-fetcher.ts index f8dda510b..8fd195405 100644 --- a/src/apps/polynomial/optimism/polynomial.smart-wallet.contract-position-fetcher.ts +++ b/src/apps/polynomial/optimism/polynomial.smart-wallet.contract-position-fetcher.ts @@ -1,47 +1,57 @@ import { Inject } from '@nestjs/common'; +import { sumBy } from 'lodash'; import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; +import { ZERO_ADDRESS } from '~app-toolkit/constants/address'; import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; -import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; -import { Erc20 } from '~contract/contracts/viem'; +import { drillBalance } from '~app-toolkit/helpers/drill-balance.helper'; +import { ContractType } from '~position/contract.interface'; +import { ContractPositionBalance } from '~position/position-balance.interface'; import { MetaType } from '~position/position.interface'; -import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher'; import { DefaultContractPositionDefinition, GetDisplayPropsParams, GetTokenBalancesParams, + GetTokenDefinitionsParams, + UnderlyingTokenDefinition, } from '~position/template/contract-position.template.types'; +import { CustomContractPositionTemplatePositionFetcher } from '~position/template/custom-contract-position.template.position-fetcher'; import { PolynomialAccountResolver } from '../common/polynomial.account-resolver'; +import { PolynomialViemContractFactory } from '../contracts'; +import { PolynomialSmartWalletIndex } from '../contracts/viem'; export type PolynomialSmartWalletDataProp = { liquidity: number; }; @PositionTemplate() -export class OptimismPolynomialSmartWalletContractPositionFetcher extends ContractPositionTemplatePositionFetcher { +export class OptimismPolynomialSmartWalletContractPositionFetcher extends CustomContractPositionTemplatePositionFetcher { groupLabel = 'Smart Wallet'; constructor( @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, + @Inject(PolynomialViemContractFactory) protected readonly contractFactory: PolynomialViemContractFactory, @Inject(PolynomialAccountResolver) protected readonly polynomialAccountResolver: PolynomialAccountResolver, ) { super(appToolkit); } getContract(address: string) { - return this.appToolkit.globalViemContracts.erc20({ address: address, network: this.network }); + return this.contractFactory.polynomialSmartWalletIndex({ address, network: this.network }); } async getDefinitions(): Promise { return [{ address: '0xb43c0899eccf98bc7a0f3e2c2a211d6fc4f9b3fe' }]; } - async getLabel({ contractPosition }: GetDisplayPropsParams): Promise { - return getLabelFromToken(contractPosition.tokens[0]); + async getLabel(_params: GetDisplayPropsParams): Promise { + return `Smart Wallet Balances`; } - async getTokenDefinitions() { + async getTokenDefinitions( + _params: GetTokenDefinitionsParams, + ): Promise { return [ '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9', //sUSD '0x7f5c764cbc14f9669b88837ca1490cca17c31607', //USDC @@ -51,11 +61,11 @@ export class OptimismPolynomialSmartWalletContractPositionFetcher extends Contra ].map(address => ({ metaType: MetaType.SUPPLIED, address, network: this.network })); } - async getAccountAddress(address: string): Promise { - return this.polynomialAccountResolver.getSmartWalletAddress(address); - } - - async getTokenBalancesPerPosition({ address, multicall, contractPosition }: GetTokenBalancesParams) { + async getTokenBalancesPerPosition({ + address, + multicall, + contractPosition, + }: GetTokenBalancesParams) { return await Promise.all( contractPosition.tokens.map(token => { const contract = this.appToolkit.globalViemContracts.erc20({ address: token.address, network: this.network }); @@ -63,4 +73,55 @@ export class OptimismPolynomialSmartWalletContractPositionFetcher extends Contra }), ); } + + async getSmartWalletAddress(address: string): Promise { + return this.polynomialAccountResolver.getSmartWalletAddress(address); + } + + async getBalances(address: string): Promise { + const multicall = this.appToolkit.getViemMulticall(this.network); + if (address === ZERO_ADDRESS) return []; + + const smartWalletAddress = await this.getSmartWalletAddress(address); + if (smartWalletAddress === ZERO_ADDRESS) return []; + + const contractPositions = await this.appToolkit.getAppContractPositions({ + appId: this.appId, + network: this.network, + groupIds: [this.groupId], + }); + + if (contractPositions.length === 0) return []; + const contractPosition = contractPositions[0]; + + const contract = multicall.wrap(this.getContract(contractPosition.address)); + const balancesRaw = await this.getTokenBalancesPerPosition({ + address: smartWalletAddress, + contract, + contractPosition, + multicall, + }); + + const allTokens = contractPosition.tokens.map((cp, idx) => + drillBalance(cp, balancesRaw[idx]?.toString() ?? '0', { isDebt: cp.metaType === MetaType.BORROWED }), + ); + + const tokens = allTokens.filter(v => Math.abs(v.balanceUSD) > 0.01); + const balanceUSD = sumBy(tokens, t => t.balanceUSD); + + const balance: ContractPositionBalance = { + type: ContractType.POSITION, + address: smartWalletAddress, + network: this.network, + appId: this.appId, + groupId: this.groupId, + groupLabel: this.groupLabel, + tokens, + dataProps: contractPosition.dataProps, + displayProps: contractPosition.displayProps, + balanceUSD, + }; + + return [balance]; + } } diff --git a/src/apps/synthetix/optimism/synthetix.perp.contract-position-fetcher.ts b/src/apps/synthetix/optimism/synthetix.perp.contract-position-fetcher.ts index 233d0491f..f2eac26d3 100644 --- a/src/apps/synthetix/optimism/synthetix.perp.contract-position-fetcher.ts +++ b/src/apps/synthetix/optimism/synthetix.perp.contract-position-fetcher.ts @@ -8,7 +8,11 @@ import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; import { DefaultDataProps } from '~position/display.interface'; import { MetaType } from '~position/position.interface'; import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher'; -import { GetDisplayPropsParams, GetTokenBalancesParams } from '~position/template/contract-position.template.types'; +import { + GetDataPropsParams, + GetDisplayPropsParams, + GetTokenBalancesParams, +} from '~position/template/contract-position.template.types'; import { SynthetixViemContractFactory } from '../contracts'; import { SynthetixPerp } from '../contracts/viem'; @@ -38,9 +42,13 @@ export type SynthetixPerpPositionDefinition = { asset: string; }; +export type SynthetixPerpDataProps = DefaultDataProps & { + asset: string; +}; + export abstract class OptimismSynthetixPerpContractPositionFetcher extends ContractPositionTemplatePositionFetcher< SynthetixPerp, - DefaultDataProps, + SynthetixPerpDataProps, SynthetixPerpPositionDefinition > { useCustomMarketLogos = false; @@ -91,16 +99,23 @@ export abstract class OptimismSynthetixPerpContractPositionFetcher extends Contr ]; } + async getDataProps( + params: GetDataPropsParams, + ) { + const defaultDataProps = await super.getDataProps(params); + return { ...defaultDataProps, asset: params.definition.asset }; + } + async getLabel({ definition, - }: GetDisplayPropsParams): Promise { + }: GetDisplayPropsParams): Promise { return `${definition.asset}-PERP`; } async getImages({ definition, - }: GetDisplayPropsParams) { - return [getAppAssetImage(this.useCustomMarketLogos ? this.appId : 'synthetix', `s${definition.asset}`)]; + }: GetDisplayPropsParams) { + return [getAppAssetImage(this.appId, `s${definition.asset}`)]; } async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams) { diff --git a/src/position/template/app-token.template.position-fetcher.ts b/src/position/template/app-token.template.position-fetcher.ts index 1123c0151..7e8a8721b 100644 --- a/src/position/template/app-token.template.position-fetcher.ts +++ b/src/position/template/app-token.template.position-fetcher.ts @@ -305,10 +305,6 @@ export abstract class AppTokenTemplatePositionFetcher< return this.getPositionsForBatch(definitions); } - async getAccountAddress(address: string) { - return address; - } - async getPositionsForBalances() { return this.appToolkit.getAppTokenPositions({ appId: this.appId, @@ -330,9 +326,8 @@ export abstract class AppTokenTemplatePositionFetcher< return multicall.wrap(erc20).read.balanceOf([address]); } - async getBalances(_address: string): Promise[]> { + async getBalances(address: string): Promise[]> { const multicall = this.appToolkit.getViemMulticall(this.network); - const address = await this.getAccountAddress(_address); const appTokens = await this.getPositionsForBalances(); if ([DEAD_ADDRESS, ZERO_ADDRESS].includes(address)) return []; @@ -347,9 +342,8 @@ export abstract class AppTokenTemplatePositionFetcher< return balances as AppTokenPositionBalance[]; } - async getRawBalances(_address: string): Promise { + async getRawBalances(address: string): Promise { const multicall = this.appToolkit.getViemMulticall(this.network); - const address = await this.getAccountAddress(_address); if (address === ZERO_ADDRESS) return []; const appTokens = await this.getPositionsForBalances(); diff --git a/src/position/template/contract-position.template.position-fetcher.ts b/src/position/template/contract-position.template.position-fetcher.ts index a6533f607..cb2020035 100644 --- a/src/position/template/contract-position.template.position-fetcher.ts +++ b/src/position/template/contract-position.template.position-fetcher.ts @@ -200,10 +200,6 @@ export abstract class ContractPositionTemplatePositionFetcher< return tokens; } - async getAccountAddress(address: string) { - return address; - } - async getPositionsForBalances() { return this.appToolkit.getAppContractPositions({ appId: this.appId, @@ -223,9 +219,8 @@ export abstract class ContractPositionTemplatePositionFetcher< multicall, }: GetTokenBalancesParams): Promise; - async getBalances(_address: string): Promise[]> { + async getBalances(address: string): Promise[]> { const multicall = this.appToolkit.getViemMulticall(this.network); - const address = await this.getAccountAddress(_address); if (address === ZERO_ADDRESS) return []; const contractPositions = await this.getPositionsForBalances(); @@ -250,9 +245,8 @@ export abstract class ContractPositionTemplatePositionFetcher< return balances; } - async getRawBalances(_address: string): Promise { + async getRawBalances(address: string): Promise { const multicall = this.appToolkit.getViemMulticall(this.network); - const address = await this.getAccountAddress(_address); if (address === ZERO_ADDRESS) return []; const contractPositions = await this.getPositionsForBalances();