From 71d21f215975803b05a6ef23bf0939127ad79b73 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Wed, 15 Nov 2023 15:04:41 +0700 Subject: [PATCH 1/3] wip --- pkg/source/rollup-finance/abis.go | 42 + .../rollup-finance/abis/ChainlinkFlags.json | 21 + pkg/source/rollup-finance/abis/ERC20.json | 222 ++ .../rollup-finance/abis/FastPriceFeedV1.json | 788 ++++ .../rollup-finance/abis/FastPriceFeedV2.json | 1144 ++++++ .../rollup-finance/abis/PancakePair.json | 27 + pkg/source/rollup-finance/abis/PriceFeed.json | 509 +++ pkg/source/rollup-finance/abis/Vault.json | 3213 +++++++++++++++++ .../rollup-finance/abis/VaultPriceFeed.json | 888 +++++ pkg/source/rollup-finance/chainlink_flags.go | 13 + .../rollup-finance/chainlink_flags_reader.go | 51 + pkg/source/rollup-finance/config.go | 7 + pkg/source/rollup-finance/constants.go | 16 + pkg/source/rollup-finance/embed.go | 27 + pkg/source/rollup-finance/errors.go | 18 + .../rollup-finance/fast_price_feed_v1.go | 118 + .../fast_price_feed_v1_reader.go | 107 + .../rollup-finance/fast_price_feed_v2.go | 137 + .../fast_price_feed_v2_reader.go | 112 + pkg/source/rollup-finance/helper.go | 17 + pkg/source/rollup-finance/iface.go | 50 + pkg/source/rollup-finance/pancake_pair.go | 20 + .../rollup-finance/pancake_pair_reader.go | 57 + pkg/source/rollup-finance/pool_simulator.go | 224 ++ pkg/source/rollup-finance/pool_tracker.go | 74 + .../rollup-finance/pools_list_updater.go | 79 + pkg/source/rollup-finance/price_feed.go | 46 + .../rollup-finance/price_feed_reader.go | 95 + pkg/source/rollup-finance/types.go | 18 + pkg/source/rollup-finance/usdr.go | 14 + pkg/source/rollup-finance/usdr_reader.go | 49 + pkg/source/rollup-finance/vault.go | 144 + pkg/source/rollup-finance/vault_price_feed.go | 476 +++ .../rollup-finance/vault_price_feed_reader.go | 156 + pkg/source/rollup-finance/vault_reader.go | 173 + pkg/source/rollup-finance/vault_scanner.go | 182 + pkg/source/rollup-finance/vault_utils.go | 103 + 37 files changed, 9437 insertions(+) create mode 100644 pkg/source/rollup-finance/abis.go create mode 100644 pkg/source/rollup-finance/abis/ChainlinkFlags.json create mode 100644 pkg/source/rollup-finance/abis/ERC20.json create mode 100644 pkg/source/rollup-finance/abis/FastPriceFeedV1.json create mode 100644 pkg/source/rollup-finance/abis/FastPriceFeedV2.json create mode 100644 pkg/source/rollup-finance/abis/PancakePair.json create mode 100644 pkg/source/rollup-finance/abis/PriceFeed.json create mode 100644 pkg/source/rollup-finance/abis/Vault.json create mode 100644 pkg/source/rollup-finance/abis/VaultPriceFeed.json create mode 100644 pkg/source/rollup-finance/chainlink_flags.go create mode 100644 pkg/source/rollup-finance/chainlink_flags_reader.go create mode 100644 pkg/source/rollup-finance/config.go create mode 100644 pkg/source/rollup-finance/constants.go create mode 100644 pkg/source/rollup-finance/embed.go create mode 100644 pkg/source/rollup-finance/errors.go create mode 100644 pkg/source/rollup-finance/fast_price_feed_v1.go create mode 100644 pkg/source/rollup-finance/fast_price_feed_v1_reader.go create mode 100644 pkg/source/rollup-finance/fast_price_feed_v2.go create mode 100644 pkg/source/rollup-finance/fast_price_feed_v2_reader.go create mode 100644 pkg/source/rollup-finance/helper.go create mode 100644 pkg/source/rollup-finance/iface.go create mode 100644 pkg/source/rollup-finance/pancake_pair.go create mode 100644 pkg/source/rollup-finance/pancake_pair_reader.go create mode 100644 pkg/source/rollup-finance/pool_simulator.go create mode 100644 pkg/source/rollup-finance/pool_tracker.go create mode 100644 pkg/source/rollup-finance/pools_list_updater.go create mode 100644 pkg/source/rollup-finance/price_feed.go create mode 100644 pkg/source/rollup-finance/price_feed_reader.go create mode 100644 pkg/source/rollup-finance/types.go create mode 100644 pkg/source/rollup-finance/usdr.go create mode 100644 pkg/source/rollup-finance/usdr_reader.go create mode 100644 pkg/source/rollup-finance/vault.go create mode 100644 pkg/source/rollup-finance/vault_price_feed.go create mode 100644 pkg/source/rollup-finance/vault_price_feed_reader.go create mode 100644 pkg/source/rollup-finance/vault_reader.go create mode 100644 pkg/source/rollup-finance/vault_scanner.go create mode 100644 pkg/source/rollup-finance/vault_utils.go diff --git a/pkg/source/rollup-finance/abis.go b/pkg/source/rollup-finance/abis.go new file mode 100644 index 000000000..bc4967276 --- /dev/null +++ b/pkg/source/rollup-finance/abis.go @@ -0,0 +1,42 @@ +package gmx + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +var ( + chainlinkABI abi.ABI + fastPriceFeedV1ABI abi.ABI + fastPriceFeedV2ABI abi.ABI + pancakePairABI abi.ABI + priceFeedABI abi.ABI + vaultABI abi.ABI + vaultPriceFeedABI abi.ABI + erc20ABI abi.ABI +) + +func init() { + builder := []struct { + ABI *abi.ABI + data []byte + }{ + {&chainlinkABI, chainlinkFlagsJson}, + {&fastPriceFeedV1ABI, fastPriceFeedV1Json}, + {&fastPriceFeedV2ABI, fastPriceFeedV2Json}, + {&pancakePairABI, pancakePairJson}, + {&priceFeedABI, priceFeedJson}, + {&vaultABI, vaultJson}, + {&vaultPriceFeedABI, vaultPriceFeedJson}, + {&erc20ABI, erc20Json}, + } + + for _, b := range builder { + var err error + *b.ABI, err = abi.JSON(bytes.NewReader(b.data)) + if err != nil { + panic(err) + } + } +} diff --git a/pkg/source/rollup-finance/abis/ChainlinkFlags.json b/pkg/source/rollup-finance/abis/ChainlinkFlags.json new file mode 100644 index 000000000..e820885c5 --- /dev/null +++ b/pkg/source/rollup-finance/abis/ChainlinkFlags.json @@ -0,0 +1,21 @@ +[ + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "getFlag", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/abis/ERC20.json b/pkg/source/rollup-finance/abis/ERC20.json new file mode 100644 index 000000000..3b0ab2f1a --- /dev/null +++ b/pkg/source/rollup-finance/abis/ERC20.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/abis/FastPriceFeedV1.json b/pkg/source/rollup-finance/abis/FastPriceFeedV1.json new file mode 100644 index 000000000..30ecc19e5 --- /dev/null +++ b/pkg/source/rollup-finance/abis/FastPriceFeedV1.json @@ -0,0 +1,788 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minBlockInterval", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDeviationBasisPoints", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_fastPriceEvents", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_positionRouter", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "DisableFastPrice", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "EnableFastPrice", + "type": "event" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PRICE_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_BITMASK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableFastPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disableFastPriceVoteCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "disableFastPriceVotes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "enableFastPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "fastPriceEvents", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "favorFastPrice", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_refPrice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minAuthorizations", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_signers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_updaters", + "type": "address[]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isSigner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isSpreadEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isUpdater", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdatedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdatedBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxDeviationBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxTimeDeviation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAuthorizations", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBlockInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "positionRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_priceBitArray", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "setCompactedPrices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fastPriceEvents", + "type": "address" + } + ], + "name": "setFastPriceEvents", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gov", + "type": "address" + } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isSpreadEnabled", + "type": "bool" + } + ], + "name": "setIsSpreadEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_lastUpdatedAt", + "type": "uint256" + } + ], + "name": "setLastUpdatedAt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxDeviationBasisPoints", + "type": "uint256" + } + ], + "name": "setMaxDeviationBasisPoints", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxTimeDeviation", + "type": "uint256" + } + ], + "name": "setMaxTimeDeviation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minAuthorizations", + "type": "uint256" + } + ], + "name": "setMinAuthorizations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBlockInterval", + "type": "uint256" + } + ], + "name": "setMinBlockInterval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceDuration", + "type": "uint256" + } + ], + "name": "setPriceDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_prices", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "setPrices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceBits", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "setPricesWithBits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceBits", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_endIndexForIncreasePositions", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_endIndexForDecreasePositions", + "type": "uint256" + } + ], + "name": "setPricesWithBitsAndExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenManager", + "type": "address" + } + ], + "name": "setTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_tokenPrecisions", + "type": "uint256[]" + } + ], + "name": "setTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setUpdater", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_volBasisPoints", + "type": "uint256" + } + ], + "name": "setVolBasisPoints", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenPrecisions", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/abis/FastPriceFeedV2.json b/pkg/source/rollup-finance/abis/FastPriceFeedV2.json new file mode 100644 index 000000000..27cb26319 --- /dev/null +++ b/pkg/source/rollup-finance/abis/FastPriceFeedV2.json @@ -0,0 +1,1144 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxPriceUpdateDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minBlockInterval", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDeviationBasisPoints", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_fastPriceEvents", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_positionRouter", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "DisableFastPrice", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "EnableFastPrice", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "refPrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fastPrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cumulativeRefDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cumulativeFastDelta", + "type": "uint256" + } + ], + "name": "MaxCumulativeDeltaDiffExceeded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "refPrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fastPrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cumulativeRefDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cumulativeFastDelta", + "type": "uint256" + } + ], + "name": "PriceData", + "type": "event" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BITMASK_32", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CUMULATIVE_DELTA_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_CUMULATIVE_FAST_DELTA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_CUMULATIVE_REF_DELTA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PRICE_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REF_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableFastPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disableFastPriceVoteCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "disableFastPriceVotes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "enableFastPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "fastPriceEvents", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "favorFastPrice", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_refPrice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getPriceData", + "outputs": [ + { + "internalType": "uint256", + "name": "refPrice", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "refTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "cumulativeRefDelta", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "cumulativeFastDelta", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minAuthorizations", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_signers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_updaters", + "type": "address[]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isSigner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isSpreadEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isUpdater", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdatedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdatedBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxCumulativeDeltaDiffs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxDeviationBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxPriceUpdateDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxTimeDeviation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAuthorizations", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBlockInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "positionRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "priceData", + "outputs": [ + { + "internalType": "uint160", + "name": "refPrice", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "refTime", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "cumulativeRefDelta", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "cumulativeFastDelta", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceDataInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_priceBitArray", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "setCompactedPrices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fastPriceEvents", + "type": "address" + } + ], + "name": "setFastPriceEvents", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gov", + "type": "address" + } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isSpreadEnabled", + "type": "bool" + } + ], + "name": "setIsSpreadEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_lastUpdatedAt", + "type": "uint256" + } + ], + "name": "setLastUpdatedAt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_maxCumulativeDeltaDiffs", + "type": "uint256[]" + } + ], + "name": "setMaxCumulativeDeltaDiffs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxDeviationBasisPoints", + "type": "uint256" + } + ], + "name": "setMaxDeviationBasisPoints", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxPriceUpdateDelay", + "type": "uint256" + } + ], + "name": "setMaxPriceUpdateDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxTimeDeviation", + "type": "uint256" + } + ], + "name": "setMaxTimeDeviation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minAuthorizations", + "type": "uint256" + } + ], + "name": "setMinAuthorizations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBlockInterval", + "type": "uint256" + } + ], + "name": "setMinBlockInterval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceDataInterval", + "type": "uint256" + } + ], + "name": "setPriceDataInterval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceDuration", + "type": "uint256" + } + ], + "name": "setPriceDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_prices", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "setPrices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceBits", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "setPricesWithBits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceBits", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_endIndexForIncreasePositions", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_endIndexForDecreasePositions", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxIncreasePositions", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDecreasePositions", + "type": "uint256" + } + ], + "name": "setPricesWithBitsAndExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_spreadBasisPointsIfChainError", + "type": "uint256" + } + ], + "name": "setSpreadBasisPointsIfChainError", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_spreadBasisPointsIfInactive", + "type": "uint256" + } + ], + "name": "setSpreadBasisPointsIfInactive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenManager", + "type": "address" + } + ], + "name": "setTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_tokenPrecisions", + "type": "uint256[]" + } + ], + "name": "setTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setUpdater", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vaultPriceFeed", + "type": "address" + } + ], + "name": "setVaultPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "spreadBasisPointsIfChainError", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "spreadBasisPointsIfInactive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenPrecisions", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultPriceFeed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/abis/PancakePair.json b/pkg/source/rollup-finance/abis/PancakePair.json new file mode 100644 index 000000000..00fc4365d --- /dev/null +++ b/pkg/source/rollup-finance/abis/PancakePair.json @@ -0,0 +1,27 @@ +[ + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/abis/PriceFeed.json b/pkg/source/rollup-finance/abis/PriceFeed.json new file mode 100644 index 000000000..f89fce1ab --- /dev/null +++ b/pkg/source/rollup-finance/abis/PriceFeed.json @@ -0,0 +1,509 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessController", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "int256", + "name": "current", + "type": "int256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + } + ], + "name": "AnswerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "startedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + } + ], + "name": "NewRound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessController", + "outputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aggregator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + } + ], + "name": "confirmAggregator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_roundId", + "type": "uint256" + } + ], + "name": "getAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "getRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_roundId", + "type": "uint256" + } + ], + "name": "getTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRound", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "phaseAggregators", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "phaseId", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + } + ], + "name": "proposeAggregator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proposedAggregator", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "proposedGetRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposedLatestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accessController", + "type": "address" + } + ], + "name": "setController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/abis/Vault.json b/pkg/source/rollup-finance/abis/Vault.json new file mode 100644 index 000000000..f6ef658a9 --- /dev/null +++ b/pkg/source/rollup-finance/abis/Vault.json @@ -0,0 +1,3213 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "usdrAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeBasisPoints", + "type": "uint256" + } + ], + "name": "BuyUSDR", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "size", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "averagePrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "entryFundingRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserveAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "realisedPnl", + "type": "int256" + } + ], + "name": "ClosePosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeUsd", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeTokens", + "type": "uint256" + } + ], + "name": "CollectMarginFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeUsd", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeTokens", + "type": "uint256" + } + ], + "name": "CollectSwapFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DecreaseGuaranteedUsd", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DecreasePoolAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "collateralToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "indexToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateralDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sizeDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isLong", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "DecreasePosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DecreaseReservedAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DecreaseUsdrAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DirectPoolDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "IncreaseGuaranteedUsd", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "IncreasePoolAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "collateralToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "indexToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateralDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sizeDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isLong", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "IncreasePosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "IncreaseReservedAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "IncreaseUsdrAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "collateralToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "indexToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isLong", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "size", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserveAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "realisedPnl", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "markPrice", + "type": "uint256" + } + ], + "name": "LiquidatePosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "usdrAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeBasisPoints", + "type": "uint256" + } + ], + "name": "SellUSDR", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOutAfterFees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeBasisPoints", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fundingRate", + "type": "uint256" + } + ], + "name": "UpdateFundingRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "hasProfit", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "delta", + "type": "uint256" + } + ], + "name": "UpdatePnl", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "size", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "averagePrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "entryFundingRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserveAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "realisedPnl", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "markPrice", + "type": "uint256" + } + ], + "name": "UpdatePosition", + "type": "event" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FUNDING_RATE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE_BASIS_POINTS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FUNDING_RATE_FACTOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LIQUIDATION_FEE_USD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_FUNDING_RATE_INTERVAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_LEVERAGE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDR_DECIMALS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_router", + "type": "address" + } + ], + "name": "addRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_tokenDiv", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenMul", + "type": "address" + } + ], + "name": "adjustForDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allWhitelistedTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allWhitelistedTokensLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "approvedRouters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bufferAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "buyUSDR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "clearTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "cumulativeFundingRates", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_collateralDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "decreasePosition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "directPoolDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "errorController", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "errors", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "feeReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fundingInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fundingRateFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_averagePrice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_lastIncreasedTime", + "type": "uint256" + } + ], + "name": "getDelta", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + } + ], + "name": "getEntryFundingRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdrDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_feeBasisPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_taxBasisPoints", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_increment", + "type": "bool" + } + ], + "name": "getFeeBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_entryFundingRate", + "type": "uint256" + } + ], + "name": "getFundingFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getGlobalShortDelta", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getMaxPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getMinPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_averagePrice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_nextPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lastIncreasedTime", + "type": "uint256" + } + ], + "name": "getNextAveragePrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getNextFundingRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_nextPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + } + ], + "name": "getNextGlobalShortAveragePrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + } + ], + "name": "getPosition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + } + ], + "name": "getPositionDelta", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + } + ], + "name": "getPositionFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + } + ], + "name": "getPositionKey", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + } + ], + "name": "getPositionLeverage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdrAmount", + "type": "uint256" + } + ], + "name": "getRedemptionAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getRedemptionCollateral", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getRedemptionCollateralUsd", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getTargetUsdrAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getUtilisation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "globalShortAveragePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "globalShortSizes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "guaranteedUsd", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hasDynamicFees", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inManagerMode", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateLiquidationMode", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "includeAmmPrice", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + } + ], + "name": "increasePosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_router", + "type": "address" + }, + { + "internalType": "address", + "name": "_usdr", + "type": "address" + }, + { + "internalType": "address", + "name": "_priceFeed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_liquidationFeeUsd", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_fundingRateFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stableFundingRateFactor", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isLeverageEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isLiquidator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isSwapEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastFundingTimes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + }, + { + "internalType": "address", + "name": "_feeReceiver", + "type": "address" + } + ], + "name": "liquidatePosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationFeeUsd", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "marginFeeBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxGasPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxGlobalShortSizes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLeverage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxUsdrAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minProfitBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minProfitTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintBurnFeeBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averagePrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "entryFundingRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveAmount", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "realisedPnl", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "lastIncreasedTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceFeed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_router", + "type": "address" + } + ], + "name": "removeRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "reservedAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "router", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "sellUSDR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "setBufferAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_errorCode", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_error", + "type": "string" + } + ], + "name": "setError", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_errorController", + "type": "address" + } + ], + "name": "setErrorController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_taxBasisPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stableTaxBasisPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_mintBurnFeeBasisPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_swapFeeBasisPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stableSwapFeeBasisPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_marginFeeBasisPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_liquidationFeeUsd", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minProfitTime", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_hasDynamicFees", + "type": "bool" + } + ], + "name": "setFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fundingInterval", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_fundingRateFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stableFundingRateFactor", + "type": "uint256" + } + ], + "name": "setFundingRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gov", + "type": "address" + } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inManagerMode", + "type": "bool" + } + ], + "name": "setInManagerMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inPrivateLiquidationMode", + "type": "bool" + } + ], + "name": "setInPrivateLiquidationMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isLeverageEnabled", + "type": "bool" + } + ], + "name": "setIsLeverageEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isSwapEnabled", + "type": "bool" + } + ], + "name": "setIsSwapEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidator", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setLiquidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_manager", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isManager", + "type": "bool" + } + ], + "name": "setManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxGasPrice", + "type": "uint256" + } + ], + "name": "setMaxGasPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "setMaxGlobalShortSize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxLeverage", + "type": "uint256" + } + ], + "name": "setMaxLeverage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_priceFeed", + "type": "address" + } + ], + "name": "setPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_tokenWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minProfitBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxUsdrAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isStable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_isShortable", + "type": "bool" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "setUsdrAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IVaultUtils", + "name": "_vaultUtils", + "type": "address" + } + ], + "name": "setVaultUtils", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shortableTokens", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stableFundingRateFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stableSwapFeeBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stableTaxBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "stableTokens", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenOut", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "swapFeeBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "taxBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenAmount", + "type": "uint256" + } + ], + "name": "tokenToUsdMin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalTokenWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + } + ], + "name": "updateCumulativeFundingRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newVault", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "upgradeVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_price", + "type": "uint256" + } + ], + "name": "usdToToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdAmount", + "type": "uint256" + } + ], + "name": "usdToTokenMax", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdAmount", + "type": "uint256" + } + ], + "name": "usdToTokenMin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "usdr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "usdrAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "useSwapPricing", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLong", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_raise", + "type": "bool" + } + ], + "name": "validateLiquidation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultUtils", + "outputs": [ + { + "internalType": "contract IVaultUtils", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "whitelistedTokenCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelistedTokens", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdrawFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/abis/VaultPriceFeed.json b/pkg/source/rollup-finance/abis/VaultPriceFeed.json new file mode 100644 index 000000000..3a9e17463 --- /dev/null +++ b/pkg/source/rollup-finance/abis/VaultPriceFeed.json @@ -0,0 +1,888 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ADJUSTMENT_BASIS_POINTS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ADJUSTMENT_INTERVAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_SPREAD_BASIS_POINTS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE_USD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "adjustmentBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bnbBusd", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "btc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "btcBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkFlags", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ethBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "favorPrimaryPrice", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getAmmPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_primaryPrice", + "type": "uint256" + } + ], + "name": "getAmmPriceV2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "bool", + "name": "_divByReserve0", + "type": "bool" + } + ], + "name": "getPairPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_includeAmmPrice", + "type": "bool" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_includeAmmPrice", + "type": "bool" + } + ], + "name": "getPriceV1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_includeAmmPrice", + "type": "bool" + } + ], + "name": "getPriceV2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + } + ], + "name": "getPrimaryPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_referencePrice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_maximise", + "type": "bool" + } + ], + "name": "getSecondaryPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isAdjustmentAdditive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isAmmEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isSecondaryPriceEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastAdjustmentTimings", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxStrictPriceDeviation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "priceDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "priceFeeds", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceSampleSpace", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "secondaryPriceFeed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isAdditive", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_adjustmentBps", + "type": "uint256" + } + ], + "name": "setAdjustment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_chainlinkFlags", + "type": "address" + } + ], + "name": "setChainlinkFlags", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_favorPrimaryPrice", + "type": "bool" + } + ], + "name": "setFavorPrimaryPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gov", + "type": "address" + } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isEnabled", + "type": "bool" + } + ], + "name": "setIsAmmEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isEnabled", + "type": "bool" + } + ], + "name": "setIsSecondaryPriceEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxStrictPriceDeviation", + "type": "uint256" + } + ], + "name": "setMaxStrictPriceDeviation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bnbBusd", + "type": "address" + }, + { + "internalType": "address", + "name": "_ethBnb", + "type": "address" + }, + { + "internalType": "address", + "name": "_btcBnb", + "type": "address" + } + ], + "name": "setPairs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_priceSampleSpace", + "type": "uint256" + } + ], + "name": "setPriceSampleSpace", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_secondaryPriceFeed", + "type": "address" + } + ], + "name": "setSecondaryPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_spreadBasisPoints", + "type": "uint256" + } + ], + "name": "setSpreadBasisPoints", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_spreadThresholdBasisPoints", + "type": "uint256" + } + ], + "name": "setSpreadThresholdBasisPoints", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_priceFeed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_priceDecimals", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isStrictStable", + "type": "bool" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_btc", + "type": "address" + }, + { + "internalType": "address", + "name": "_eth", + "type": "address" + }, + { + "internalType": "address", + "name": "_bnb", + "type": "address" + } + ], + "name": "setTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_useV2Pricing", + "type": "bool" + } + ], + "name": "setUseV2Pricing", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "spreadBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "spreadThresholdBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "strictStableTokens", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "useV2Pricing", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/pkg/source/rollup-finance/chainlink_flags.go b/pkg/source/rollup-finance/chainlink_flags.go new file mode 100644 index 000000000..695e6f48b --- /dev/null +++ b/pkg/source/rollup-finance/chainlink_flags.go @@ -0,0 +1,13 @@ +package gmx + +type ChainlinkFlags struct { + Flags map[string]bool `json:"flags"` +} + +const ( + chainlinkFlagsMethodGetFlag = "getFlag" +) + +func (f *ChainlinkFlags) GetFlag(address string) bool { + return f.Flags[address] +} diff --git a/pkg/source/rollup-finance/chainlink_flags_reader.go b/pkg/source/rollup-finance/chainlink_flags_reader.go new file mode 100644 index 000000000..428dd918f --- /dev/null +++ b/pkg/source/rollup-finance/chainlink_flags_reader.go @@ -0,0 +1,51 @@ +package gmx + +import ( + "context" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +type ChainlinkFlagsReader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewChainlinkFlagsReader(ethrpcClient *ethrpc.Client) *ChainlinkFlagsReader { + return &ChainlinkFlagsReader{ + abi: chainlinkABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "ChainlinkFlagsReader", + }), + } +} + +func (r *ChainlinkFlagsReader) Read(ctx context.Context, address string) (*ChainlinkFlags, error) { + var value bool + + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(ðrpc.Call{ + ABI: r.abi, + Target: address, + Method: chainlinkFlagsMethodGetFlag, + Params: []interface{}{common.HexToAddress(flagArbitrumSeqOffline)}, + }, []interface{}{&value}) + + if _, err := rpcRequest.Call(); err != nil { + r.log.Errorf("error when call rpc: %s", err) + return nil, err + } + + return &ChainlinkFlags{ + Flags: map[string]bool{ + flagArbitrumSeqOffline: value, + }, + }, nil +} diff --git a/pkg/source/rollup-finance/config.go b/pkg/source/rollup-finance/config.go new file mode 100644 index 000000000..6997e2d20 --- /dev/null +++ b/pkg/source/rollup-finance/config.go @@ -0,0 +1,7 @@ +package gmx + +type Config struct { + DexID string `json:"-"` + VaultAddress string `json:"vaultAddress"` + UseSecondaryPriceFeedV1 bool `json:"useSecondaryPriceFeedV1"` +} diff --git a/pkg/source/rollup-finance/constants.go b/pkg/source/rollup-finance/constants.go new file mode 100644 index 000000000..58535d01f --- /dev/null +++ b/pkg/source/rollup-finance/constants.go @@ -0,0 +1,16 @@ +package gmx + +import "math/big" + +const DexTypeGmx = "gmx" + +const flagArbitrumSeqOffline = "0xa438451d6458044c3c8cd2f6f31c91ac882a6d91" + +var ( + DefaultGas = Gas{Swap: 165000} + BasisPointsDivisor = big.NewInt(10000) + PricePrecision = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) + USDRDecimals = big.NewInt(18) + OneUSD = PricePrecision + FlagArbitrumSeqOffline = "0xa438451d6458044c3c8cd2f6f31c91ac882a6d91" +) diff --git a/pkg/source/rollup-finance/embed.go b/pkg/source/rollup-finance/embed.go new file mode 100644 index 000000000..302ecd42f --- /dev/null +++ b/pkg/source/rollup-finance/embed.go @@ -0,0 +1,27 @@ +package gmx + +import _ "embed" + +//go:embed abis/ChainlinkFlags.json +var chainlinkFlagsJson []byte + +//go:embed abis/FastPriceFeedV1.json +var fastPriceFeedV1Json []byte + +//go:embed abis/FastPriceFeedV2.json +var fastPriceFeedV2Json []byte + +//go:embed abis/PancakePair.json +var pancakePairJson []byte + +//go:embed abis/PriceFeed.json +var priceFeedJson []byte + +//go:embed abis/Vault.json +var vaultJson []byte + +//go:embed abis/VaultPriceFeed.json +var vaultPriceFeedJson []byte + +//go:embed abis/ERC20.json +var erc20Json []byte diff --git a/pkg/source/rollup-finance/errors.go b/pkg/source/rollup-finance/errors.go new file mode 100644 index 000000000..f11b7c09d --- /dev/null +++ b/pkg/source/rollup-finance/errors.go @@ -0,0 +1,18 @@ +package gmx + +import "errors" + +var ( + ErrVaultSwapsNotEnabled = errors.New("vault: swaps not enabled") + ErrVaultMaxUsdrExceeded = errors.New("vault: max USDR exceeded") // code: 51 + ErrVaultPoolAmountExceeded = errors.New("vault: poolAmount exceeded") + ErrVaultReserveExceedsPool = errors.New("vault: reserve exceeds pool") // code: 50 + ErrVaultPoolAmountLessThanBufferAmount = errors.New("vault: poolAmount < buffer") + + ErrVaultPriceFeedInvalidPriceFeed = errors.New("vaultPriceFeed: invalid price feed") + ErrVaultPriceFeedInvalidPrice = errors.New("vaultPriceFeed: invalid price") + ErrVaultPriceFeedCouldNotFetchPrice = errors.New("vaultPriceFeed: could not fetch price") + ErrVaultPriceFeedChainlinkFeedsNotUpdated = errors.New("chainlink feeds are not being updated") + + ErrInvalidSecondaryPriceFeedVersion = errors.New("invalid secondary price feed version") +) diff --git a/pkg/source/rollup-finance/fast_price_feed_v1.go b/pkg/source/rollup-finance/fast_price_feed_v1.go new file mode 100644 index 000000000..73405b9a3 --- /dev/null +++ b/pkg/source/rollup-finance/fast_price_feed_v1.go @@ -0,0 +1,118 @@ +package gmx + +import ( + "math/big" + "time" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber" +) + +type FastPriceFeedV1 struct { + DisableFastPriceVoteCount *big.Int `json:"disableFastPriceVoteCount"` + IsSpreadEnabled bool `json:"isSpreadEnabled"` + LastUpdatedAt *big.Int `json:"lastUpdatedAt"` + MaxDeviationBasisPoints *big.Int `json:"maxDeviationBasisPoints"` + MinAuthorizations *big.Int `json:"minAuthorizations"` + PriceDuration *big.Int `json:"priceDuration"` + VolBasisPoints *big.Int `json:"volBasisPoints"` + Prices map[string]*big.Int `json:"prices"` +} + +func (fp FastPriceFeedV1) GetVersion() int { + return int(secondaryPriceFeedVersion1) +} + +func NewFastPriceFeedV1() *FastPriceFeedV1 { + return &FastPriceFeedV1{ + Prices: make(map[string]*big.Int), + } +} + +const ( + fastPriceFeedMethodV1DisableFastPriceVoteCount = "disableFastPriceVoteCount" + fastPriceFeedMethodV1IsSpreadEnabled = "isSpreadEnabled" + fastPriceFeedMethodV1LastUpdatedAt = "lastUpdatedAt" + fastPriceFeedMethodV1MaxDeviationBasisPoints = "maxDeviationBasisPoints" + fastPriceFeedMethodV1MinAuthorizations = "minAuthorizations" + fastPriceFeedMethodV1PriceDuration = "priceDuration" + fastPriceFeedMethodV1Prices = "prices" + fastPriceFeedMethodV1VolBasisPoints = "volBasisPoints" +) + +func (pf *FastPriceFeedV1) GetPrice(token string, refPrice *big.Int, maximise bool) *big.Int { + if new(big.Int).SetInt64(time.Now().Unix()).Cmp(new(big.Int).Add(pf.LastUpdatedAt, pf.PriceDuration)) > 0 { + return refPrice + } + + fastPrice := pf.Prices[token] + if fastPrice.Cmp(bignumber.ZeroBI) == 0 { + return refPrice + } + + maxPrice := new(big.Int).Div(new(big.Int).Mul(refPrice, new(big.Int).Add(BasisPointsDivisor, pf.MaxDeviationBasisPoints)), BasisPointsDivisor) + minPrice := new(big.Int).Div(new(big.Int).Mul(refPrice, new(big.Int).Sub(BasisPointsDivisor, pf.MaxDeviationBasisPoints)), BasisPointsDivisor) + + if pf.favorFastPrice() { + if fastPrice.Cmp(minPrice) >= 0 && fastPrice.Cmp(maxPrice) <= 0 { + if maximise { + if refPrice.Cmp(fastPrice) > 0 { + volPrice := new(big.Int).Div(new(big.Int).Mul(fastPrice, new(big.Int).Add(BasisPointsDivisor, pf.VolBasisPoints)), BasisPointsDivisor) + + if volPrice.Cmp(refPrice) > 0 { + return refPrice + } else { + return volPrice + } + } + + return fastPrice + } + + if refPrice.Cmp(fastPrice) < 0 { + volPrice := new(big.Int).Div(new(big.Int).Mul(fastPrice, new(big.Int).Sub(BasisPointsDivisor, pf.VolBasisPoints)), BasisPointsDivisor) + + if volPrice.Cmp(refPrice) < 0 { + return refPrice + } else { + return volPrice + } + } + + return fastPrice + } + } + + if maximise { + if refPrice.Cmp(fastPrice) > 0 { + return refPrice + } + + if fastPrice.Cmp(maxPrice) > 0 { + return maxPrice + } else { + return fastPrice + } + } + + if refPrice.Cmp(fastPrice) < 0 { + return refPrice + } + + if fastPrice.Cmp(minPrice) < 0 { + return minPrice + } else { + return fastPrice + } +} + +func (pf *FastPriceFeedV1) favorFastPrice() bool { + if pf.IsSpreadEnabled { + return false + } + + if pf.DisableFastPriceVoteCount.Cmp(pf.MinAuthorizations) >= 0 { + return false + } + + return true +} diff --git a/pkg/source/rollup-finance/fast_price_feed_v1_reader.go b/pkg/source/rollup-finance/fast_price_feed_v1_reader.go new file mode 100644 index 000000000..0002a2667 --- /dev/null +++ b/pkg/source/rollup-finance/fast_price_feed_v1_reader.go @@ -0,0 +1,107 @@ +package gmx + +import ( + "context" + "math/big" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +type FastPriceFeedV1Reader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewFastPriceFeedV1Reader(ethrpcClient *ethrpc.Client) *FastPriceFeedV1Reader { + return &FastPriceFeedV1Reader{ + abi: fastPriceFeedV1ABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "FastPriceFeedV1Reader", + }), + } +} + +func (r *FastPriceFeedV1Reader) Read( + ctx context.Context, + address string, + tokens []string, +) (*FastPriceFeedV1, error) { + fastPriceFeedV1 := NewFastPriceFeedV1() + + if err := r.readData(ctx, address, fastPriceFeedV1); err != nil { + r.log.Errorf("error when read data: %s", err) + return nil, err + } + + if err := r.readTokenData(ctx, address, fastPriceFeedV1, tokens); err != nil { + r.log.Errorf("error when read token data: %s", err) + return nil, err + } + + return fastPriceFeedV1, nil +} + +// readData +// - DisableFastPriceVoteCount +// - IsSpreadEnabled +// - LastUpdatedAt +// - MaxDeviationBasisPoints +// - MinAuthorizations +// - PriceDuration +// - VolBasisPoints +func (r *FastPriceFeedV1Reader) readData(ctx context.Context, address string, fastPriceFeed *FastPriceFeedV1) error { + callParamsFactory := CallParamsFactory(r.abi, address) + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV1DisableFastPriceVoteCount, nil), []interface{}{&fastPriceFeed.DisableFastPriceVoteCount}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV1IsSpreadEnabled, nil), []interface{}{&fastPriceFeed.IsSpreadEnabled}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV1LastUpdatedAt, nil), []interface{}{&fastPriceFeed.LastUpdatedAt}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV1MaxDeviationBasisPoints, nil), []interface{}{&fastPriceFeed.MaxDeviationBasisPoints}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV1MinAuthorizations, nil), []interface{}{&fastPriceFeed.MinAuthorizations}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV1PriceDuration, nil), []interface{}{&fastPriceFeed.PriceDuration}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV1VolBasisPoints, nil), []interface{}{&fastPriceFeed.VolBasisPoints}) + + _, err := rpcRequest.TryAggregate() + if err != nil { + r.log.Errorf("error when call aggreate request: %s", err) + } + return err +} + +func (r *FastPriceFeedV1Reader) readTokenData( + ctx context.Context, + address string, + fastPriceFeed *FastPriceFeedV1, + tokens []string, +) error { + tokensLen := len(tokens) + + prices := make([]*big.Int, tokensLen) + + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + for i, token := range tokens { + rpcRequest.AddCall(ðrpc.Call{ + ABI: r.abi, + Target: address, + Method: fastPriceFeedMethodV1Prices, + Params: []interface{}{common.HexToAddress(token)}, + }, []interface{}{&prices[i]}) + } + + if _, err := rpcRequest.TryAggregate(); err != nil { + return err + } + + for i, token := range tokens { + fastPriceFeed.Prices[token] = prices[i] + } + + return nil +} diff --git a/pkg/source/rollup-finance/fast_price_feed_v2.go b/pkg/source/rollup-finance/fast_price_feed_v2.go new file mode 100644 index 000000000..561f6ece6 --- /dev/null +++ b/pkg/source/rollup-finance/fast_price_feed_v2.go @@ -0,0 +1,137 @@ +package gmx + +import ( + "math/big" + "time" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber" +) + +type FastPriceFeedV2 struct { + DisableFastPriceVoteCount *big.Int `json:"disableFastPriceVoteCount"` + IsSpreadEnabled bool `json:"isSpreadEnabled"` + LastUpdatedAt *big.Int `json:"lastUpdatedAt"` + MaxDeviationBasisPoints *big.Int `json:"maxDeviationBasisPoints"` + MinAuthorizations *big.Int `json:"minAuthorizations"` + PriceDuration *big.Int `json:"priceDuration"` + MaxPriceUpdateDelay *big.Int `json:"maxPriceUpdateDelay"` + SpreadBasisPointsIfChainError *big.Int `json:"spreadBasisPointsIfChainError"` + SpreadBasisPointsIfInactive *big.Int `json:"spreadBasisPointsIfInactive"` + Prices map[string]*big.Int `json:"prices"` + PriceData map[string]PriceDataItem `json:"priceData"` + MaxCumulativeDeltaDiffs map[string]*big.Int `json:"maxCumulativeDeltaDiffs"` +} + +type PriceDataItem struct { + RefPrice *big.Int `json:"refPrice"` + RefTime uint64 `json:"refTime"` + CumulativeRefDelta uint64 `json:"cumulativeRefDelta"` + CumulativeFastDelta uint64 `json:"cumulativeFastDelta"` +} + +func (fp FastPriceFeedV2) GetVersion() int { + return int(secondaryPriceFeedVersion2) +} + +func NewFastPriceFeedV2() *FastPriceFeedV2 { + return &FastPriceFeedV2{ + Prices: make(map[string]*big.Int), + PriceData: make(map[string]PriceDataItem), + MaxCumulativeDeltaDiffs: make(map[string]*big.Int), + } +} + +const ( + fastPriceFeedMethodV2DisableFastPriceVoteCount = "disableFastPriceVoteCount" + fastPriceFeedMethodV2IsSpreadEnabled = "isSpreadEnabled" + fastPriceFeedMethodV2LastUpdatedAt = "lastUpdatedAt" + fastPriceFeedMethodV2MaxDeviationBasisPoints = "maxDeviationBasisPoints" + fastPriceFeedMethodV2MinAuthorizations = "minAuthorizations" + fastPriceFeedMethodV2PriceDuration = "priceDuration" + fastPriceFeedMethodV2MaxPriceUpdateDelay = "maxPriceUpdateDelay" + fastPriceFeedMethodV2SpreadBasisPointsIfChainError = "spreadBasisPointsIfChainError" + fastPriceFeedMethodV2SpreadBasisPointsIfInactive = "spreadBasisPointsIfInactive" + fastPriceFeedMethodV2Prices = "prices" + fastPriceFeedMethodV2MaxCumulativeDeltaDiffs = "maxCumulativeDeltaDiffs" + fastPriceFeedMethodV2GetPriceData = "getPriceData" +) + +func (pf *FastPriceFeedV2) GetPrice(token string, refPrice *big.Int, maximise bool) *big.Int { + if new(big.Int).SetInt64(time.Now().Unix()).Cmp(new(big.Int).Add(pf.LastUpdatedAt, pf.MaxPriceUpdateDelay)) > 0 { + if maximise { + return new(big.Int).Div(new(big.Int).Mul(refPrice, new(big.Int).Add(BasisPointsDivisor, pf.SpreadBasisPointsIfChainError)), BasisPointsDivisor) + } + + return new(big.Int).Div(new(big.Int).Mul(refPrice, new(big.Int).Sub(BasisPointsDivisor, pf.SpreadBasisPointsIfChainError)), BasisPointsDivisor) + } + + if new(big.Int).SetInt64(time.Now().Unix()).Cmp(new(big.Int).Add(pf.LastUpdatedAt, pf.PriceDuration)) > 0 { + if maximise { + return new(big.Int).Div(new(big.Int).Mul(refPrice, new(big.Int).Add(BasisPointsDivisor, pf.SpreadBasisPointsIfInactive)), BasisPointsDivisor) + } + + return new(big.Int).Div(new(big.Int).Mul(refPrice, new(big.Int).Sub(BasisPointsDivisor, pf.SpreadBasisPointsIfInactive)), BasisPointsDivisor) + } + + fastPrice := pf.Prices[token] + if fastPrice.Cmp(bignumber.ZeroBI) == 0 { + return refPrice + } + + var diffBasisPoints *big.Int + if refPrice.Cmp(fastPrice) > 0 { + diffBasisPoints = new(big.Int).Sub(refPrice, fastPrice) + } else { + diffBasisPoints = new(big.Int).Sub(fastPrice, refPrice) + } + + diffBasisPoints = new(big.Int).Div(new(big.Int).Mul(diffBasisPoints, BasisPointsDivisor), refPrice) + + hasSpread := !pf.favorFastPrice(token) || diffBasisPoints.Cmp(pf.MaxDeviationBasisPoints) > 0 + + if hasSpread { + if maximise { + if refPrice.Cmp(fastPrice) > 0 { + return refPrice + } + + return fastPrice + } + + if refPrice.Cmp(fastPrice) < 0 { + return refPrice + } + + return fastPrice + } + + return fastPrice +} + +func (pf *FastPriceFeedV2) favorFastPrice(token string) bool { + if pf.IsSpreadEnabled { + return false + } + + if pf.DisableFastPriceVoteCount.Cmp(pf.MinAuthorizations) >= 0 { + return false + } + + _, _, cumulativeRefDelta, cumulativeFastDelta := pf.getPriceData(token) + + if cumulativeFastDelta.Cmp(cumulativeRefDelta) > 0 && + new(big.Int).Sub(cumulativeFastDelta, cumulativeRefDelta).Cmp(pf.MaxCumulativeDeltaDiffs[token]) > 0 { + return false + } + + return true +} + +func (pf *FastPriceFeedV2) getPriceData(token string) (*big.Int, *big.Int, *big.Int, *big.Int) { + priceDataItem := pf.PriceData[token] + + return priceDataItem.RefPrice, + new(big.Int).SetUint64(priceDataItem.RefTime), + new(big.Int).SetUint64(priceDataItem.CumulativeRefDelta), + new(big.Int).SetUint64(priceDataItem.CumulativeFastDelta) +} diff --git a/pkg/source/rollup-finance/fast_price_feed_v2_reader.go b/pkg/source/rollup-finance/fast_price_feed_v2_reader.go new file mode 100644 index 000000000..10e5abe1c --- /dev/null +++ b/pkg/source/rollup-finance/fast_price_feed_v2_reader.go @@ -0,0 +1,112 @@ +package gmx + +import ( + "context" + "math/big" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +type FastPriceFeedV2Reader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewFastPriceFeedV2Reader(ethrpcClient *ethrpc.Client) *FastPriceFeedV2Reader { + return &FastPriceFeedV2Reader{ + abi: fastPriceFeedV2ABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "FastPriceFeedV2Reader", + }), + } +} + +func (r *FastPriceFeedV2Reader) Read( + ctx context.Context, + address string, + tokens []string, +) (*FastPriceFeedV2, error) { + fastPriceFeedV2 := NewFastPriceFeedV2() + + if err := r.readData(ctx, address, fastPriceFeedV2); err != nil { + r.log.Errorf("error when read data: %s", err) + return nil, err + } + + if err := r.readTokenData(ctx, address, fastPriceFeedV2, tokens); err != nil { + r.log.Errorf("error when read token data: %s", err) + return nil, err + } + + return fastPriceFeedV2, nil +} + +// readData +// - DisableFastPriceVoteCount +// - IsSpreadEnabled +// - LastUpdatedAt +// - MaxDeviationBasisPoints +// - MinAuthorizations +// - PriceDuration +// - MaxPriceUpdateDelay +// - SpreadBasisPointsIfChainError +// - SpreadBasisPointsIfInactive +func (r *FastPriceFeedV2Reader) readData(ctx context.Context, address string, fastPriceFeed *FastPriceFeedV2) error { + + callParamsFactory := CallParamsFactory(r.abi, address) + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2DisableFastPriceVoteCount, nil), []interface{}{&fastPriceFeed.DisableFastPriceVoteCount}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2IsSpreadEnabled, nil), []interface{}{&fastPriceFeed.IsSpreadEnabled}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2LastUpdatedAt, nil), []interface{}{&fastPriceFeed.LastUpdatedAt}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2MaxDeviationBasisPoints, nil), []interface{}{&fastPriceFeed.MaxDeviationBasisPoints}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2MinAuthorizations, nil), []interface{}{&fastPriceFeed.MinAuthorizations}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2PriceDuration, nil), []interface{}{&fastPriceFeed.PriceDuration}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2MaxPriceUpdateDelay, nil), []interface{}{&fastPriceFeed.MaxPriceUpdateDelay}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2SpreadBasisPointsIfChainError, nil), []interface{}{&fastPriceFeed.SpreadBasisPointsIfChainError}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2SpreadBasisPointsIfInactive, nil), []interface{}{&fastPriceFeed.SpreadBasisPointsIfInactive}) + + _, err := rpcRequest.TryAggregate() + return err + +} + +func (r *FastPriceFeedV2Reader) readTokenData( + ctx context.Context, + address string, + fastPriceFeed *FastPriceFeedV2, + tokens []string, +) error { + tokensLen := len(tokens) + + prices := make([]*big.Int, tokensLen) + maxCumulativeDeltaDiffs := make([]*big.Int, tokensLen) + priceData := make([]PriceDataItem, tokensLen) + callParamsFactory := CallParamsFactory(r.abi, address) + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + for i, token := range tokens { + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2Prices, []interface{}{common.HexToAddress(token)}), []interface{}{&prices[i]}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2MaxCumulativeDeltaDiffs, []interface{}{common.HexToAddress(token)}), []interface{}{&maxCumulativeDeltaDiffs[i]}) + rpcRequest.AddCall(callParamsFactory(fastPriceFeedMethodV2GetPriceData, []interface{}{common.HexToAddress(token)}), []interface{}{&priceData[i]}) + } + + if _, err := rpcRequest.TryAggregate(); err != nil { + r.log.Errorf("error when call aggreate request: %s", err) + return err + } + + for i, token := range tokens { + fastPriceFeed.Prices[token] = prices[i] + fastPriceFeed.MaxCumulativeDeltaDiffs[token] = maxCumulativeDeltaDiffs[i] + fastPriceFeed.PriceData[token] = priceData[i] + } + + return nil +} diff --git a/pkg/source/rollup-finance/helper.go b/pkg/source/rollup-finance/helper.go new file mode 100644 index 000000000..6db6939e2 --- /dev/null +++ b/pkg/source/rollup-finance/helper.go @@ -0,0 +1,17 @@ +package gmx + +import ( + "github.com/KyberNetwork/ethrpc" + "github.com/ethereum/go-ethereum/accounts/abi" +) + +func CallParamsFactory(abi abi.ABI, address string) func(callMethod string, params []interface{}) *ethrpc.Call { + return func(callMethod string, params []interface{}) *ethrpc.Call { + return ðrpc.Call{ + ABI: abi, + Target: address, + Method: callMethod, + Params: params, + } + } +} diff --git a/pkg/source/rollup-finance/iface.go b/pkg/source/rollup-finance/iface.go new file mode 100644 index 000000000..21d2673ef --- /dev/null +++ b/pkg/source/rollup-finance/iface.go @@ -0,0 +1,50 @@ +package gmx + +import ( + "context" + "math/big" +) + +// IVaultReader reads vault smart contract +type IVaultReader interface { + Read(ctx context.Context, address string) (*Vault, error) +} + +// IVaultPriceFeedReader reads vault price feed smart contract +type IVaultPriceFeedReader interface { + Read(ctx context.Context, address string, tokens []string) (*VaultPriceFeed, error) +} + +// IFastPriceFeedV1Reader reads fast price feed smart contract +type IFastPriceFeedV1Reader interface { + Read(ctx context.Context, address string, tokens []string) (*FastPriceFeedV1, error) +} + +type IFastPriceFeedV2Reader interface { + Read(ctx context.Context, address string, tokens []string) (*FastPriceFeedV2, error) +} + +// IPriceFeedReader reads price feed smart contract +type IPriceFeedReader interface { + Read(ctx context.Context, address string, roundCount int) (*PriceFeed, error) +} + +// IUSDRReader reads usdr smart contract +type IUSDRReader interface { + Read(ctx context.Context, address string) (*USDR, error) +} + +// IChainlinkFlagsReader reads chainlink flag smart contract +type IChainlinkFlagsReader interface { + Read(ctx context.Context, address string) (*ChainlinkFlags, error) +} + +// IPancakePairReader reads pancake pair smart contract +type IPancakePairReader interface { + Read(ctx context.Context, address string) (*PancakePair, error) +} + +type IFastPriceFeed interface { + GetVersion() int + GetPrice(token string, refPrice *big.Int, maximise bool) *big.Int +} diff --git a/pkg/source/rollup-finance/pancake_pair.go b/pkg/source/rollup-finance/pancake_pair.go new file mode 100644 index 000000000..1b3b9b11b --- /dev/null +++ b/pkg/source/rollup-finance/pancake_pair.go @@ -0,0 +1,20 @@ +package gmx + +import "math/big" + +type PancakePair struct { + Reserves []*big.Int `json:"reserves"` + TimestampLast uint32 `json:"timestampLast"` +} + +func NewPancakePair() *PancakePair { + return &PancakePair{} +} + +const ( + pancakePairMethodGetReserves = "getReserves" +) + +func (p *PancakePair) GetReserves() (*big.Int, *big.Int, uint32) { + return p.Reserves[0], p.Reserves[1], p.TimestampLast +} diff --git a/pkg/source/rollup-finance/pancake_pair_reader.go b/pkg/source/rollup-finance/pancake_pair_reader.go new file mode 100644 index 000000000..3ea19f045 --- /dev/null +++ b/pkg/source/rollup-finance/pancake_pair_reader.go @@ -0,0 +1,57 @@ +package gmx + +import ( + "context" + "math/big" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" +) + +type PancakePairReader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewPancakePairReader(ethrpcClient *ethrpc.Client) *PancakePairReader { + return &PancakePairReader{ + abi: pancakePairABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "PancakePairReader", + }), + } +} + +func (r *PancakePairReader) Read(ctx context.Context, address string) (*PancakePair, error) { + var reserves struct { + Reserve0 *big.Int + Reserve1 *big.Int + BlockTimestampLast uint32 + } + + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(ðrpc.Call{ + ABI: r.abi, + Target: address, + Method: pancakePairMethodGetReserves, + Params: nil, + }, []interface{}{&reserves}) + + if _, err := rpcRequest.Call(); err != nil { + r.log.Errorf("error when call rpc request %v", err) + return nil, err + } + + return &PancakePair{ + Reserves: []*big.Int{ + reserves.Reserve0, + reserves.Reserve1, + }, + TimestampLast: reserves.BlockTimestampLast, + }, nil +} diff --git a/pkg/source/rollup-finance/pool_simulator.go b/pkg/source/rollup-finance/pool_simulator.go new file mode 100644 index 000000000..ecdc5f6d7 --- /dev/null +++ b/pkg/source/rollup-finance/pool_simulator.go @@ -0,0 +1,224 @@ +package gmx + +import ( + "encoding/json" + "math/big" + "strings" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/entity" + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/pool" + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber" +) + +type Gas struct { + Swap int64 +} + +type PoolSimulator struct { + pool.Pool + + vault *Vault + vaultUtils *VaultUtils + gas Gas +} + +func NewPoolSimulator(entityPool entity.Pool) (*PoolSimulator, error) { + var extra Extra + if err := json.Unmarshal([]byte(entityPool.Extra), &extra); err != nil { + return nil, err + } + + tokens := make([]string, 0, len(entityPool.Tokens)) + for _, poolToken := range entityPool.Tokens { + tokens = append(tokens, poolToken.Address) + } + + info := pool.PoolInfo{ + Address: entityPool.Address, + Exchange: entityPool.Exchange, + Type: entityPool.Type, + Tokens: tokens, + } + + return &PoolSimulator{ + Pool: pool.Pool{ + Info: info, + }, + vault: extra.Vault, + vaultUtils: NewVaultUtils(extra.Vault), + gas: DefaultGas, + }, nil +} + +func (p *PoolSimulator) CalcAmountOut( + tokenAmountIn pool.TokenAmount, + tokenOut string, +) (*pool.CalcAmountOutResult, error) { + amountOutAfterFees, feeAmount, err := p.getAmountOut(tokenAmountIn.Token, tokenOut, tokenAmountIn.Amount) + if err != nil { + return &pool.CalcAmountOutResult{}, err + } + + tokenAmountOut := &pool.TokenAmount{ + Token: tokenOut, + Amount: amountOutAfterFees, + } + tokenAmountFee := &pool.TokenAmount{ + Token: tokenOut, + Amount: feeAmount, + } + + return &pool.CalcAmountOutResult{ + TokenAmountOut: tokenAmountOut, + Fee: tokenAmountFee, + Gas: p.gas.Swap, + }, nil +} + +// UpdateBalance update UsdrAmount only +// https://github.com/gmx-io/gmx-contracts/blob/787d767e033c411f6d083f2725fb54b7fa956f7e/contracts/core/Vault.sol#L547-L548 +func (p *PoolSimulator) UpdateBalance(params pool.UpdateBalanceParams) { + input, output, fee := params.TokenAmountIn, params.TokenAmountOut, params.Fee + priceIn, err := p.vault.GetMinPrice(input.Token) + if err != nil { + return + } + + usdrAmount := new(big.Int).Div(new(big.Int).Mul(input.Amount, priceIn), PricePrecision) + usdrAmount = p.vault.AdjustForDecimals(usdrAmount, input.Token, p.vault.USDR.Address) + + p.vault.IncreaseUSDRAmount(input.Token, usdrAmount) + p.vault.DecreaseUSDRAmount(output.Token, usdrAmount) + p.vault.IncreasePoolAmount(input.Token, input.Amount) + p.vault.DecreasePoolAmount(output.Token, new(big.Int).Add(output.Amount, fee.Amount)) +} + +func (p *PoolSimulator) CanSwapFrom(address string) []string { return p.CanSwapTo(address) } + +func (p *PoolSimulator) CanSwapTo(address string) []string { + whitelistedTokens := p.vault.WhitelistedTokens + + isTokenExists := false + for _, token := range whitelistedTokens { + if strings.EqualFold(token, address) { + isTokenExists = true + } + } + + if !isTokenExists { + return nil + } + + swappableTokens := make([]string, 0, len(whitelistedTokens)-1) + for _, token := range whitelistedTokens { + tokenAddress := token + + if address == tokenAddress { + continue + } + + swappableTokens = append(swappableTokens, tokenAddress) + } + + return swappableTokens +} + +func (p *PoolSimulator) GetMetaInfo(_ string, _ string) interface{} { return nil } + +// getAmountOut returns amountOutAfterFees, feeAmount and error +func (p *PoolSimulator) getAmountOut(tokenIn string, tokenOut string, amountIn *big.Int) (*big.Int, *big.Int, error) { + if !p.vault.IsSwapEnabled { + return nil, nil, ErrVaultSwapsNotEnabled + } + + priceIn, err := p.vault.GetMinPrice(tokenIn) + if err != nil { + return nil, nil, err + } + + priceOut, err := p.vault.GetMaxPrice(tokenOut) + if err != nil { + return nil, nil, err + } + + amountOut := new(big.Int).Div(new(big.Int).Mul(amountIn, priceIn), priceOut) + amountOut = p.vault.AdjustForDecimals(amountOut, tokenIn, tokenOut) + + usdrAmount := new(big.Int).Div(new(big.Int).Mul(amountIn, priceIn), PricePrecision) + usdrAmount = p.vault.AdjustForDecimals(usdrAmount, tokenIn, p.vault.USDR.Address) + + // in smart contract, this validation is implemented inside _increaseUsdrAmount method + if err = p.validateMaxUsdrExceed(tokenIn, usdrAmount); err != nil { + return nil, nil, err + } + + // in smart contract, this validation is implemented inside _decreasePoolAmount method + if err = p.validateMinPoolAmount(tokenOut, amountOut); err != nil { + return nil, nil, err + } + + // in smart contract, this validation is implemented inside _validateBufferAmount method + if err = p.validateBufferAmount(tokenOut, amountOut); err != nil { + return nil, nil, err + } + + feeBasisPoints := p.vaultUtils.GetSwapFeeBasisPoints(tokenIn, tokenOut, usdrAmount) + amountOutAfterFees := new(big.Int).Div( + new(big.Int).Mul( + amountOut, + new(big.Int).Sub(BasisPointsDivisor, feeBasisPoints), + ), + BasisPointsDivisor, + ) + + feeAmount := new(big.Int).Sub(amountOut, amountOutAfterFees) + + return amountOutAfterFees, feeAmount, nil +} + +func (p *PoolSimulator) validateMaxUsdrExceed(token string, amount *big.Int) error { + currentUsdrAmount := p.vault.USDRAmounts[token] + newUsdrAmount := new(big.Int).Add(currentUsdrAmount, amount) + + maxUsdrAmount := p.vault.MaxUSDRAmounts[token] + + if maxUsdrAmount.Cmp(bignumber.ZeroBI) == 0 { + return nil + } + + if newUsdrAmount.Cmp(maxUsdrAmount) < 0 { + return nil + } + + return ErrVaultMaxUsdrExceeded +} + +func (p *PoolSimulator) validateMinPoolAmount(token string, amount *big.Int) error { + currentPoolAmount := p.vault.PoolAmounts[token] + + if currentPoolAmount.Cmp(amount) < 0 { + return ErrVaultPoolAmountExceeded + } + + newPoolAmount := new(big.Int).Sub(currentPoolAmount, amount) + reservedAmount := p.vault.ReservedAmounts[token] + + if reservedAmount.Cmp(newPoolAmount) > 0 { + return ErrVaultReserveExceedsPool + } + + return nil +} + +func (p *PoolSimulator) validateBufferAmount(token string, amount *big.Int) error { + currentPoolAmount := p.vault.PoolAmounts[token] + newPoolAmount := new(big.Int).Sub(currentPoolAmount, amount) + + bufferAmount := p.vault.BufferAmounts[token] + + if newPoolAmount.Cmp(bufferAmount) < 0 { + return ErrVaultPoolAmountLessThanBufferAmount + } + + return nil +} diff --git a/pkg/source/rollup-finance/pool_tracker.go b/pkg/source/rollup-finance/pool_tracker.go new file mode 100644 index 000000000..226a4dd44 --- /dev/null +++ b/pkg/source/rollup-finance/pool_tracker.go @@ -0,0 +1,74 @@ +package gmx + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/entity" + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/pool" +) + +type PoolTracker struct { + config *Config + ethrpcClient *ethrpc.Client +} + +func NewPoolTracker( + cfg *Config, + ethrpcClient *ethrpc.Client, +) (*PoolTracker, error) { + return &PoolTracker{ + config: cfg, + ethrpcClient: ethrpcClient, + }, nil +} + +func (d *PoolTracker) GetNewPoolState( + ctx context.Context, + p entity.Pool, + _ pool.GetNewPoolStateParams, +) (entity.Pool, error) { + log := logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "poolAddress": p.Address, + }) + log.Info("Start getting new state of pool") + + vault, err := NewVaultScanner(d.config, d.ethrpcClient).getVault(ctx, p.Address) + if err != nil { + log.Errorf("get vault failed: %v", err) + return entity.Pool{}, fmt.Errorf("get vault failed, pool: %s, err: %v", p.Address, err) + } + + poolTokens := make([]*entity.PoolToken, 0, len(vault.WhitelistedTokens)) + reserves := make(entity.PoolReserves, 0, len(vault.WhitelistedTokens)) + for _, token := range vault.WhitelistedTokens { + poolTokens = append(poolTokens, &entity.PoolToken{ + Address: token, + Swappable: true, + }) + reserves = append(reserves, vault.PoolAmounts[token].String()) + } + + extra := Extra{Vault: vault} + + extraBytes, err := json.Marshal(extra) + if err != nil { + log.Errorf("marshal extra failed: %v", err) + return entity.Pool{}, err + } + + p.Extra = string(extraBytes) + p.Reserves = reserves + p.Tokens = poolTokens + p.Timestamp = time.Now().Unix() + + log.Info("Finish getting new state") + + return p, nil +} diff --git a/pkg/source/rollup-finance/pools_list_updater.go b/pkg/source/rollup-finance/pools_list_updater.go new file mode 100644 index 000000000..1b12f2aa0 --- /dev/null +++ b/pkg/source/rollup-finance/pools_list_updater.go @@ -0,0 +1,79 @@ +package gmx + +import ( + "context" + "encoding/json" + "time" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/entity" +) + +type PoolsListUpdater struct { + config *Config + ethrpcClient *ethrpc.Client + hasInitialized bool +} + +func NewPoolsListUpdater( + cfg *Config, + ethrpcClient *ethrpc.Client, +) *PoolsListUpdater { + return &PoolsListUpdater{ + config: cfg, + ethrpcClient: ethrpcClient, + hasInitialized: false, + } +} + +func (d *PoolsListUpdater) GetNewPools(ctx context.Context, metadataBytes []byte) ([]entity.Pool, []byte, error) { + log := logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "kind": "getNewPools", + }) + if d.hasInitialized { + log.Infof("initialized. Ignore making new pools") + return nil, nil, nil + } + + vault, err := NewVaultScanner(d.config, d.ethrpcClient).getVault(ctx, d.config.VaultAddress) + if err != nil { + log.Errorf("get vault failed: %v", err) + return nil, nil, err + } + + poolTokens := make([]*entity.PoolToken, 0, len(vault.WhitelistedTokens)) + reserves := make(entity.PoolReserves, 0, len(vault.WhitelistedTokens)) + for _, token := range vault.WhitelistedTokens { + poolTokens = append(poolTokens, &entity.PoolToken{ + Address: token, + Swappable: true, + }) + reserves = append(reserves, vault.PoolAmounts[token].String()) + } + + extra := Extra{Vault: vault} + + extraBytes, err := json.Marshal(extra) + if err != nil { + log.Errorf("error when marshal extra: %v", err) + return nil, nil, err + } + + pool := entity.Pool{ + Address: d.config.VaultAddress, + Exchange: d.config.DexID, + Type: DexTypeGmx, + Tokens: poolTokens, + Reserves: reserves, + Extra: string(extraBytes), + Timestamp: time.Now().Unix(), + } + + d.hasInitialized = true + log.Infof("got %v vault", d.config.VaultAddress) + + return []entity.Pool{pool}, nil, nil +} diff --git a/pkg/source/rollup-finance/price_feed.go b/pkg/source/rollup-finance/price_feed.go new file mode 100644 index 000000000..c7e9df226 --- /dev/null +++ b/pkg/source/rollup-finance/price_feed.go @@ -0,0 +1,46 @@ +package gmx + +import ( + "math/big" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber" +) + +type PriceFeed struct { + RoundID *big.Int `json:"roundId"` + Answer *big.Int `json:"answer"` + Answers map[string]*big.Int `json:"answers"` +} + +type RoundData struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +} + +func NewPriceFeed() *PriceFeed { + return &PriceFeed{ + Answers: make(map[string]*big.Int), + } +} + +const ( + priceFeedMethodLatestRoundData = "latestRoundData" + priceFeedMethodGetRoundData = "getRoundData" + minRoundCount = 2 +) + +func (pf *PriceFeed) LatestRound() *big.Int { + return pf.RoundID +} + +func (pf *PriceFeed) LatestAnswer() *big.Int { + return pf.Answer +} + +// GetRoundData returns roundId, answer, startedAt, updatedAt, answeredInRound +func (pf *PriceFeed) GetRoundData(roundID *big.Int) (*big.Int, *big.Int, *big.Int, *big.Int, *big.Int) { + return roundID, pf.Answers[roundID.String()], bignumber.ZeroBI, bignumber.ZeroBI, bignumber.ZeroBI +} diff --git a/pkg/source/rollup-finance/price_feed_reader.go b/pkg/source/rollup-finance/price_feed_reader.go new file mode 100644 index 000000000..96b77da5d --- /dev/null +++ b/pkg/source/rollup-finance/price_feed_reader.go @@ -0,0 +1,95 @@ +package gmx + +import ( + "context" + "math/big" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" +) + +type PriceFeedReader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewPriceFeedReader(ethrpcClient *ethrpc.Client) *PriceFeedReader { + return &PriceFeedReader{ + abi: priceFeedABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "PriceFeedReader", + }), + } +} + +func (r *PriceFeedReader) Read(ctx context.Context, address string, roundCount int) (*PriceFeed, error) { + priceFeed := NewPriceFeed() + + if err := r.getLatestRoundData(ctx, address, priceFeed); err != nil { + r.log.Errorf("error when get latest round data: %s", err) + return nil, err + } + + if err := r.getHistoryRoundData(ctx, address, priceFeed, roundCount); err != nil { + r.log.Errorf("error when get history round data: %s", err) + return nil, err + } + + return priceFeed, nil +} + +func (r *PriceFeedReader) getLatestRoundData(ctx context.Context, address string, priceFeed *PriceFeed) error { + var latestRoundData RoundData + + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(ðrpc.Call{ + ABI: r.abi, + Target: address, + Method: priceFeedMethodLatestRoundData, + Params: nil, + }, []interface{}{&latestRoundData}) + + if _, err := rpcRequest.Call(); err != nil { + return err + } + + priceFeed.RoundID = latestRoundData.RoundId + priceFeed.Answer = latestRoundData.Answer + priceFeed.Answers[latestRoundData.RoundId.String()] = latestRoundData.Answer + + return nil +} + +func (r *PriceFeedReader) getHistoryRoundData(ctx context.Context, address string, priceFeed *PriceFeed, roundCount int) error { + if roundCount < minRoundCount { + return nil + } + + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + roundDataList := make([]RoundData, roundCount-1) + for i := 1; i < roundCount; i++ { + roundID := new(big.Int).Sub(priceFeed.RoundID, big.NewInt(int64(i))) + + rpcRequest.AddCall(ðrpc.Call{ + ABI: r.abi, + Target: address, + Method: priceFeedMethodGetRoundData, + Params: []interface{}{roundID}, + }, []interface{}{&roundDataList[i-1]}) + } + + if _, err := rpcRequest.TryAggregate(); err != nil { + return err + } + + for _, roundData := range roundDataList { + priceFeed.Answers[roundData.RoundId.String()] = roundData.Answer + } + + return nil +} diff --git a/pkg/source/rollup-finance/types.go b/pkg/source/rollup-finance/types.go new file mode 100644 index 000000000..e41d8192f --- /dev/null +++ b/pkg/source/rollup-finance/types.go @@ -0,0 +1,18 @@ +package gmx + +type VaultAddress struct { + Vault string `json:"vault"` +} + +type Extra struct { + Vault *Vault `json:"vault"` +} + +type ChainID uint + +type SecondaryPriceFeedVersion int + +const ( + secondaryPriceFeedVersion1 SecondaryPriceFeedVersion = 1 + secondaryPriceFeedVersion2 SecondaryPriceFeedVersion = 2 +) diff --git a/pkg/source/rollup-finance/usdr.go b/pkg/source/rollup-finance/usdr.go new file mode 100644 index 000000000..14468e6f7 --- /dev/null +++ b/pkg/source/rollup-finance/usdr.go @@ -0,0 +1,14 @@ +package gmx + +import ( + "math/big" +) + +type USDR struct { + Address string `json:"address"` + TotalSupply *big.Int `json:"totalSupply"` +} + +const ( + usdrMethodTotalSupply = "totalSupply" +) diff --git a/pkg/source/rollup-finance/usdr_reader.go b/pkg/source/rollup-finance/usdr_reader.go new file mode 100644 index 000000000..207abc662 --- /dev/null +++ b/pkg/source/rollup-finance/usdr_reader.go @@ -0,0 +1,49 @@ +package gmx + +import ( + "context" + "math/big" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" +) + +type USDRReader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewUSDRReader(ethrpcClient *ethrpc.Client) *USDRReader { + return &USDRReader{ + abi: erc20ABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "USDRReader", + }), + } +} + +func (r *USDRReader) Read(ctx context.Context, address string) (*USDR, error) { + var totalSupply *big.Int + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(ðrpc.Call{ + ABI: r.abi, + Target: address, + Method: usdrMethodTotalSupply, + Params: nil, + }, []interface{}{&totalSupply}) + + if _, err := rpcRequest.Call(); err != nil { + r.log.Errorf("error when call rpc request %v", err) + return nil, err + } + + return &USDR{ + Address: address, + TotalSupply: totalSupply, + }, nil +} diff --git a/pkg/source/rollup-finance/vault.go b/pkg/source/rollup-finance/vault.go new file mode 100644 index 000000000..d6b7ac1ef --- /dev/null +++ b/pkg/source/rollup-finance/vault.go @@ -0,0 +1,144 @@ +package gmx + +import ( + "math/big" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber" + "github.com/ethereum/go-ethereum/common" +) + +type Vault struct { + HasDynamicFees bool `json:"hasDynamicFees"` + IncludeAmmPrice bool `json:"includeAmmPrice"` + IsSwapEnabled bool `json:"isSwapEnabled"` + StableSwapFeeBasisPoints *big.Int `json:"stableSwapFeeBasisPoints"` + StableTaxBasisPoints *big.Int `json:"stableTaxBasisPoints"` + SwapFeeBasisPoints *big.Int `json:"swapFeeBasisPoints"` + TaxBasisPoints *big.Int `json:"taxBasisPoints"` + TotalTokenWeights *big.Int `json:"totalTokenWeights"` + + WhitelistedTokens []string `json:"whitelistedTokens"` + PoolAmounts map[string]*big.Int `json:"poolAmounts"` + BufferAmounts map[string]*big.Int `json:"bufferAmounts"` + ReservedAmounts map[string]*big.Int `json:"reservedAmounts"` + TokenDecimals map[string]*big.Int `json:"tokenDecimals"` + StableTokens map[string]bool `json:"stableTokens"` + USDRAmounts map[string]*big.Int `json:"usdrAmounts"` + MaxUSDRAmounts map[string]*big.Int `json:"maxUsdrAmounts"` + TokenWeights map[string]*big.Int `json:"tokenWeights"` + + PriceFeedAddress common.Address `json:"-"` + PriceFeed *VaultPriceFeed `json:"priceFeed"` + + USDRAddress common.Address `json:"-"` + USDR *USDR `json:"usdr"` + + WhitelistedTokensCount *big.Int `json:"-"` + + UseSwapPricing bool // not used, always false for now +} + +func NewVault() *Vault { + return &Vault{ + PoolAmounts: make(map[string]*big.Int), + BufferAmounts: make(map[string]*big.Int), + ReservedAmounts: make(map[string]*big.Int), + TokenDecimals: make(map[string]*big.Int), + StableTokens: make(map[string]bool), + USDRAmounts: make(map[string]*big.Int), + MaxUSDRAmounts: make(map[string]*big.Int), + TokenWeights: make(map[string]*big.Int), + } +} + +const ( + vaultMethodHasDynamicFees = "hasDynamicFees" + vaultMethodIncludeAmmPrice = "includeAmmPrice" + vaultMethodIsSwapEnabled = "isSwapEnabled" + vaultMethodPriceFeed = "priceFeed" + vaultMethodStableSwapFeeBasisPoints = "stableSwapFeeBasisPoints" + vaultMethodStableTaxBasisPoints = "stableTaxBasisPoints" + vaultMethodSwapFeeBasisPoints = "swapFeeBasisPoints" + vaultMethodTaxBasisPoints = "taxBasisPoints" + vaultMethodTotalTokenWeights = "totalTokenWeights" + vaultMethodUSDR = "usdr" + vaultMethodWhitelistedTokenCount = "whitelistedTokenCount" + + vaultMethodAllWhitelistedTokens = "allWhitelistedTokens" + + vaultMethodPoolAmounts = "poolAmounts" + vaultMethodBufferAmounts = "bufferAmounts" + vaultMethodReservedAmounts = "reservedAmounts" + vaultMethodTokenDecimals = "tokenDecimals" + vaultMethodStableTokens = "stableTokens" + vaultMethodUSDRAmounts = "usdrAmounts" + vaultMethodMaxUSDRAmounts = "maxUsdrAmounts" + vaultMethodTokenWeights = "tokenWeights" +) + +func (v *Vault) GetMinPrice(token string) (*big.Int, error) { + return v.PriceFeed.GetPrice(token, false, v.IncludeAmmPrice, v.UseSwapPricing) +} + +func (v *Vault) GetMaxPrice(token string) (*big.Int, error) { + return v.PriceFeed.GetPrice(token, true, v.IncludeAmmPrice, v.UseSwapPricing) +} + +func (v *Vault) GetTargetUSDRAmount(token string) *big.Int { + supply := v.USDR.TotalSupply + + if supply.Cmp(bignumber.ZeroBI) == 0 { + return bignumber.ZeroBI + } + + weight := v.TokenWeights[token] + + return new(big.Int).Div(new(big.Int).Mul(weight, supply), v.TotalTokenWeights) +} + +func (v *Vault) AdjustForDecimals(amount *big.Int, tokenDiv string, tokenMul string) *big.Int { + var decimalsDiv *big.Int + if tokenDiv == v.USDR.Address { + decimalsDiv = USDRDecimals + } else { + decimalsDiv = v.TokenDecimals[tokenDiv] + } + + var decimalsMul *big.Int + if tokenMul == v.USDR.Address { + decimalsMul = USDRDecimals + } else { + decimalsMul = v.TokenDecimals[tokenMul] + } + + return new(big.Int).Div( + new(big.Int).Mul( + amount, + new(big.Int).Exp(big.NewInt(10), decimalsMul, nil), + ), + new(big.Int).Exp(big.NewInt(10), decimalsDiv, nil), + ) +} + +func (v *Vault) IncreaseUSDRAmount(token string, amount *big.Int) { + v.USDRAmounts[token] = new(big.Int).Add(v.USDRAmounts[token], amount) +} + +func (v *Vault) DecreaseUSDRAmount(token string, amount *big.Int) { + currentUSDRAmount := v.USDRAmounts[token] + + if currentUSDRAmount.Cmp(amount) < 0 { + v.USDRAmounts[token] = bignumber.ZeroBI + return + } + + v.USDRAmounts[token] = new(big.Int).Sub(v.USDRAmounts[token], amount) +} + +func (v *Vault) IncreasePoolAmount(token string, amount *big.Int) { + v.PoolAmounts[token] = new(big.Int).Add(v.PoolAmounts[token], amount) +} + +func (v *Vault) DecreasePoolAmount(token string, amount *big.Int) { + v.PoolAmounts[token] = new(big.Int).Sub(v.PoolAmounts[token], amount) +} diff --git a/pkg/source/rollup-finance/vault_price_feed.go b/pkg/source/rollup-finance/vault_price_feed.go new file mode 100644 index 000000000..bb70fa202 --- /dev/null +++ b/pkg/source/rollup-finance/vault_price_feed.go @@ -0,0 +1,476 @@ +package gmx + +import ( + "encoding/json" + "math/big" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber" + "github.com/ethereum/go-ethereum/common" +) + +type VaultPriceFeed struct { + BNB string `json:"bnb"` + BTC string `json:"btc"` + ETH string `json:"eth"` + FavorPrimaryPrice bool `json:"favorPrimaryPrice"` + IsAmmEnabled bool `json:"isAmmEnabled"` + IsSecondaryPriceEnabled bool `json:"isSecondaryPriceEnabled"` + MaxStrictPriceDeviation *big.Int `json:"maxStrictPriceDeviation"` + PriceSampleSpace *big.Int `json:"priceSampleSpace"` + SpreadThresholdBasisPoints *big.Int `json:"spreadThresholdBasisPoints"` + UseV2Pricing bool `json:"useV2Pricing"` + + PriceDecimals map[string]*big.Int `json:"priceDecimals"` + SpreadBasisPoints map[string]*big.Int `json:"spreadBasisPoints"` + AdjustmentBasisPoints map[string]*big.Int `json:"adjustmentBasisPoints"` + StrictStableTokens map[string]bool `json:"strictStableTokens"` + IsAdjustmentAdditive map[string]bool `json:"isAdjustmentAdditive"` + + BNBBUSDAddress common.Address `json:"-"` + BNBBUSD *PancakePair `json:"bnbBusd,omitempty"` + + BTCBNBAddress common.Address `json:"-"` + BTCBNB *PancakePair `json:"btcBnb,omitempty"` + + ETHBNBAddress common.Address `json:"-"` + ETHBNB *PancakePair `json:"ethBnb,omitempty"` + + ChainlinkFlagsAddress common.Address `json:"-"` + ChainlinkFlags *ChainlinkFlags `json:"chainlinkFlags,omitempty"` + + SecondaryPriceFeedAddress common.Address `json:"-"` + SecondaryPriceFeed IFastPriceFeed `json:"secondaryPriceFeed"` + SecondaryPriceFeedVersion int `json:"secondaryPriceFeedVersion"` + + PriceFeedsAddresses map[string]common.Address `json:"-"` + PriceFeeds map[string]*PriceFeed `json:"priceFeeds"` +} + +func NewVaultPriceFeed() *VaultPriceFeed { + return &VaultPriceFeed{ + PriceDecimals: make(map[string]*big.Int), + SpreadBasisPoints: make(map[string]*big.Int), + AdjustmentBasisPoints: make(map[string]*big.Int), + StrictStableTokens: make(map[string]bool), + IsAdjustmentAdditive: make(map[string]bool), + PriceFeedsAddresses: make(map[string]common.Address), + PriceFeeds: make(map[string]*PriceFeed), + } +} + +const ( + vaultPriceFeedMethodBNB = "bnb" + vaultPriceFeedMethodBNBBUSD = "bnbBusd" + vaultPriceFeedMethodBTC = "btc" + vaultPriceFeedMethodBTCBNB = "btcBnb" + vaultPriceFeedMethodChainlinkFlags = "chainlinkFlags" + vaultPriceFeedMethodETH = "eth" + vaultPriceFeedMethodETHBNB = "ethBnb" + vaultPriceFeedMethodFavorPrimaryPrice = "favorPrimaryPrice" + vaultPriceFeedMethodIsAmmEnabled = "isAmmEnabled" + vaultPriceFeedMethodIsSecondaryPriceEnabled = "isSecondaryPriceEnabled" + vaultPriceFeedMethodMaxStrictPriceDeviation = "maxStrictPriceDeviation" + vaultPriceFeedMethodPriceSampleSpace = "priceSampleSpace" + vaultPriceFeedMethodSecondaryPriceFeed = "secondaryPriceFeed" + vaultPriceFeedMethodSpreadThresholdBasisPoints = "spreadThresholdBasisPoints" + vaultPriceFeedMethodUseV2Pricing = "useV2Pricing" + + vaultPriceFeedMethodPriceFeeds = "priceFeeds" + vaultPriceFeedMethodPriceDecimals = "priceDecimals" + vaultPriceFeedMethodSpreadBasisPoints = "spreadBasisPoints" + vaultPriceFeedMethodAdjustmentBasisPoints = "adjustmentBasisPoints" + vaultPriceFeedMethodStrictStableTokens = "strictStableTokens" + vaultPriceFeedMethodIsAdjustmentAdditive = "isAdjustmentAdditive" +) + +func (pf *VaultPriceFeed) UnmarshalJSON(bytes []byte) error { + var priceFeed struct { + BNB string `json:"bnb"` + BTC string `json:"btc"` + ETH string `json:"eth"` + FavorPrimaryPrice bool `json:"favorPrimaryPrice"` + IsAmmEnabled bool `json:"isAmmEnabled"` + IsSecondaryPriceEnabled bool `json:"isSecondaryPriceEnabled"` + MaxStrictPriceDeviation *big.Int `json:"maxStrictPriceDeviation"` + PriceSampleSpace *big.Int `json:"priceSampleSpace"` + SpreadThresholdBasisPoints *big.Int `json:"spreadThresholdBasisPoints"` + UseV2Pricing bool `json:"useV2Pricing"` + PriceDecimals map[string]*big.Int `json:"priceDecimals"` + SpreadBasisPoints map[string]*big.Int `json:"spreadBasisPoints"` + AdjustmentBasisPoints map[string]*big.Int `json:"adjustmentBasisPoints"` + StrictStableTokens map[string]bool `json:"strictStableTokens"` + IsAdjustmentAdditive map[string]bool `json:"isAdjustmentAdditive"` + BNBBUSD *PancakePair `json:"bnbBusd,omitempty"` + BTCBNB *PancakePair `json:"btcBnb,omitempty"` + ETHBNB *PancakePair `json:"ethBnb,omitempty"` + ChainlinkFlags *ChainlinkFlags `json:"chainlinkFlags,omitempty"` + SecondaryPriceFeedVersion int `json:"secondaryPriceFeedVersion"` + PriceFeeds map[string]*PriceFeed `json:"priceFeeds"` + } + + if err := json.Unmarshal(bytes, &priceFeed); err != nil { + return err + } + + pf.BNB = priceFeed.BNB + pf.BTC = priceFeed.BTC + pf.ETH = priceFeed.ETH + pf.FavorPrimaryPrice = priceFeed.FavorPrimaryPrice + pf.IsAmmEnabled = priceFeed.IsAmmEnabled + pf.IsSecondaryPriceEnabled = priceFeed.IsSecondaryPriceEnabled + pf.MaxStrictPriceDeviation = priceFeed.MaxStrictPriceDeviation + pf.PriceSampleSpace = priceFeed.PriceSampleSpace + pf.SpreadThresholdBasisPoints = priceFeed.SpreadThresholdBasisPoints + pf.UseV2Pricing = priceFeed.UseV2Pricing + pf.PriceDecimals = priceFeed.PriceDecimals + pf.SpreadBasisPoints = priceFeed.SpreadBasisPoints + pf.AdjustmentBasisPoints = priceFeed.AdjustmentBasisPoints + pf.StrictStableTokens = priceFeed.StrictStableTokens + pf.IsAdjustmentAdditive = priceFeed.IsAdjustmentAdditive + pf.BNBBUSD = priceFeed.BNBBUSD + pf.BTCBNB = priceFeed.BTCBNB + pf.ETHBNB = priceFeed.ETHBNB + pf.ChainlinkFlags = priceFeed.ChainlinkFlags + pf.SecondaryPriceFeedVersion = priceFeed.SecondaryPriceFeedVersion + pf.PriceFeeds = priceFeed.PriceFeeds + + if err := pf.UnmarshalJSONSecondaryPriceFeed(bytes); err != nil { + return err + } + + return nil +} + +func (pf *VaultPriceFeed) UnmarshalJSONSecondaryPriceFeed(bytes []byte) error { + switch pf.SecondaryPriceFeedVersion { + case 1: + var priceFeed struct { + SecondaryPriceFeed *FastPriceFeedV1 `json:"secondaryPriceFeed"` + } + + if err := json.Unmarshal(bytes, &priceFeed); err != nil { + return nil + } + + pf.SecondaryPriceFeed = priceFeed.SecondaryPriceFeed + case 2: + var priceFeed struct { + SecondaryPriceFeed *FastPriceFeedV2 `json:"secondaryPriceFeed"` + } + + if err := json.Unmarshal(bytes, &priceFeed); err != nil { + return nil + } + + pf.SecondaryPriceFeed = priceFeed.SecondaryPriceFeed + default: + return ErrInvalidSecondaryPriceFeedVersion + } + + return nil +} + +func (pf *VaultPriceFeed) GetPrice(token string, maximise bool, includeAmmPrice bool, _ bool) (*big.Int, error) { + var price *big.Int + var err error + + if pf.UseV2Pricing { + price, err = pf.getPriceV2(token, maximise, includeAmmPrice) + if err != nil { + return nil, err + } + } else { + price, err = pf.getPriceV1(token, maximise, includeAmmPrice) + if err != nil { + return nil, err + } + } + + adjustmentBps := pf.AdjustmentBasisPoints[token] + + if adjustmentBps.Cmp(bignumber.ZeroBI) > 0 { + isAdditive := pf.IsAdjustmentAdditive[token] + + if isAdditive { + price = new(big.Int).Div( + new(big.Int).Mul( + price, + new(big.Int).Add(BasisPointsDivisor, adjustmentBps), + ), + BasisPointsDivisor, + ) + } else { + price = new(big.Int).Div( + new(big.Int).Mul( + price, + new(big.Int).Sub(BasisPointsDivisor, adjustmentBps), + ), + BasisPointsDivisor, + ) + } + } + + return price, nil +} + +func (pf *VaultPriceFeed) getPriceV1(token string, maximise bool, includeAmmPrice bool) (*big.Int, error) { + price, err := pf.getPrimaryPrice(token, maximise) + if err != nil { + return nil, err + } + + if includeAmmPrice && pf.IsAmmEnabled { + ammPrice := pf.getAmmPrice(token) + if ammPrice.Cmp(bignumber.ZeroBI) > 0 { + if maximise && ammPrice.Cmp(price) > 0 { + price = ammPrice + } + if !maximise && ammPrice.Cmp(price) < 0 { + price = ammPrice + } + } + } + + if pf.IsSecondaryPriceEnabled { + price = pf.getSecondaryPrice(token, price, maximise) + } + + if pf.StrictStableTokens[token] { + var delta *big.Int + if price.Cmp(OneUSD) > 0 { + delta = new(big.Int).Sub(price, OneUSD) + } else { + delta = new(big.Int).Sub(OneUSD, price) + } + + if delta.Cmp(pf.MaxStrictPriceDeviation) <= 0 { + return OneUSD, nil + } + + if maximise && price.Cmp(OneUSD) > 0 { + return price, nil + } + + if !maximise && price.Cmp(OneUSD) < 0 { + return price, nil + } + + return OneUSD, nil + } + + spreadBasisPoint := pf.SpreadBasisPoints[token] + + if maximise { + return new(big.Int).Div( + new(big.Int).Mul( + price, + new(big.Int).Add(BasisPointsDivisor, spreadBasisPoint), + ), + BasisPointsDivisor, + ), nil + } + + return new(big.Int).Div( + new(big.Int).Mul( + price, + new(big.Int).Sub(BasisPointsDivisor, spreadBasisPoint), + ), + BasisPointsDivisor, + ), nil +} + +func (pf *VaultPriceFeed) getPriceV2(token string, maximise bool, includeAmmPrice bool) (*big.Int, error) { + price, err := pf.getPrimaryPrice(token, maximise) + if err != nil { + return nil, err + } + + if includeAmmPrice && pf.IsAmmEnabled { + price = pf.getAmmPriceV2(token, maximise, price) + } + + if pf.IsSecondaryPriceEnabled { + price = pf.getSecondaryPrice(token, price, maximise) + } + + if pf.StrictStableTokens[token] { + var delta *big.Int + if price.Cmp(OneUSD) > 0 { + delta = new(big.Int).Sub(price, OneUSD) + } else { + delta = new(big.Int).Sub(OneUSD, price) + } + + if delta.Cmp(pf.MaxStrictPriceDeviation) <= 0 { + return OneUSD, nil + } + + if maximise && price.Cmp(OneUSD) > 0 { + return price, nil + } + + if !maximise && price.Cmp(OneUSD) < 0 { + return price, nil + } + + return OneUSD, nil + } + + spreadBasisPoint := pf.SpreadBasisPoints[token] + + if maximise { + return new(big.Int).Div( + new(big.Int).Mul( + price, + new(big.Int).Add(BasisPointsDivisor, spreadBasisPoint), + ), + BasisPointsDivisor, + ), nil + } + + return new(big.Int).Div( + new(big.Int).Mul( + price, + new(big.Int).Sub(BasisPointsDivisor, spreadBasisPoint), + ), + BasisPointsDivisor, + ), nil +} + +func (pf *VaultPriceFeed) getPrimaryPrice(token string, maximise bool) (*big.Int, error) { + priceFeed, ok := pf.PriceFeeds[token] + if !ok { + return nil, ErrVaultPriceFeedInvalidPriceFeed + } + + if pf.ChainlinkFlags != nil { + isRaised := pf.ChainlinkFlags.GetFlag(FlagArbitrumSeqOffline) + + if isRaised { + return nil, ErrVaultPriceFeedChainlinkFeedsNotUpdated + } + } + + price := bignumber.ZeroBI + roundID := priceFeed.LatestRound() + + for i := big.NewInt(0); i.Cmp(pf.PriceSampleSpace) < 0; i = new(big.Int).Add(i, big.NewInt(1)) { + if roundID.Cmp(i) <= 0 { + break + } + + var p *big.Int + if i.Cmp(bignumber.ZeroBI) == 0 { + p = priceFeed.LatestAnswer() + + if p.Cmp(bignumber.ZeroBI) <= 0 { + return nil, ErrVaultPriceFeedInvalidPrice + } + } else { + _, p, _, _, _ = priceFeed.GetRoundData(new(big.Int).Sub(roundID, bignumber.One)) + + if p.Cmp(bignumber.ZeroBI) <= 0 { + return nil, ErrVaultPriceFeedInvalidPrice + } + } + + if price.Cmp(bignumber.ZeroBI) == 0 { + price = p + continue + } + + if !maximise && p.Cmp(price) < 0 { + price = p + } + } + + if price.Cmp(bignumber.ZeroBI) <= 0 { + return nil, ErrVaultPriceFeedCouldNotFetchPrice + } + + priceDecimal := pf.PriceDecimals[token] + + return new(big.Int).Div( + new(big.Int).Mul(price, PricePrecision), + new(big.Int).Exp(big.NewInt(10), priceDecimal, nil), + ), nil +} + +func (pf *VaultPriceFeed) getSecondaryPrice(token string, referencePrice *big.Int, maximise bool) *big.Int { + if pf.SecondaryPriceFeed == nil { + return referencePrice + } + + return pf.SecondaryPriceFeed.GetPrice(token, referencePrice, maximise) +} + +func (pf *VaultPriceFeed) getAmmPrice(token string) *big.Int { + if token == pf.BNB { + return pf.getPairPrice(pf.BNBBUSD, true) + } + + if token == pf.ETH { + price0 := pf.getPairPrice(pf.BNBBUSD, true) + price1 := pf.getPairPrice(pf.ETHBNB, true) + + return new(big.Int).Div(new(big.Int).Mul(price0, price1), PricePrecision) + } + + if token == pf.BTC { + price0 := pf.getPairPrice(pf.BNBBUSD, true) + price1 := pf.getPairPrice(pf.BTCBNB, true) + + return new(big.Int).Div(new(big.Int).Mul(price0, price1), PricePrecision) + } + + return bignumber.ZeroBI +} + +func (pf *VaultPriceFeed) getAmmPriceV2(token string, maximise bool, primaryPrice *big.Int) *big.Int { + ammPrice := pf.getAmmPrice(token) + if ammPrice.Cmp(bignumber.ZeroBI) == 0 { + return primaryPrice + } + + var diff *big.Int + if ammPrice.Cmp(primaryPrice) > 0 { + diff = new(big.Int).Sub(ammPrice, primaryPrice) + } else { + diff = new(big.Int).Sub(primaryPrice, ammPrice) + } + + if new(big.Int).Mul(diff, BasisPointsDivisor).Cmp(new(big.Int).Mul(primaryPrice, pf.SpreadThresholdBasisPoints)) < 0 { + if pf.FavorPrimaryPrice { + return primaryPrice + } + return ammPrice + } + + if maximise && ammPrice.Cmp(primaryPrice) > 0 { + return ammPrice + } + + if !maximise && ammPrice.Cmp(primaryPrice) < 0 { + return ammPrice + } + + return primaryPrice +} + +func (pf *VaultPriceFeed) getPairPrice(pair *PancakePair, divByReserve0 bool) *big.Int { + reserve0, reserve1, _ := pair.GetReserves() + + if divByReserve0 { + if reserve0.Cmp(bignumber.ZeroBI) == 0 { + return bignumber.ZeroBI + } + + return new(big.Int).Div(new(big.Int).Mul(reserve1, PricePrecision), reserve0) + } + + if reserve1.Cmp(bignumber.ZeroBI) == 0 { + return bignumber.ZeroBI + } + + return new(big.Int).Div(new(big.Int).Mul(reserve0, PricePrecision), reserve1) +} diff --git a/pkg/source/rollup-finance/vault_price_feed_reader.go b/pkg/source/rollup-finance/vault_price_feed_reader.go new file mode 100644 index 000000000..e9e8b51d9 --- /dev/null +++ b/pkg/source/rollup-finance/vault_price_feed_reader.go @@ -0,0 +1,156 @@ +package gmx + +import ( + "context" + "math/big" + "strings" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +type VaultPriceFeedReader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewVaultPriceFeedReader(ethrpcClient *ethrpc.Client) *VaultPriceFeedReader { + return &VaultPriceFeedReader{ + abi: vaultPriceFeedABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "VaultPriceFeedReader", + }), + } +} + +func (r *VaultPriceFeedReader) Read( + ctx context.Context, + address string, + tokens []string, +) (*VaultPriceFeed, error) { + vaultPriceFeed := NewVaultPriceFeed() + + if err := r.readData(ctx, address, vaultPriceFeed); err != nil { + r.log.Errorf("error when read data: %s", err) + return nil, err + } + + if err := r.readTokenData(ctx, address, vaultPriceFeed, tokens); err != nil { + r.log.Errorf("error when read token data: %s", err) + return nil, err + } + + return vaultPriceFeed, nil +} + +// readData reads data which required no parameters, included: +// - BNB +// - BNBBUSD +// - BTC +// - BTCBNB +// - ChainlinkFlags +// - ETH +// - ETHBNB +// - FavorPrimaryPrice +// - IsAmmEnabled +// - IsSecondaryPriceEnabled +// - MaxStrictPriceDeviation +// - PriceSampleSpace +// - SecondaryPriceFeed +// - SpreadThresholdBasisPoints +// - UseV2Pricing +func (r *VaultPriceFeedReader) readData( + ctx context.Context, + address string, + vaultPriceFeed *VaultPriceFeed, +) error { + var bnb, btc, eth common.Address + + callParamsFactory := CallParamsFactory(r.abi, address) + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodBNB, nil), []interface{}{&bnb}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodBNBBUSD, nil), []interface{}{&vaultPriceFeed.BNBBUSDAddress}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodBTC, nil), []interface{}{&btc}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodBTCBNB, nil), []interface{}{&vaultPriceFeed.BTCBNBAddress}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodChainlinkFlags, nil), []interface{}{&vaultPriceFeed.ChainlinkFlagsAddress}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodETH, nil), []interface{}{ð}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodETHBNB, nil), []interface{}{&vaultPriceFeed.ETHBNBAddress}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodFavorPrimaryPrice, nil), []interface{}{&vaultPriceFeed.FavorPrimaryPrice}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodIsAmmEnabled, nil), []interface{}{&vaultPriceFeed.IsAmmEnabled}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodIsSecondaryPriceEnabled, nil), []interface{}{&vaultPriceFeed.IsSecondaryPriceEnabled}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodMaxStrictPriceDeviation, nil), []interface{}{&vaultPriceFeed.MaxStrictPriceDeviation}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodPriceSampleSpace, nil), []interface{}{&vaultPriceFeed.PriceSampleSpace}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodSecondaryPriceFeed, nil), []interface{}{&vaultPriceFeed.SecondaryPriceFeedAddress}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodSpreadThresholdBasisPoints, nil), []interface{}{&vaultPriceFeed.SpreadThresholdBasisPoints}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodUseV2Pricing, nil), []interface{}{&vaultPriceFeed.UseV2Pricing}) + + if _, err := rpcRequest.TryAggregate(); err != nil { + r.log.Errorf("error when call aggreate request: %s", err) + return err + } + + vaultPriceFeed.BNB = strings.ToLower(bnb.String()) + vaultPriceFeed.BTC = strings.ToLower(btc.String()) + vaultPriceFeed.ETH = strings.ToLower(eth.String()) + + return nil +} + +// readTokenData reads data which required token address as parameter, included: +// - PriceFeedsAddresses +// - PriceDecimals +// - SpreadBasisPoints +// - AdjustmentBasisPoints +// - StrictStableTokens +// - IsAdjustmentAdditive +func (r *VaultPriceFeedReader) readTokenData( + ctx context.Context, + address string, + vaultPriceFeed *VaultPriceFeed, + tokens []string, +) error { + tokensLen := len(tokens) + + priceFeedsAddresses := make([]common.Address, tokensLen) + priceDecimals := make([]*big.Int, tokensLen) + spreadBasisPoints := make([]*big.Int, tokensLen) + adjustmentBasisPoints := make([]*big.Int, tokensLen) + strictStableTokens := make([]bool, tokensLen) + isAdjustmentAdditive := make([]bool, tokensLen) + + callParamsFactory := CallParamsFactory(r.abi, address) + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + for i, token := range tokens { + tokenAddress := common.HexToAddress(token) + + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodPriceFeeds, []interface{}{tokenAddress}), []interface{}{&priceFeedsAddresses[i]}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodPriceDecimals, []interface{}{tokenAddress}), []interface{}{&priceDecimals[i]}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodSpreadBasisPoints, []interface{}{tokenAddress}), []interface{}{&spreadBasisPoints[i]}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodAdjustmentBasisPoints, []interface{}{tokenAddress}), []interface{}{&adjustmentBasisPoints[i]}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodStrictStableTokens, []interface{}{tokenAddress}), []interface{}{&strictStableTokens[i]}) + rpcRequest.AddCall(callParamsFactory(vaultPriceFeedMethodIsAdjustmentAdditive, []interface{}{tokenAddress}), []interface{}{&isAdjustmentAdditive[i]}) + } + + if _, err := rpcRequest.TryAggregate(); err != nil { + r.log.Errorf("error when call aggreate request: %s", err) + return err + } + + for i, token := range tokens { + vaultPriceFeed.PriceFeedsAddresses[token] = priceFeedsAddresses[i] + vaultPriceFeed.PriceDecimals[token] = priceDecimals[i] + vaultPriceFeed.SpreadBasisPoints[token] = spreadBasisPoints[i] + vaultPriceFeed.AdjustmentBasisPoints[token] = adjustmentBasisPoints[i] + vaultPriceFeed.StrictStableTokens[token] = strictStableTokens[i] + vaultPriceFeed.IsAdjustmentAdditive[token] = isAdjustmentAdditive[i] + } + + return nil +} diff --git a/pkg/source/rollup-finance/vault_reader.go b/pkg/source/rollup-finance/vault_reader.go new file mode 100644 index 000000000..c9fa28f33 --- /dev/null +++ b/pkg/source/rollup-finance/vault_reader.go @@ -0,0 +1,173 @@ +package gmx + +import ( + "context" + "math/big" + "strings" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +type VaultReader struct { + abi abi.ABI + ethrpcClient *ethrpc.Client + log logger.Logger +} + +func NewVaultReader(ethrpcClient *ethrpc.Client) *VaultReader { + return &VaultReader{ + abi: vaultABI, + ethrpcClient: ethrpcClient, + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "reader": "VaultReader", + }), + } +} + +// Read reads all data required for finding route +func (r *VaultReader) Read(ctx context.Context, address string) (*Vault, error) { + vault := NewVault() + + if err := r.readData(ctx, address, vault); err != nil { + r.log.Errorf("error when read data: %s", err) + return nil, err + } + + if err := r.readWhitelistedTokens(ctx, address, vault); err != nil { + r.log.Errorf("error when read white listed token: %s", err) + return nil, err + } + + if err := r.readTokensData(ctx, address, vault); err != nil { + r.log.Errorf("error when read tokens data: %s", err) + return nil, err + } + + return vault, nil +} + +// readData reads data which required no parameters, included: +// - HasDynamicFees +// - IncludeAmmPrice +// - IsSwapEnabled +// - PriceFeedAddress +// - StableSwapFeeBasisPoints +// - StableTaxBasisPoints +// - SwapFeeBasisPoints +// - TaxBasisPoints +// - TotalTokenWeights +// - USDRAddress +// - WhitelistedTokensCount +func (r *VaultReader) readData(ctx context.Context, address string, vault *Vault) error { + callParamsFactory := CallParamsFactory(r.abi, address) + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + rpcRequest.AddCall(callParamsFactory(vaultMethodHasDynamicFees, nil), []interface{}{&vault.HasDynamicFees}) + rpcRequest.AddCall(callParamsFactory(vaultMethodIncludeAmmPrice, nil), []interface{}{&vault.IncludeAmmPrice}) + rpcRequest.AddCall(callParamsFactory(vaultMethodIsSwapEnabled, nil), []interface{}{&vault.IsSwapEnabled}) + rpcRequest.AddCall(callParamsFactory(vaultMethodPriceFeed, nil), []interface{}{&vault.PriceFeedAddress}) + rpcRequest.AddCall(callParamsFactory(vaultMethodStableSwapFeeBasisPoints, nil), []interface{}{&vault.StableSwapFeeBasisPoints}) + rpcRequest.AddCall(callParamsFactory(vaultMethodStableTaxBasisPoints, nil), []interface{}{&vault.StableTaxBasisPoints}) + rpcRequest.AddCall(callParamsFactory(vaultMethodSwapFeeBasisPoints, nil), []interface{}{&vault.SwapFeeBasisPoints}) + rpcRequest.AddCall(callParamsFactory(vaultMethodTaxBasisPoints, nil), []interface{}{&vault.TaxBasisPoints}) + rpcRequest.AddCall(callParamsFactory(vaultMethodTotalTokenWeights, nil), []interface{}{&vault.TotalTokenWeights}) + rpcRequest.AddCall(callParamsFactory(vaultMethodUSDR, nil), []interface{}{&vault.USDRAddress}) + rpcRequest.AddCall(callParamsFactory(vaultMethodWhitelistedTokenCount, nil), []interface{}{&vault.WhitelistedTokensCount}) + + _, err := rpcRequest.TryAggregate() + + return err +} + +// readWhitelistedTokens reads whitelistedTokens +func (r *VaultReader) readWhitelistedTokens( + ctx context.Context, + address string, + vault *Vault, +) error { + tokensLen := int(vault.WhitelistedTokensCount.Int64()) + + whitelistedTokens := make([]common.Address, tokensLen) + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + + for i := 0; i < tokensLen; i++ { + rpcRequest.AddCall(ðrpc.Call{ + ABI: r.abi, + Target: address, + Method: vaultMethodAllWhitelistedTokens, + Params: []interface{}{new(big.Int).SetInt64(int64(i))}, + }, []interface{}{&whitelistedTokens[i]}) + } + if _, err := rpcRequest.TryAggregate(); err != nil { + return err + } + + tokens := make([]string, tokensLen) + for i := range whitelistedTokens { + tokens[i] = strings.ToLower(whitelistedTokens[i].String()) + } + + vault.WhitelistedTokens = tokens + + return nil +} + +// readTokensData reads data which required token address as parameter, included: +// - PoolAmounts +// - TokenDecimals +// - StableTokens +// - USDRAmounts +// - MaxUSDRAmounts +// - TokenWeights +func (r *VaultReader) readTokensData( + ctx context.Context, + address string, + vault *Vault, +) error { + tokensLen := len(vault.WhitelistedTokens) + poolAmounts := make([]*big.Int, tokensLen) + bufferAmounts := make([]*big.Int, tokensLen) + reservedAmounts := make([]*big.Int, tokensLen) + tokenDecimals := make([]*big.Int, tokensLen) + stableTokens := make([]bool, tokensLen) + usdrAmounts := make([]*big.Int, tokensLen) + maxUSDRAmounts := make([]*big.Int, tokensLen) + tokenWeights := make([]*big.Int, tokensLen) + + rpcRequest := r.ethrpcClient.NewRequest().SetContext(ctx) + callParamsFactory := CallParamsFactory(r.abi, address) + + for i, token := range vault.WhitelistedTokens { + tokenAddress := common.HexToAddress(token) + + rpcRequest.AddCall(callParamsFactory(vaultMethodPoolAmounts, []interface{}{tokenAddress}), []interface{}{&poolAmounts[i]}) + rpcRequest.AddCall(callParamsFactory(vaultMethodBufferAmounts, []interface{}{tokenAddress}), []interface{}{&bufferAmounts[i]}) + rpcRequest.AddCall(callParamsFactory(vaultMethodReservedAmounts, []interface{}{tokenAddress}), []interface{}{&reservedAmounts[i]}) + rpcRequest.AddCall(callParamsFactory(vaultMethodTokenDecimals, []interface{}{tokenAddress}), []interface{}{&tokenDecimals[i]}) + rpcRequest.AddCall(callParamsFactory(vaultMethodStableTokens, []interface{}{tokenAddress}), []interface{}{&stableTokens[i]}) + rpcRequest.AddCall(callParamsFactory(vaultMethodUSDRAmounts, []interface{}{tokenAddress}), []interface{}{&usdrAmounts[i]}) + rpcRequest.AddCall(callParamsFactory(vaultMethodMaxUSDRAmounts, []interface{}{tokenAddress}), []interface{}{&maxUSDRAmounts[i]}) + rpcRequest.AddCall(callParamsFactory(vaultMethodTokenWeights, []interface{}{tokenAddress}), []interface{}{&tokenWeights[i]}) + } + + if _, err := rpcRequest.TryAggregate(); err != nil { + return err + } + + for i, token := range vault.WhitelistedTokens { + vault.PoolAmounts[token] = poolAmounts[i] + vault.BufferAmounts[token] = bufferAmounts[i] + vault.ReservedAmounts[token] = reservedAmounts[i] + vault.TokenDecimals[token] = tokenDecimals[i] + vault.StableTokens[token] = stableTokens[i] + vault.USDRAmounts[token] = usdrAmounts[i] + vault.MaxUSDRAmounts[token] = maxUSDRAmounts[i] + vault.TokenWeights[token] = tokenWeights[i] + } + + return nil +} diff --git a/pkg/source/rollup-finance/vault_scanner.go b/pkg/source/rollup-finance/vault_scanner.go new file mode 100644 index 000000000..f34f81d77 --- /dev/null +++ b/pkg/source/rollup-finance/vault_scanner.go @@ -0,0 +1,182 @@ +package gmx + +import ( + "context" + "math/big" + + "github.com/KyberNetwork/ethrpc" + "github.com/KyberNetwork/logger" + "github.com/ethereum/go-ethereum/common" + + "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/eth" +) + +type VaultScanner struct { + config *Config + vaultReader IVaultReader + vaultPriceFeedReader IVaultPriceFeedReader + fastPriceFeedV1Reader IFastPriceFeedV1Reader + fastPriceFeedV2Reader IFastPriceFeedV2Reader + priceFeedReader IPriceFeedReader + usdrReader IUSDRReader + chainlinkFlagsReader IChainlinkFlagsReader + pancakePairReader IPancakePairReader + log logger.Logger +} + +func NewVaultScanner( + config *Config, + ethrpcClient *ethrpc.Client, +) *VaultScanner { + return &VaultScanner{ + config: config, + vaultReader: NewVaultReader(ethrpcClient), + vaultPriceFeedReader: NewVaultPriceFeedReader(ethrpcClient), + fastPriceFeedV1Reader: NewFastPriceFeedV1Reader(ethrpcClient), + fastPriceFeedV2Reader: NewFastPriceFeedV2Reader(ethrpcClient), + priceFeedReader: NewPriceFeedReader(ethrpcClient), + usdrReader: NewUSDRReader(ethrpcClient), + chainlinkFlagsReader: NewChainlinkFlagsReader(ethrpcClient), + pancakePairReader: NewPancakePairReader(ethrpcClient), + log: logger.WithFields(logger.Fields{ + "liquiditySource": DexTypeGmx, + "scanner": "VaultScanner", + }), + } +} + +func (vs *VaultScanner) getVault(ctx context.Context, address string) (*Vault, error) { + vault, err := vs.vaultReader.Read(ctx, address) + if err != nil { + vs.log.Errorf("error when vaultReader read: %s", err) + return nil, err + } + + usdr, err := vs.usdrReader.Read(ctx, vault.USDRAddress.String()) + if err != nil { + vs.log.Errorf("error when usdrReader read: %s", err) + return nil, err + } + + vault.USDR = usdr + + vaultPriceFeed, err := vs.getVaultPriceFeed(ctx, vault.PriceFeedAddress.String(), vault.WhitelistedTokens) + if err != nil { + vs.log.Errorf("error when get vaultPriceFeed: %s", err) + return nil, err + } + + vault.PriceFeed = vaultPriceFeed + + return vault, nil +} + +// ================================================================================ + +func (vs *VaultScanner) getVaultPriceFeed(ctx context.Context, address string, tokens []string) (*VaultPriceFeed, error) { + vaultPriceFeed, err := vs.vaultPriceFeedReader.Read(ctx, address, tokens) + if err != nil { + return nil, err + } + + if !eth.IsZeroAddress(vaultPriceFeed.ChainlinkFlagsAddress) { + chainlinkFlags, err := vs.chainlinkFlagsReader.Read(ctx, vaultPriceFeed.ChainlinkFlagsAddress.String()) + if err != nil { + return nil, err + } + + vaultPriceFeed.ChainlinkFlags = chainlinkFlags + } + + if !eth.IsZeroAddress(vaultPriceFeed.BNBBUSDAddress) { + bnbBusd, err := vs.pancakePairReader.Read(ctx, vaultPriceFeed.BNBBUSDAddress.String()) + if err != nil { + return nil, err + } + + vaultPriceFeed.BNBBUSD = bnbBusd + } + + if !eth.IsZeroAddress(vaultPriceFeed.BTCBNBAddress) { + btcBnb, err := vs.pancakePairReader.Read(ctx, vaultPriceFeed.BTCBNBAddress.String()) + if err != nil { + return nil, err + } + + vaultPriceFeed.BTCBNB = btcBnb + } + + if !eth.IsZeroAddress(vaultPriceFeed.ETHBNBAddress) { + ethBnb, err := vs.pancakePairReader.Read(ctx, vaultPriceFeed.ETHBNBAddress.String()) + if err != nil { + return nil, err + } + + vaultPriceFeed.ETHBNB = ethBnb + } + + secondaryPriceFeedVersion := vs.getSecondaryPriceFeedVersion() + + vaultPriceFeed.SecondaryPriceFeedVersion = int(secondaryPriceFeedVersion) + + fastPriceFeed, err := vs.getFastPriceFeed( + ctx, + secondaryPriceFeedVersion, + vaultPriceFeed.SecondaryPriceFeedAddress.String(), + tokens, + ) + if err != nil { + return nil, err + } + + vaultPriceFeed.SecondaryPriceFeed = fastPriceFeed + + priceFeeds, err := vs.getPriceFeeds(ctx, vaultPriceFeed.PriceFeedsAddresses, vaultPriceFeed.PriceSampleSpace) + if err != nil { + return nil, err + } + + vaultPriceFeed.PriceFeeds = priceFeeds + + return vaultPriceFeed, nil +} + +func (vs *VaultScanner) getPriceFeeds( + ctx context.Context, + priceFeedAddresses map[string]common.Address, + priceSampleSpace *big.Int, +) (map[string]*PriceFeed, error) { + roundCount := int(priceSampleSpace.Int64()) + priceFeeds := make(map[string]*PriceFeed, len(priceFeedAddresses)) + + for tokenAddress, priceFeedAddress := range priceFeedAddresses { + priceFeed, err := vs.priceFeedReader.Read(ctx, priceFeedAddress.String(), roundCount) + if err != nil { + return nil, err + } + + priceFeeds[tokenAddress] = priceFeed + } + + return priceFeeds, nil +} + +func (vs VaultScanner) getFastPriceFeed( + ctx context.Context, + version SecondaryPriceFeedVersion, + address string, + tokens []string, +) (IFastPriceFeed, error) { + if version == secondaryPriceFeedVersion2 { + return vs.fastPriceFeedV2Reader.Read(ctx, address, tokens) + } + + return vs.fastPriceFeedV1Reader.Read(ctx, address, tokens) +} + +func (vs *VaultScanner) getSecondaryPriceFeedVersion() SecondaryPriceFeedVersion { + if vs.config.UseSecondaryPriceFeedV1 { + return secondaryPriceFeedVersion1 + } + return secondaryPriceFeedVersion2 +} diff --git a/pkg/source/rollup-finance/vault_utils.go b/pkg/source/rollup-finance/vault_utils.go new file mode 100644 index 000000000..b1682e249 --- /dev/null +++ b/pkg/source/rollup-finance/vault_utils.go @@ -0,0 +1,103 @@ +package gmx + +import ( + "math/big" + + constant "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber" +) + +// VaultUtils +// https://github.com/gmx-io/gmx-contracts/blob/master/contracts/core/VaultUtils.sol +type VaultUtils struct { + vault *Vault +} + +func NewVaultUtils(vault *Vault) *VaultUtils { + return &VaultUtils{ + vault: vault, + } +} + +func (u *VaultUtils) GetSwapFeeBasisPoints(tokenIn string, tokenOut string, usdrAmount *big.Int) *big.Int { + isStableSwap := u.vault.StableTokens[tokenIn] && u.vault.StableTokens[tokenOut] + + var baseBps *big.Int + if isStableSwap { + baseBps = u.vault.StableSwapFeeBasisPoints + } else { + baseBps = u.vault.SwapFeeBasisPoints + } + + var taxBps *big.Int + if isStableSwap { + taxBps = u.vault.StableTaxBasisPoints + } else { + taxBps = u.vault.TaxBasisPoints + } + + feeBasisPoints0 := u.GetFeeBasisPoints(tokenIn, usdrAmount, baseBps, taxBps, true) + feeBasisPoints1 := u.GetFeeBasisPoints(tokenOut, usdrAmount, baseBps, taxBps, false) + + if feeBasisPoints0.Cmp(feeBasisPoints1) > 0 { + return feeBasisPoints0 + } else { + return feeBasisPoints1 + } +} + +func (u *VaultUtils) GetFeeBasisPoints(token string, usdrDelta *big.Int, feeBasisPoints *big.Int, taxBasisPoints *big.Int, increment bool) *big.Int { + if !u.vault.HasDynamicFees { + return feeBasisPoints + } + + initialAmount := u.vault.USDRAmounts[token] + nextAmount := new(big.Int).Add(initialAmount, usdrDelta) + + if !increment { + if usdrDelta.Cmp(initialAmount) > 0 { + nextAmount = constant.ZeroBI + } else { + nextAmount = new(big.Int).Sub(initialAmount, usdrDelta) + } + } + + targetAmount := u.vault.GetTargetUSDRAmount(token) + + if targetAmount.Cmp(constant.ZeroBI) == 0 { + return feeBasisPoints + } + + var initialDiff *big.Int + if initialAmount.Cmp(targetAmount) > 0 { + initialDiff = new(big.Int).Sub(initialAmount, targetAmount) + } else { + initialDiff = new(big.Int).Sub(targetAmount, initialAmount) + } + + var nextDiff *big.Int + if nextAmount.Cmp(targetAmount) > 0 { + nextDiff = new(big.Int).Sub(nextAmount, targetAmount) + } else { + nextDiff = new(big.Int).Sub(targetAmount, nextAmount) + } + + if nextDiff.Cmp(initialDiff) < 0 { + rebateBps := new(big.Int).Div(new(big.Int).Mul(taxBasisPoints, initialDiff), targetAmount) + + if rebateBps.Cmp(feeBasisPoints) > 0 { + return constant.ZeroBI + } else { + return new(big.Int).Sub(feeBasisPoints, rebateBps) + } + } + + averageDiff := new(big.Int).Div(new(big.Int).Add(initialDiff, nextDiff), constant.Two) + + if averageDiff.Cmp(targetAmount) > 0 { + averageDiff = targetAmount + } + + taxBps := new(big.Int).Div(new(big.Int).Mul(taxBasisPoints, averageDiff), targetAmount) + + return new(big.Int).Add(feeBasisPoints, taxBps) +} From 5061d9083acfae052ce90381daf3ee0ab3d117a9 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Wed, 15 Nov 2023 15:07:22 +0700 Subject: [PATCH 2/3] wip --- pkg/source/rollup-finance/abis.go | 2 +- pkg/source/rollup-finance/chainlink_flags.go | 2 +- pkg/source/rollup-finance/chainlink_flags_reader.go | 4 ++-- pkg/source/rollup-finance/config.go | 2 +- pkg/source/rollup-finance/constants.go | 4 ++-- pkg/source/rollup-finance/embed.go | 2 +- pkg/source/rollup-finance/errors.go | 2 +- pkg/source/rollup-finance/fast_price_feed_v1.go | 2 +- pkg/source/rollup-finance/fast_price_feed_v1_reader.go | 4 ++-- pkg/source/rollup-finance/fast_price_feed_v2.go | 2 +- pkg/source/rollup-finance/fast_price_feed_v2_reader.go | 4 ++-- pkg/source/rollup-finance/helper.go | 2 +- pkg/source/rollup-finance/iface.go | 2 +- pkg/source/rollup-finance/pancake_pair.go | 2 +- pkg/source/rollup-finance/pancake_pair_reader.go | 4 ++-- pkg/source/rollup-finance/pool_simulator.go | 2 +- pkg/source/rollup-finance/pool_tracker.go | 4 ++-- pkg/source/rollup-finance/pools_list_updater.go | 6 +++--- pkg/source/rollup-finance/price_feed.go | 2 +- pkg/source/rollup-finance/price_feed_reader.go | 4 ++-- pkg/source/rollup-finance/types.go | 2 +- pkg/source/rollup-finance/usdr.go | 2 +- pkg/source/rollup-finance/usdr_reader.go | 4 ++-- pkg/source/rollup-finance/vault.go | 2 +- pkg/source/rollup-finance/vault_price_feed.go | 2 +- pkg/source/rollup-finance/vault_price_feed_reader.go | 4 ++-- pkg/source/rollup-finance/vault_reader.go | 4 ++-- pkg/source/rollup-finance/vault_scanner.go | 4 ++-- pkg/source/rollup-finance/vault_utils.go | 2 +- 29 files changed, 42 insertions(+), 42 deletions(-) diff --git a/pkg/source/rollup-finance/abis.go b/pkg/source/rollup-finance/abis.go index bc4967276..6b10bf638 100644 --- a/pkg/source/rollup-finance/abis.go +++ b/pkg/source/rollup-finance/abis.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "bytes" diff --git a/pkg/source/rollup-finance/chainlink_flags.go b/pkg/source/rollup-finance/chainlink_flags.go index 695e6f48b..864aaaffd 100644 --- a/pkg/source/rollup-finance/chainlink_flags.go +++ b/pkg/source/rollup-finance/chainlink_flags.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance type ChainlinkFlags struct { Flags map[string]bool `json:"flags"` diff --git a/pkg/source/rollup-finance/chainlink_flags_reader.go b/pkg/source/rollup-finance/chainlink_flags_reader.go index 428dd918f..290729177 100644 --- a/pkg/source/rollup-finance/chainlink_flags_reader.go +++ b/pkg/source/rollup-finance/chainlink_flags_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -20,7 +20,7 @@ func NewChainlinkFlagsReader(ethrpcClient *ethrpc.Client) *ChainlinkFlagsReader abi: chainlinkABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "ChainlinkFlagsReader", }), } diff --git a/pkg/source/rollup-finance/config.go b/pkg/source/rollup-finance/config.go index 6997e2d20..40be8ef55 100644 --- a/pkg/source/rollup-finance/config.go +++ b/pkg/source/rollup-finance/config.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance type Config struct { DexID string `json:"-"` diff --git a/pkg/source/rollup-finance/constants.go b/pkg/source/rollup-finance/constants.go index 58535d01f..3481a4de6 100644 --- a/pkg/source/rollup-finance/constants.go +++ b/pkg/source/rollup-finance/constants.go @@ -1,8 +1,8 @@ -package gmx +package rollupfinance import "math/big" -const DexTypeGmx = "gmx" +const DexTypeRollupFinance = "rollup-finance" const flagArbitrumSeqOffline = "0xa438451d6458044c3c8cd2f6f31c91ac882a6d91" diff --git a/pkg/source/rollup-finance/embed.go b/pkg/source/rollup-finance/embed.go index 302ecd42f..1d24ac150 100644 --- a/pkg/source/rollup-finance/embed.go +++ b/pkg/source/rollup-finance/embed.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import _ "embed" diff --git a/pkg/source/rollup-finance/errors.go b/pkg/source/rollup-finance/errors.go index f11b7c09d..5f5a6cb0b 100644 --- a/pkg/source/rollup-finance/errors.go +++ b/pkg/source/rollup-finance/errors.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import "errors" diff --git a/pkg/source/rollup-finance/fast_price_feed_v1.go b/pkg/source/rollup-finance/fast_price_feed_v1.go index 73405b9a3..1fa4aee03 100644 --- a/pkg/source/rollup-finance/fast_price_feed_v1.go +++ b/pkg/source/rollup-finance/fast_price_feed_v1.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "math/big" diff --git a/pkg/source/rollup-finance/fast_price_feed_v1_reader.go b/pkg/source/rollup-finance/fast_price_feed_v1_reader.go index 0002a2667..e89232b59 100644 --- a/pkg/source/rollup-finance/fast_price_feed_v1_reader.go +++ b/pkg/source/rollup-finance/fast_price_feed_v1_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -21,7 +21,7 @@ func NewFastPriceFeedV1Reader(ethrpcClient *ethrpc.Client) *FastPriceFeedV1Reade abi: fastPriceFeedV1ABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "FastPriceFeedV1Reader", }), } diff --git a/pkg/source/rollup-finance/fast_price_feed_v2.go b/pkg/source/rollup-finance/fast_price_feed_v2.go index 561f6ece6..d5510d00f 100644 --- a/pkg/source/rollup-finance/fast_price_feed_v2.go +++ b/pkg/source/rollup-finance/fast_price_feed_v2.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "math/big" diff --git a/pkg/source/rollup-finance/fast_price_feed_v2_reader.go b/pkg/source/rollup-finance/fast_price_feed_v2_reader.go index 10e5abe1c..962e2c94d 100644 --- a/pkg/source/rollup-finance/fast_price_feed_v2_reader.go +++ b/pkg/source/rollup-finance/fast_price_feed_v2_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -21,7 +21,7 @@ func NewFastPriceFeedV2Reader(ethrpcClient *ethrpc.Client) *FastPriceFeedV2Reade abi: fastPriceFeedV2ABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "FastPriceFeedV2Reader", }), } diff --git a/pkg/source/rollup-finance/helper.go b/pkg/source/rollup-finance/helper.go index 6db6939e2..b316c00d7 100644 --- a/pkg/source/rollup-finance/helper.go +++ b/pkg/source/rollup-finance/helper.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "github.com/KyberNetwork/ethrpc" diff --git a/pkg/source/rollup-finance/iface.go b/pkg/source/rollup-finance/iface.go index 21d2673ef..44f24c6ec 100644 --- a/pkg/source/rollup-finance/iface.go +++ b/pkg/source/rollup-finance/iface.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" diff --git a/pkg/source/rollup-finance/pancake_pair.go b/pkg/source/rollup-finance/pancake_pair.go index 1b3b9b11b..4a7858d58 100644 --- a/pkg/source/rollup-finance/pancake_pair.go +++ b/pkg/source/rollup-finance/pancake_pair.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import "math/big" diff --git a/pkg/source/rollup-finance/pancake_pair_reader.go b/pkg/source/rollup-finance/pancake_pair_reader.go index 3ea19f045..01411329c 100644 --- a/pkg/source/rollup-finance/pancake_pair_reader.go +++ b/pkg/source/rollup-finance/pancake_pair_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -20,7 +20,7 @@ func NewPancakePairReader(ethrpcClient *ethrpc.Client) *PancakePairReader { abi: pancakePairABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "PancakePairReader", }), } diff --git a/pkg/source/rollup-finance/pool_simulator.go b/pkg/source/rollup-finance/pool_simulator.go index ecdc5f6d7..fd38b77aa 100644 --- a/pkg/source/rollup-finance/pool_simulator.go +++ b/pkg/source/rollup-finance/pool_simulator.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "encoding/json" diff --git a/pkg/source/rollup-finance/pool_tracker.go b/pkg/source/rollup-finance/pool_tracker.go index 226a4dd44..6a79c686f 100644 --- a/pkg/source/rollup-finance/pool_tracker.go +++ b/pkg/source/rollup-finance/pool_tracker.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -34,7 +34,7 @@ func (d *PoolTracker) GetNewPoolState( _ pool.GetNewPoolStateParams, ) (entity.Pool, error) { log := logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "poolAddress": p.Address, }) log.Info("Start getting new state of pool") diff --git a/pkg/source/rollup-finance/pools_list_updater.go b/pkg/source/rollup-finance/pools_list_updater.go index 1b12f2aa0..1ac6322d6 100644 --- a/pkg/source/rollup-finance/pools_list_updater.go +++ b/pkg/source/rollup-finance/pools_list_updater.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -30,7 +30,7 @@ func NewPoolsListUpdater( func (d *PoolsListUpdater) GetNewPools(ctx context.Context, metadataBytes []byte) ([]entity.Pool, []byte, error) { log := logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "kind": "getNewPools", }) if d.hasInitialized { @@ -65,7 +65,7 @@ func (d *PoolsListUpdater) GetNewPools(ctx context.Context, metadataBytes []byte pool := entity.Pool{ Address: d.config.VaultAddress, Exchange: d.config.DexID, - Type: DexTypeGmx, + Type: DexTypeRollupFinance, Tokens: poolTokens, Reserves: reserves, Extra: string(extraBytes), diff --git a/pkg/source/rollup-finance/price_feed.go b/pkg/source/rollup-finance/price_feed.go index c7e9df226..bac2c6c63 100644 --- a/pkg/source/rollup-finance/price_feed.go +++ b/pkg/source/rollup-finance/price_feed.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "math/big" diff --git a/pkg/source/rollup-finance/price_feed_reader.go b/pkg/source/rollup-finance/price_feed_reader.go index 96b77da5d..7c6451025 100644 --- a/pkg/source/rollup-finance/price_feed_reader.go +++ b/pkg/source/rollup-finance/price_feed_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -20,7 +20,7 @@ func NewPriceFeedReader(ethrpcClient *ethrpc.Client) *PriceFeedReader { abi: priceFeedABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "PriceFeedReader", }), } diff --git a/pkg/source/rollup-finance/types.go b/pkg/source/rollup-finance/types.go index e41d8192f..dc573a4f8 100644 --- a/pkg/source/rollup-finance/types.go +++ b/pkg/source/rollup-finance/types.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance type VaultAddress struct { Vault string `json:"vault"` diff --git a/pkg/source/rollup-finance/usdr.go b/pkg/source/rollup-finance/usdr.go index 14468e6f7..ea7cccf28 100644 --- a/pkg/source/rollup-finance/usdr.go +++ b/pkg/source/rollup-finance/usdr.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "math/big" diff --git a/pkg/source/rollup-finance/usdr_reader.go b/pkg/source/rollup-finance/usdr_reader.go index 207abc662..0397c2376 100644 --- a/pkg/source/rollup-finance/usdr_reader.go +++ b/pkg/source/rollup-finance/usdr_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -20,7 +20,7 @@ func NewUSDRReader(ethrpcClient *ethrpc.Client) *USDRReader { abi: erc20ABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "USDRReader", }), } diff --git a/pkg/source/rollup-finance/vault.go b/pkg/source/rollup-finance/vault.go index d6b7ac1ef..ebed50aab 100644 --- a/pkg/source/rollup-finance/vault.go +++ b/pkg/source/rollup-finance/vault.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "math/big" diff --git a/pkg/source/rollup-finance/vault_price_feed.go b/pkg/source/rollup-finance/vault_price_feed.go index bb70fa202..ff9217852 100644 --- a/pkg/source/rollup-finance/vault_price_feed.go +++ b/pkg/source/rollup-finance/vault_price_feed.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "encoding/json" diff --git a/pkg/source/rollup-finance/vault_price_feed_reader.go b/pkg/source/rollup-finance/vault_price_feed_reader.go index e9e8b51d9..85d570914 100644 --- a/pkg/source/rollup-finance/vault_price_feed_reader.go +++ b/pkg/source/rollup-finance/vault_price_feed_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -22,7 +22,7 @@ func NewVaultPriceFeedReader(ethrpcClient *ethrpc.Client) *VaultPriceFeedReader abi: vaultPriceFeedABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "VaultPriceFeedReader", }), } diff --git a/pkg/source/rollup-finance/vault_reader.go b/pkg/source/rollup-finance/vault_reader.go index c9fa28f33..016cd7c9f 100644 --- a/pkg/source/rollup-finance/vault_reader.go +++ b/pkg/source/rollup-finance/vault_reader.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -22,7 +22,7 @@ func NewVaultReader(ethrpcClient *ethrpc.Client) *VaultReader { abi: vaultABI, ethrpcClient: ethrpcClient, log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "reader": "VaultReader", }), } diff --git a/pkg/source/rollup-finance/vault_scanner.go b/pkg/source/rollup-finance/vault_scanner.go index f34f81d77..2e4350de6 100644 --- a/pkg/source/rollup-finance/vault_scanner.go +++ b/pkg/source/rollup-finance/vault_scanner.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "context" @@ -39,7 +39,7 @@ func NewVaultScanner( chainlinkFlagsReader: NewChainlinkFlagsReader(ethrpcClient), pancakePairReader: NewPancakePairReader(ethrpcClient), log: logger.WithFields(logger.Fields{ - "liquiditySource": DexTypeGmx, + "liquiditySource": DexTypeRollupFinance, "scanner": "VaultScanner", }), } diff --git a/pkg/source/rollup-finance/vault_utils.go b/pkg/source/rollup-finance/vault_utils.go index b1682e249..1fde0592b 100644 --- a/pkg/source/rollup-finance/vault_utils.go +++ b/pkg/source/rollup-finance/vault_utils.go @@ -1,4 +1,4 @@ -package gmx +package rollupfinance import ( "math/big" From 7331c48c993cbb2a7fab89132a751881dd91fc59 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Thu, 16 Nov 2023 12:52:39 +0700 Subject: [PATCH 3/3] wip --- pkg/source/rollup-finance/vault.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/source/rollup-finance/vault.go b/pkg/source/rollup-finance/vault.go index ebed50aab..5d629d0e5 100644 --- a/pkg/source/rollup-finance/vault.go +++ b/pkg/source/rollup-finance/vault.go @@ -35,7 +35,7 @@ type Vault struct { WhitelistedTokensCount *big.Int `json:"-"` - UseSwapPricing bool // not used, always false for now + UseSwapPricing bool `json:"useSwapPricing"` // not used, always false for now } func NewVault() *Vault {