diff --git a/src/abi/solidly/SolidlyFactory.json b/src/abi/solidly/SolidlyFactory.json new file mode 100644 index 000000000..f678bfe1a --- /dev/null +++ b/src/abi/solidly/SolidlyFactory.json @@ -0,0 +1,147 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPairs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPair", + "outputs": [ + { "internalType": "address", "name": "pair", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "name": "getPair", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingPauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pauser", "type": "address" } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/abi/solidly/SolidlyPair.json b/src/abi/solidly/SolidlyPair.json new file mode 100644 index 000000000..46bee0b6b --- /dev/null +++ b/src/abi/solidly/SolidlyPair.json @@ -0,0 +1,658 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "name": "current", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct BaseV1Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/abi/uniswap-v2/DystFactory.json b/src/abi/uniswap-v2/DystFactory.json deleted file mode 100644 index 150007e4c..000000000 --- a/src/abi/uniswap-v2/DystFactory.json +++ /dev/null @@ -1,280 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "address", - "name": "_treasury", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token0", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "token1", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "stable", - "type": "bool" - }, - { - "indexed": false, - "internalType": "address", - "name": "pair", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "allPairsLength", - "type": "uint256" - } - ], - "name": "PairCreated", - "type": "event" - }, - { - "inputs": [], - "name": "acceptPauser", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "allPairs", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "allPairsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "bool", - "name": "stable", - "type": "bool" - } - ], - "name": "createPair", - "outputs": [ - { - "internalType": "address", - "name": "pair", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getInitializable", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "name": "getPair", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isPair", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isPaused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pairCodeHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "pauser", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingPauser", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_state", - "type": "bool" - } - ], - "name": "setPause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_pauser", - "type": "address" - } - ], - "name": "setPauser", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "treasury", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/src/abi/uniswap-v2/DystPair.json b/src/abi/uniswap-v2/DystPair.json deleted file mode 100644 index ff05d645f..000000000 --- a/src/abi/uniswap-v2/DystPair.json +++ /dev/null @@ -1,1202 +0,0 @@ -[ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "Burn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Claim", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Fees", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Mint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0In", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1In", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0Out", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1Out", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "Swap", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "reserve0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reserve1", - "type": "uint256" - } - ], - "name": "Sync", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Treasury", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PERMIT_TYPEHASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "blockTimestampLast", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "burn", - "outputs": [ - { - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "chainId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "claimFees", - "outputs": [ - { - "internalType": "uint256", - "name": "claimed0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "claimed1", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "claimable0", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "claimable1", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - } - ], - "name": "current", - "outputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentCumulativePrices", - "outputs": [ - { - "internalType": "uint256", - "name": "reserve0Cumulative", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserve1Cumulative", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "blockTimestamp", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "fees", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - } - ], - "name": "getAmountOut", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getReserves", - "outputs": [ - { - "internalType": "uint112", - "name": "_reserve0", - "type": "uint112" - }, - { - "internalType": "uint112", - "name": "_reserve1", - "type": "uint112" - }, - { - "internalType": "uint32", - "name": "_blockTimestampLast", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "index0", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "index1", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lastObservation", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserve0Cumulative", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserve1Cumulative", - "type": "uint256" - } - ], - "internalType": "struct IPair.Observation", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "metadata", - "outputs": [ - { - "internalType": "uint256", - "name": "dec0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dec1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "r0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "r1", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "st", - "type": "bool" - }, - { - "internalType": "address", - "name": "t0", - "type": "address" - }, - { - "internalType": "address", - "name": "t1", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "mint", - "outputs": [ - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "nonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "observationLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "observations", - "outputs": [ - { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserve0Cumulative", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserve1Cumulative", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "points", - "type": "uint256" - } - ], - "name": "prices", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "granularity", - "type": "uint256" - } - ], - "name": "quote", - "outputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "reserve0", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "reserve0CumulativeLast", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "reserve1", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "reserve1CumulativeLast", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "points", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "window", - "type": "uint256" - } - ], - "name": "sample", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "skim", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "stable", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "supplyIndex0", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "supplyIndex1", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount0Out", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Out", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "swap", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "sync", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "token0", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token1", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tokens", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "dst", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "src", - "type": "address" - }, - { - "internalType": "address", - "name": "dst", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "treasury", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/src/dex/index.ts b/src/dex/index.ts index ef14fa779..a5d2da39d 100644 --- a/src/dex/index.ts +++ b/src/dex/index.ts @@ -1,4 +1,3 @@ -import { Provider } from '@ethersproject/providers'; import { Address, UnoptimizedRate } from '../types'; import { Curve } from './curve'; import { CurveV2 } from './curve-v2'; @@ -41,13 +40,12 @@ import { KyberDmm } from './kyberdmm/kyberdmm'; import { Platypus } from './platypus/platypus'; import { GMX } from './gmx/gmx'; import { WooFi } from './woo-fi/woo-fi'; -import { Dystopia } from './uniswap-v2/dystopia/dystopia'; -import { SpiritSwapV2 } from './spirit-swap-v2'; import { ParaSwapLimitOrders } from './paraswap-limit-orders/paraswap-limit-orders'; import { AugustusRFQOrder } from './augustus-rfq'; import Web3 from 'web3'; -import { Velodrome } from './velodrome'; -import { Solidly } from './solidly'; +import { Solidly } from './solidly/solidly'; +import { Velodrome } from './solidly/forks-override/velodrome'; +import { SpiritSwapV2 } from './solidly/forks-override/spiritSwapV2'; const LegacyDexes = [ Curve, @@ -69,9 +67,6 @@ const LegacyDexes = [ Jarvis, Lido, AugustusRFQOrder, - SpiritSwapV2, - Velodrome, - Solidly, ]; const Dexes = [ @@ -91,8 +86,10 @@ const Dexes = [ Platypus, GMX, WooFi, - Dystopia, ParaSwapLimitOrders, + Solidly, + SpiritSwapV2, + Velodrome, ]; export type LegacyDexConstructor = new ( diff --git a/src/dex/solidly.ts b/src/dex/solidly.ts deleted file mode 100644 index 0e63b95b0..000000000 --- a/src/dex/solidly.ts +++ /dev/null @@ -1,54 +0,0 @@ -import Web3 from 'web3'; -import { Address } from '../types'; -import { IDexTxBuilder } from './idex'; -import { IDexHelper } from '../dex-helper'; -import { DexParams, UniswapParam, UniswapV2Data } from './uniswap-v2/types'; -import { Dystopia } from './uniswap-v2/dystopia/dystopia'; -import { Network } from '../constants'; - -const dexKey = 'Solidly'; - -export const SolidlyConfig: Record = { - [Network.FANTOM]: { - subgraphURL: 'https://api.thegraph.com/subgraphs/name/deusfinance/solidly', - factoryAddress: '0x3faab499b519fdc5819e3d7ed0c26111904cbc28', - // ParaSwap-compatible Router with stable pools support - router: '0x56a14A1954b5d5FD7C636a24137a93742bA708b9', - initCode: - '0x57ae84018c47ebdaf7ddb2d1216c8c36389d12481309af65428eb6d460f747a4', - stableFee: 1, - volatileFee: 1, - poolGasCost: 180 * 1000, - - feeCode: 1, // Not used - set for type. TODO: clean up when move to fully event based - }, -}; - -export class Solidly - extends Dystopia - implements IDexTxBuilder -{ - static dexKeys = [dexKey.toLowerCase()]; - - constructor( - augustusAddress: Address, - network: Network, - provider: Web3, - dexHelper?: IDexHelper, - ) { - if (dexHelper === undefined) - throw new Error(`DexHelper must be provided to ${dexKey}`); - super( - network, - dexKey, - dexHelper, - true, - SolidlyConfig[network].factoryAddress, - SolidlyConfig[network].subgraphURL, - SolidlyConfig[network].initCode, - SolidlyConfig[network].stableFee, - SolidlyConfig[network].poolGasCost, - SolidlyConfig[network].router, - ); - } -} diff --git a/src/dex/solidly/config.ts b/src/dex/solidly/config.ts new file mode 100644 index 000000000..cb8967d33 --- /dev/null +++ b/src/dex/solidly/config.ts @@ -0,0 +1,75 @@ +import { DexParams } from './types'; +import { DexConfigMap, AdapterMappings } from '../../types'; +import { Network, SwapSide } from '../../constants'; + +export const SolidlyConfig: DexConfigMap = { + Solidly: { + [Network.FANTOM]: { + subgraphURL: + 'https://api.thegraph.com/subgraphs/name/deusfinance/solidly', + factoryAddress: '0x3faab499b519fdc5819e3d7ed0c26111904cbc28', + router: '0x56a14A1954b5d5FD7C636a24137a93742bA708b9', // ParaSwap-compatible Router with stable pools support + initCode: + '0x57ae84018c47ebdaf7ddb2d1216c8c36389d12481309af65428eb6d460f747a4', + // Fixed Fees, same for volative and stable pools + feeCode: 1, + poolGasCost: 180 * 1000, + }, + }, + Dystopia: { + [Network.POLYGON]: { + subgraphURL: + 'https://api.thegraph.com/subgraphs/name/dystopia-exchange/dystopia-v2', + factoryAddress: '0x1d21Db6cde1b18c7E47B0F7F42f4b3F68b9beeC9', + router: '0x0E98A8e5ca6067B98d10Eb6476ec30E232346402', // ParaSwap-compatible Router with stable pools support + initCode: + '0x009bce6d7eb00d3d075e5bd9851068137f44bba159f1cde806a268e20baaf2e8', + // Fixed Fees, same for volative and stable pools + feeCode: 5, + poolGasCost: 180 * 1000, + }, + }, + SpiritSwapV2: { + [Network.FANTOM]: { + // Later in Dystopia constructor it will be replaced with undefined + // If we set here undefined, it will go search for non-existing config + subgraphURL: '', + factoryAddress: '0x9d3591719038752db0c8bEEe2040FfcC3B2c6B9c', + router: '0x56a14A1954b5d5FD7C636a24137a93742bA708b9', // ParaSwap-compatible Router with stable pools support + initCode: + '0x5442fb448d86f32a7d2a9dc1a457e64bf5a6c77415d98802aac4fb5a9dc5ecd9', + // updatable fees on the pool contract without event + stableFee: 4, // 10000 / 2500 = 4 in BPS + volatileFee: 18, // ceil(10000 / 556) = 18 in BPS + poolGasCost: 180 * 1000, + feeCode: 4, + }, + }, + Velodrome: { + [Network.OPTIMISM]: { + subgraphURL: 'https://api.thegraph.com/subgraphs/name/dmihal/velodrome', + factoryAddress: '0x25cbddb98b35ab1ff77413456b31ec81a6b6b746', + router: '0xa2f581b012E0f2dcCDe86fCbfb529f4aC5dD4983', // ParaSwap-compatible Router with stable pools support + initCode: + '0xc1ac28b1c4ebe53c0cff67bab5878c4eb68759bb1e9f73977cd266b247d149f0', + // updatable fees on the factory without event + stableFee: 2, + volatileFee: 2, + poolGasCost: 180 * 1000, + feeCode: 2, + }, + }, +}; + +// TODO: segment adapters by dex key +export const Adapters: Record = { + [Network.POLYGON]: { + [SwapSide.SELL]: [{ name: 'PolygonAdapter02', index: 3 }], // dystopia + }, + [Network.FANTOM]: { + [SwapSide.SELL]: [{ name: 'FantomAdapter01', index: 10 }], // solidly + spiritSwapV2 + }, + [Network.OPTIMISM]: { + [SwapSide.SELL]: [{ name: 'OptimismAdapter01', index: 8 }], // velodrome + }, +}; diff --git a/src/dex/solidly/forks-override/spiritSwapV2.ts b/src/dex/solidly/forks-override/spiritSwapV2.ts new file mode 100644 index 000000000..3bd53c073 --- /dev/null +++ b/src/dex/solidly/forks-override/spiritSwapV2.ts @@ -0,0 +1,60 @@ +import { Solidly } from '../solidly'; +import { SolidlyPair } from '../types'; +import { Network } from '../../../constants'; +import { IDexHelper } from '../../../dex-helper'; +import { Interface } from '@ethersproject/abi'; +import { SolidlyConfig } from '../config'; +import { getDexKeysWithNetwork } from '../../../utils'; +import _ from 'lodash'; + +const SpiritSwapV2PairABI = [ + { + inputs: [], + name: 'fee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; + +const spiritSwapV2PairIface = new Interface(SpiritSwapV2PairABI); +const FEE_FACTOR = 10_000; + +export class SpiritSwapV2 extends Solidly { + public static dexKeysWithNetwork: { key: string; networks: Network[] }[] = + getDexKeysWithNetwork(_.pick(SolidlyConfig, ['SpiritSwapV2'])); + + constructor( + protected network: Network, + protected dexKey: string, + protected dexHelper: IDexHelper, + ) { + super( + network, + dexKey, + dexHelper, + true, // dynamic fees + ); + } + + protected getFeesMultiCallData(pair: SolidlyPair) { + const callEntry = { + target: pair.exchange!, + callData: spiritSwapV2PairIface.encodeFunctionData('fee', []), + }; + const callDecoder = (values: any[]) => { + const fees = parseInt( + spiritSwapV2PairIface.decodeFunctionResult('fee', values)[0].toString(), + ); + if (!fees) return 0; + + const feeCode = Math.ceil(FEE_FACTOR / fees); + return feeCode; + }; + + return { + callEntry, + callDecoder, + }; + } +} diff --git a/src/dex/solidly/forks-override/velodrome.ts b/src/dex/solidly/forks-override/velodrome.ts new file mode 100644 index 000000000..cfbf366cc --- /dev/null +++ b/src/dex/solidly/forks-override/velodrome.ts @@ -0,0 +1,58 @@ +import { Solidly } from '../solidly'; +import { SolidlyPair } from '../types'; +import { Network } from '../../../constants'; +import { IDexHelper } from '../../../dex-helper'; +import { Interface } from '@ethersproject/abi'; +import { getDexKeysWithNetwork } from '../../../utils'; +import { SolidlyConfig } from '../config'; +import _ from 'lodash'; + +const VelodromeFactoryABI = [ + { + inputs: [{ internalType: 'bool', name: '_stable', type: 'bool' }], + name: 'getFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; + +const velodromeFactoryIface = new Interface(VelodromeFactoryABI); + +export class Velodrome extends Solidly { + public static dexKeysWithNetwork: { key: string; networks: Network[] }[] = + getDexKeysWithNetwork(_.pick(SolidlyConfig, ['Velodrome'])); + + constructor( + protected network: Network, + protected dexKey: string, + protected dexHelper: IDexHelper, + ) { + super( + network, + dexKey, + dexHelper, + true, // dynamic fees + ); + } + + protected getFeesMultiCallData(pair: SolidlyPair) { + const callEntry = { + target: this.factoryAddress, + callData: velodromeFactoryIface.encodeFunctionData('getFee', [ + pair.stable, + ]), + }; + const callDecoder = (values: any[]) => + parseInt( + velodromeFactoryIface + .decodeFunctionResult('getFee', values)[0] + .toString(), + ); + + return { + callEntry, + callDecoder, + }; + } +} diff --git a/src/dex/uniswap-v2/dystopia/dystopia-stable-pool.ts b/src/dex/solidly/solidly-stable-pool.ts similarity index 79% rename from src/dex/uniswap-v2/dystopia/dystopia-stable-pool.ts rename to src/dex/solidly/solidly-stable-pool.ts index 3cbb648dc..2781273e5 100644 --- a/src/dex/uniswap-v2/dystopia/dystopia-stable-pool.ts +++ b/src/dex/solidly/solidly-stable-pool.ts @@ -1,7 +1,6 @@ -import { RESERVE_LIMIT } from '../uniswap-v2'; -import { BI_POWS } from '../../../bigint-constants'; -import { DystopiaPoolOrderedParams } from './dystopia'; -import { SWAP_FEE_FACTOR } from './constants'; +import { BI_POWS } from '../../bigint-constants'; +import { RESERVE_LIMIT } from '../uniswap-v2/uniswap-v2'; +import { SolidlyPoolOrderedParams } from './types'; const e18 = BI_POWS[18]; @@ -61,18 +60,21 @@ function _closeTo(a: bigint, b: bigint, target: bigint) { return false; } -export class DystopiaStablePool { +export class SolidlyStablePool { static async getSellPrice( - priceParams: DystopiaPoolOrderedParams, + priceParams: SolidlyPoolOrderedParams, srcAmount: bigint, + feeFactor: number, ): Promise { - const { reservesIn, reservesOut, decimalsIn, decimalsOut } = priceParams; + const { reservesIn, reservesOut, decimalsIn, decimalsOut, fee } = + priceParams; + // FIXME: some dexes use uint112 others use uint256 if (BigInt(reservesIn) + srcAmount > RESERVE_LIMIT) { return 0n; } - const amountIn = srcAmount - srcAmount / SWAP_FEE_FACTOR; + const amountIn = srcAmount - (srcAmount * BigInt(fee)) / BigInt(feeFactor); const reservesInN = BigInt(reservesIn); const reservesOutN = BigInt(reservesOut); diff --git a/src/dex/uniswap-v2/dystopia/dystopia.ts b/src/dex/solidly/solidly.ts similarity index 74% rename from src/dex/uniswap-v2/dystopia/dystopia.ts rename to src/dex/solidly/solidly.ts index 44851ebac..1a38aaa12 100644 --- a/src/dex/uniswap-v2/dystopia/dystopia.ts +++ b/src/dex/solidly/solidly.ts @@ -1,5 +1,5 @@ -import { UniswapV2, UniswapV2Pair } from '../uniswap-v2'; -import { Network, NULL_ADDRESS, SUBGRAPH_TIMEOUT } from '../../../constants'; +import { UniswapV2 } from '../uniswap-v2/uniswap-v2'; +import { Network, NULL_ADDRESS, SUBGRAPH_TIMEOUT } from '../../constants'; import { AdapterExchangeParam, Address, @@ -7,47 +7,32 @@ import { PoolLiquidity, SimpleExchangeParam, Token, -} from '../../../types'; -import { IDexHelper } from '../../../dex-helper'; -import { UniswapData, UniswapV2Data } from '../types'; -import { getBigIntPow, getDexKeysWithNetwork } from '../../../utils'; -import dystopiaFactoryABI from '../../../abi/uniswap-v2/DystFactory.json'; -import dystPairABI from '../../../abi/uniswap-v2/DystPair.json'; +} from '../../types'; +import { IDexHelper } from '../../dex-helper'; +import erc20ABI from '../../abi/erc20.json'; +import { UniswapData, UniswapV2Data } from '../uniswap-v2/types'; +import { getBigIntPow, getDexKeysWithNetwork } from '../../utils'; +import solidlyFactoryABI from '../../abi/solidly/SolidlyFactory.json'; +import solidlyPair from '../../abi/solidly/SolidlyPair.json'; import _ from 'lodash'; import { NumberAsString, SwapSide } from 'paraswap-core'; -import { DystopiaUniswapV2Pool } from './dystopia-uniswap-v2-pool'; -import { DystopiaStablePool } from './dystopia-stable-pool'; -import { Adapters, DystopiaConfig } from './config'; -import { AbiCoder, Interface } from '@ethersproject/abi'; - -// to calculate prices for stable pool, we need decimals of the stable tokens -// so, we are extending UniswapV2PoolOrderedParams with token decimals -export interface DystopiaPoolOrderedParams { - tokenIn: string; - tokenOut: string; - reservesIn: string; - reservesOut: string; - fee: string; - direction: boolean; - exchange: string; - decimalsIn: number; - decimalsOut: number; - stable: boolean; -} +import { Interface, AbiCoder } from '@ethersproject/abi'; +import { SolidlyStablePool } from './solidly-stable-pool'; +import { Uniswapv2ConstantProductPool } from '../uniswap-v2/uniswap-v2-constant-product-pool'; +import { PoolState, SolidlyPair, SolidlyPoolOrderedParams } from './types'; +import { SolidlyConfig, Adapters } from './config'; -export interface DystopiaPoolState { - reserves0: string; - reserves1: string; - feeCode: number; -} +const erc20Iface = new Interface(erc20ABI); +const solidlyPairIface = new Interface(solidlyPair); +const defaultAbiCoder = new AbiCoder(); -const iface = new Interface(dystPairABI); -const coder = new AbiCoder(); +export class Solidly extends UniswapV2 { + pairs: { [key: string]: SolidlyPair } = {}; + stableFee?: number; + volatileFee?: number; -export class Dystopia extends UniswapV2 { - feeFactor = 20000; public static dexKeysWithNetwork: { key: string; networks: Network[] }[] = - getDexKeysWithNetwork(DystopiaConfig); + getDexKeysWithNetwork(_.omit(SolidlyConfig, ['Velodrome', 'SpiritSwapV2'])); constructor( protected network: Network, @@ -68,37 +53,40 @@ export class Dystopia extends UniswapV2 { isDynamicFees, factoryAddress !== undefined ? factoryAddress - : DystopiaConfig[dexKey][network].factoryAddress, + : SolidlyConfig[dexKey][network].factoryAddress, subgraphURL === '' ? undefined : subgraphURL !== undefined ? subgraphURL - : DystopiaConfig[dexKey][network].subgraphURL, + : SolidlyConfig[dexKey][network].subgraphURL, initCode !== undefined ? initCode - : DystopiaConfig[dexKey][network].initCode, - feeCode !== undefined ? feeCode : DystopiaConfig[dexKey][network].feeCode, + : SolidlyConfig[dexKey][network].initCode, + feeCode !== undefined ? feeCode : SolidlyConfig[dexKey][network].feeCode, poolGasCost !== undefined ? poolGasCost - : DystopiaConfig[dexKey][network].poolGasCost, - iface, + : SolidlyConfig[dexKey][network].poolGasCost, + solidlyPairIface, Adapters[network] || undefined, ); + this.stableFee = SolidlyConfig[dexKey][network].stableFee; + this.volatileFee = SolidlyConfig[dexKey][network].volatileFee; + this.factory = new dexHelper.web3Provider.eth.Contract( - dystopiaFactoryABI as any, + solidlyFactoryABI as any, factoryAddress !== undefined ? factoryAddress - : DystopiaConfig[dexKey][network].factoryAddress, + : SolidlyConfig[dexKey][network].factoryAddress, ); this.router = routerAddress !== undefined ? routerAddress - : DystopiaConfig[dexKey][network].router || ''; + : SolidlyConfig[dexKey][network].router || ''; } - async findDystopiaPair(from: Token, to: Token, stable: boolean) { + async findSolidlyPair(from: Token, to: Token, stable: boolean) { if (from.address.toLowerCase() === to.address.toLowerCase()) return null; const [token0, token1] = from.address.toLowerCase() < to.address.toLowerCase() @@ -111,15 +99,15 @@ export class Dystopia extends UniswapV2 { if (pair) return pair; let exchange = await this.factory.methods - // Dystopia has additional boolean parameter "StablePool" + // Solidly has additional boolean parameter "StablePool" // At first we look for uniswap-like volatile pool .getPair(token0.address, token1.address, stable) .call(); if (exchange === NULL_ADDRESS) { - pair = { token0, token1 }; + pair = { token0, token1, stable }; } else { - pair = { token0, token1, exchange }; + pair = { token0, token1, exchange, stable }; } this.pairs[key] = pair; return pair; @@ -127,10 +115,10 @@ export class Dystopia extends UniswapV2 { async batchCatchUpPairs(pairs: [Token, Token][], blockNumber: number) { if (!blockNumber) return; - const pairsToFetch: UniswapV2Pair[] = []; + const pairsToFetch: SolidlyPair[] = []; for (const _pair of pairs) { for (const stable of [false, true]) { - const pair = await this.findDystopiaPair(_pair[0], _pair[1], stable); + const pair = await this.findSolidlyPair(_pair[0], _pair[1], stable); if (!(pair && pair.exchange)) continue; if (!pair.pool) { pairsToFetch.push(pair); @@ -166,18 +154,31 @@ export class Dystopia extends UniswapV2 { } async getManyPoolReserves( - pairs: UniswapV2Pair[], + pairs: SolidlyPair[], blockNumber: number, - ): Promise { + ): Promise { try { + const multiCallFeeData = pairs.map(pair => + this.getFeesMultiCallData(pair), + ); const calldata = pairs - .map(pair => { - return [ + .map((pair, i) => { + let calldata = [ { - target: pair.exchange, - callData: iface.encodeFunctionData('getReserves', []), + target: pair.token0.address, + callData: erc20Iface.encodeFunctionData('balanceOf', [ + pair.exchange!, + ]), + }, + { + target: pair.token1.address, + callData: erc20Iface.encodeFunctionData('balanceOf', [ + pair.exchange!, + ]), }, ]; + if (this.isDynamicFees) calldata.push(multiCallFeeData[i]!.callEntry); + return calldata; }) .flat(); @@ -186,18 +187,19 @@ export class Dystopia extends UniswapV2 { .aggregate(calldata) .call({}, blockNumber); - return pairs.map((pair, i) => { - const decodedData = coder.decode( - ['uint112', 'uint112', 'uint32'], - data.returnData[i], - ); - - return { - reserves0: decodedData[0].toString(), - reserves1: decodedData[1].toString(), - feeCode: this.feeCode, - }; - }); + const returnData = _.chunk(data.returnData, this.isDynamicFees ? 3 : 2); + + return pairs.map((pair, i) => ({ + reserves0: defaultAbiCoder + .decode(['uint256'], returnData[i][0])[0] + .toString(), + reserves1: defaultAbiCoder + .decode(['uint256'], returnData[i][1])[0] + .toString(), + feeCode: this.isDynamicFees + ? multiCallFeeData[i]!.callDecoder(returnData[i][2]) + : (pair.stable ? this.stableFee : this.volatileFee) || this.feeCode, + })); } catch (e) { this.logger.error( `Error_getManyPoolReserves could not get reserves with error:`, @@ -208,20 +210,28 @@ export class Dystopia extends UniswapV2 { } async getSellPrice( - priceParams: DystopiaPoolOrderedParams, + priceParams: SolidlyPoolOrderedParams, srcAmount: bigint, ): Promise { return priceParams.stable - ? DystopiaStablePool.getSellPrice(priceParams, srcAmount) - : DystopiaUniswapV2Pool.getSellPrice(priceParams, srcAmount); + ? SolidlyStablePool.getSellPrice(priceParams, srcAmount, this.feeFactor) + : Uniswapv2ConstantProductPool.getSellPrice( + priceParams, + srcAmount, + this.feeFactor, + ); } async getBuyPrice( - priceParams: DystopiaPoolOrderedParams, + priceParams: SolidlyPoolOrderedParams, srcAmount: bigint, ): Promise { if (priceParams.stable) throw new Error(`Buy not supported`); - return DystopiaUniswapV2Pool.getBuyPrice(priceParams, srcAmount); + return Uniswapv2ConstantProductPool.getBuyPrice( + priceParams, + srcAmount, + this.feeFactor, + ); } async getPricesVolume( @@ -258,7 +268,7 @@ export class Dystopia extends UniswapV2 { if (limitPools && limitPools.every(p => p !== poolIdentifier)) return null; - const pairParam = await this.getDystopiaPairOrderedParams( + const pairParam = await this.getSolidlyPairOrderedParams( from, to, blockNumber, @@ -335,10 +345,14 @@ export class Dystopia extends UniswapV2 { count: number, ): Promise { if (!this.subgraphURL) return []; + + const stableFieldKey = + this.dexKey.toLowerCase() === 'solidly' ? 'stable' : 'isStable'; + const query = `query ($token: Bytes!, $count: Int) { pools0: pairs(first: $count, orderBy: reserveUSD, orderDirection: desc, where: {token0: $token, reserve0_gt: 1, reserve1_gt: 1}) { id - isStable + ${stableFieldKey} token0 { id decimals @@ -351,7 +365,7 @@ export class Dystopia extends UniswapV2 { } pools1: pairs(first: $count, orderBy: reserveUSD, orderDirection: desc, where: {token1: $token, reserve0_gt: 1, reserve1_gt: 1}) { id - isStable + ${stableFieldKey} token0 { id decimals @@ -377,7 +391,7 @@ export class Dystopia extends UniswapV2 { throw new Error("Couldn't fetch the pools from the subgraph"); const pools0 = _.map(data.pools0, pool => ({ exchange: this.dexKey, - stable: pool.isStable, + stable: pool[stableFieldKey], address: pool.id.toLowerCase(), connectorTokens: [ { @@ -390,7 +404,7 @@ export class Dystopia extends UniswapV2 { const pools1 = _.map(data.pools1, pool => ({ exchange: this.dexKey, - stable: pool.isStable, + stable: pool[stableFieldKey], address: pool.id.toLowerCase(), connectorTokens: [ { @@ -409,14 +423,13 @@ export class Dystopia extends UniswapV2 { } // Same as at uniswap-v2-pool.json, but extended with decimals and stable - - async getDystopiaPairOrderedParams( + async getSolidlyPairOrderedParams( from: Token, to: Token, blockNumber: number, stable: boolean, - ): Promise { - const pair = await this.findDystopiaPair(from, to, stable); + ): Promise { + const pair = await this.findSolidlyPair(from, to, stable); if (!(pair && pair.pool && pair.exchange)) return null; const pairState = pair.pool.getState(blockNumber); if (!pairState) { diff --git a/src/dex/solidly/types.ts b/src/dex/solidly/types.ts new file mode 100644 index 000000000..c32e17e9a --- /dev/null +++ b/src/dex/solidly/types.ts @@ -0,0 +1,39 @@ +import { + UniswapV2Data, + UniswapV2PoolOrderedParams, + DexParams as UniswapV2DexParams, +} from '../uniswap-v2/types'; +import { UniswapV2Pair } from '../uniswap-v2/uniswap-v2'; + +export type PoolState = { + // TODO: poolState is the state of event + // subscriber. This should be the minimum + // set of parameters required to compute + // pool prices. Complete me! + reserves0: string; + reserves1: string; + feeCode: number; +}; + +// to calculate prices for stable pool, we need decimals of the stable tokens +export interface SolidlyPoolOrderedParams extends UniswapV2PoolOrderedParams { + decimalsIn: number; + decimalsOut: number; + stable: boolean; +} + +export type SolidlyData = UniswapV2Data; + +// FIXME: exclude fee code + handle dynamic fees +export interface DexParams extends Omit { + // TODO: DexParams is set of parameters the can + // be used to initiate a DEX fork. + // Complete me! + feeCode: number; + stableFee?: number; + volatileFee?: number; +} + +export interface SolidlyPair extends UniswapV2Pair { + stable: boolean; +} diff --git a/src/dex/spirit-swap-v2.ts b/src/dex/spirit-swap-v2.ts deleted file mode 100644 index 68ca719ab..000000000 --- a/src/dex/spirit-swap-v2.ts +++ /dev/null @@ -1,60 +0,0 @@ -import Web3 from 'web3'; -import { Address } from '../types'; -import { IDexTxBuilder } from './idex'; -import { IDexHelper } from '../dex-helper'; -import { DexParams, UniswapParam, UniswapV2Data } from './uniswap-v2/types'; -import { Dystopia } from './uniswap-v2/dystopia/dystopia'; -import { Network } from '../constants'; - -const dexKey = 'SpiritSwapV2'; - -export const spiritSwapV2Config: Record = { - [Network.FANTOM]: { - // Later in Dystopia constructor it will be replaced with undefined - // If we set here undefined, it will go search for non-existing config - subgraphURL: '', - factoryAddress: '0x9d3591719038752db0c8bEEe2040FfcC3B2c6B9c', - // ParaSwap-compatible Router with stable pools support - router: '0x56a14A1954b5d5FD7C636a24137a93742bA708b9', - initCode: - '0x5442fb448d86f32a7d2a9dc1a457e64bf5a6c77415d98802aac4fb5a9dc5ecd9', - - // 10000 / 2000 = 5 in BPS - stableFee: 5, - // 10000 / 500 = 20 in BPS - volatileFee: 20, - poolGasCost: 180 * 1000, - - // TODO: Not correct, need to update implementation for event based - feeCode: 5, - }, -}; - -export class SpiritSwapV2 - extends Dystopia - implements IDexTxBuilder -{ - static dexKeys = [dexKey.toLowerCase()]; - - constructor( - augustusAddress: Address, - network: Network, - provider: Web3, - dexHelper?: IDexHelper, - ) { - if (dexHelper === undefined) - throw new Error(`DexHelper must be provided to ${dexKey}`); - super( - network, - dexKey, - dexHelper, - false, - spiritSwapV2Config[network].factoryAddress, - spiritSwapV2Config[network].subgraphURL, - spiritSwapV2Config[network].initCode, - spiritSwapV2Config[network].stableFee, - spiritSwapV2Config[network].poolGasCost, - spiritSwapV2Config[network].router, - ); - } -} diff --git a/src/dex/uniswap-v2/dystopia/config.ts b/src/dex/uniswap-v2/dystopia/config.ts deleted file mode 100644 index 64d2a4496..000000000 --- a/src/dex/uniswap-v2/dystopia/config.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AdapterMappings, DexConfigMap } from '../../../types'; -import { DexParams } from '../types'; -import { Network, SwapSide } from '../../../constants'; - -export const DystopiaConfig: DexConfigMap = { - Dystopia: { - [Network.POLYGON]: { - subgraphURL: - 'https://api.thegraph.com/subgraphs/name/dystopia-exchange/dystopia-v2', - factoryAddress: '0x1d21Db6cde1b18c7E47B0F7F42f4b3F68b9beeC9', - // ParaSwap-compatible Router with stable pools support - router: '0x0E98A8e5ca6067B98d10Eb6476ec30E232346402', - initCode: - '0x009bce6d7eb00d3d075e5bd9851068137f44bba159f1cde806a268e20baaf2e8', - feeCode: 5, - poolGasCost: 180 * 1000, - }, - }, -}; - -export const Adapters: Record = { - [Network.POLYGON]: { - [SwapSide.SELL]: [{ name: 'PolygonAdapter02', index: 3 }], - }, - [Network.FANTOM]: { - [SwapSide.SELL]: [{ name: 'FantomAdapter01', index: 10 }], - }, -}; diff --git a/src/dex/uniswap-v2/dystopia/constants.ts b/src/dex/uniswap-v2/dystopia/constants.ts deleted file mode 100644 index 62ad9c068..000000000 --- a/src/dex/uniswap-v2/dystopia/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// 0.05% swap fee -export const SWAP_FEE_FACTOR = 2000n; diff --git a/src/dex/uniswap-v2/dystopia/dystopia-integration.test.ts b/src/dex/uniswap-v2/dystopia/dystopia-integration.test.ts deleted file mode 100644 index f148c3ec9..000000000 --- a/src/dex/uniswap-v2/dystopia/dystopia-integration.test.ts +++ /dev/null @@ -1,213 +0,0 @@ -import dotenv from 'dotenv'; -dotenv.config(); - -import { DummyDexHelper } from '../../../dex-helper'; -import { Network, SwapSide } from '../../../constants'; -import { checkPoolPrices, checkPoolsLiquidity } from '../../../../tests/utils'; -import { BI_POWS } from '../../../bigint-constants'; -import { Dystopia } from './dystopia'; -import { Tokens } from '../../../../tests/constants-e2e'; -import { Interface, Result } from '@ethersproject/abi'; -import dystopiaPairABI from '../../../abi/uniswap-v2/DystPair.json'; - -const amounts18 = [0n, BI_POWS[18], 2000000000000000000n]; -const amounts6 = [0n, BI_POWS[6], BI_POWS[6] * 2n]; - -const dexKey = 'Dystopia'; -const network = Network.POLYGON; -const dexHelper = new DummyDexHelper(network); -const dystopia = new Dystopia(network, dexKey, dexHelper); - -function getReaderCalldata( - exchangeAddress: string, - readerIface: Interface, - amounts: bigint[], - funcName: string, - tokenIn: string, -) { - return amounts.map(amount => ({ - target: exchangeAddress, - callData: readerIface.encodeFunctionData(funcName, [amount, tokenIn]), - })); -} - -function decodeReaderResult( - results: Result, - readerIface: Interface, - funcName: string, -) { - return results.map(result => { - const parsed = readerIface.decodeFunctionResult(funcName, result); - return BigInt(parsed[0]._hex); - }); -} - -async function checkOnChainPricing( - dystopia: Dystopia, - funcName: string, - blockNumber: number, - prices: bigint[], - exchangeAddress: string, - tokenIn: string, - amounts: bigint[], -) { - const readerIface = new Interface(dystopiaPairABI as any); - - const readerCallData = getReaderCalldata( - exchangeAddress, - readerIface, - amounts.slice(1), - funcName, - tokenIn, - ); - console.log('readerCallData', readerCallData); - const readerResult = ( - await dexHelper.multiContract.methods - .aggregate(readerCallData) - .call({}, blockNumber) - ).returnData; - const expectedPrices = [0n].concat( - decodeReaderResult(readerResult, readerIface, funcName), - ); - - expect(prices).toEqual(expectedPrices); -} - -describe('Dystopia', function () { - describe('UniswapV2 like pool', function () { - const TokenASymbol = 'WETH'; - const tokenA = Tokens[network][TokenASymbol]; - const TokenBSymbol = 'WMATIC'; - const tokenB = Tokens[network][TokenBSymbol]; - - const amounts = amounts18; - - it('getPoolIdentifiers and getPricesVolume', async function () { - const blocknumber = await dexHelper.web3Provider.eth.getBlockNumber(); - const dystopia = new Dystopia(network, dexKey, dexHelper); - const pools = await dystopia.getPoolIdentifiers( - tokenA, - tokenB, - SwapSide.SELL, - blocknumber, - ); - console.log( - `${TokenASymbol} <> ${TokenBSymbol} Pool Identifiers: `, - pools, - ); - - expect(pools.length).toBeGreaterThan(0); - - const poolPrices = await dystopia.getPricesVolume( - tokenA, - tokenB, - amounts, - SwapSide.SELL, - blocknumber, - pools, - ); - console.log( - `${TokenASymbol} <> ${TokenBSymbol} Pool Prices: `, - poolPrices, - ); - - expect(poolPrices).not.toBeNull(); - checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey); - - // Check if onchain pricing equals to calculated ones - - for (const i in poolPrices || []) { - await checkOnChainPricing( - dystopia, - 'getAmountOut', - blocknumber, - poolPrices![i].prices, - poolPrices![i].poolAddresses![0], - tokenA.address, - amounts, - ); - } - }); - - it('getTopPoolsForToken', async function () { - const dexHelper = new DummyDexHelper(Network.POLYGON); - const dystopia = new Dystopia(Network.POLYGON, dexKey, dexHelper); - - const poolLiquidity = await dystopia.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log(`${TokenASymbol} Top Pools:`, poolLiquidity); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - }); - - describe('Curve like stable pool', function () { - const TokenASymbol = 'DAI'; // 'USDT'; - const tokenA = Tokens[Network.POLYGON][TokenASymbol]; - const TokenBSymbol = 'USDC'; - const tokenB = Tokens[Network.POLYGON][TokenBSymbol]; - - const amounts = amounts18; // amounts6; - - it('getPoolIdentifiers and getPricesVolume', async function () { - const dexHelper = new DummyDexHelper(Network.POLYGON); - const blocknumber = await dexHelper.web3Provider.eth.getBlockNumber(); - const pools = await dystopia.getPoolIdentifiers( - tokenA, - tokenB, - SwapSide.SELL, - blocknumber, - ); - console.log( - `${TokenASymbol} <> ${TokenBSymbol} Pool Identifiers: `, - pools, - ); - - expect(pools.length).toBeGreaterThan(0); - - const poolPrices = await dystopia.getPricesVolume( - tokenA, - tokenB, - amounts, - SwapSide.SELL, - blocknumber, - pools, - ); - console.log( - `${TokenASymbol} <> ${TokenBSymbol} Pool Prices: `, - poolPrices, - ); - - expect(poolPrices).not.toBeNull(); - checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey); - - // Check if onchain pricing equals to calculated ones - for (const i in poolPrices || []) { - await checkOnChainPricing( - dystopia, - 'getAmountOut', - blocknumber, - poolPrices![i].prices, - poolPrices![i].poolAddresses![0], - tokenA.address, - amounts, - ); - } - }); - - it('getTopPoolsForToken', async function () { - const dexHelper = new DummyDexHelper(Network.POLYGON); - const dystopiaStable = new Dystopia(Network.POLYGON, dexKey, dexHelper); - - const poolLiquidity = await dystopiaStable.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log(`${TokenASymbol} Top Pools:`, poolLiquidity); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - }); -}); diff --git a/src/dex/uniswap-v2/dystopia/dystopia-uniswap-v2-pool.ts b/src/dex/uniswap-v2/dystopia/dystopia-uniswap-v2-pool.ts deleted file mode 100644 index d6eedca73..000000000 --- a/src/dex/uniswap-v2/dystopia/dystopia-uniswap-v2-pool.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { RESERVE_LIMIT } from '../uniswap-v2'; -import { UniswapV2PoolOrderedParams } from '../types'; -import { BI_MAX_UINT } from '../../../bigint-constants'; -import { SWAP_FEE_FACTOR } from './constants'; - -export class DystopiaUniswapV2Pool { - // Dystopia non-stable pools has almost same formula like uniswap2, - // but little changed in contract. - // So we repeat formulas here to have same output. - static async getSellPrice( - priceParams: UniswapV2PoolOrderedParams, - srcAmount: bigint, - ): Promise { - const { reservesIn, reservesOut } = priceParams; - - if (BigInt(reservesIn) + srcAmount > RESERVE_LIMIT) { - return 0n; - } - - const amountInWithFee = srcAmount * (SWAP_FEE_FACTOR - 1n); - - const numerator = amountInWithFee * BigInt(reservesOut); - - const denominator = BigInt(reservesIn) * SWAP_FEE_FACTOR + amountInWithFee; - - return denominator === 0n ? 0n : numerator / denominator; - } - - static async getBuyPrice( - priceParams: UniswapV2PoolOrderedParams, - destAmount: bigint, - ): Promise { - const { reservesIn, reservesOut } = priceParams; - - const numerator = BigInt(reservesIn) * destAmount * SWAP_FEE_FACTOR; - const denominator = - (SWAP_FEE_FACTOR - 1n) * (BigInt(reservesOut) - destAmount); - - if (denominator <= 0n) return BI_MAX_UINT; - return 1n + numerator / denominator; - } -} diff --git a/src/dex/uniswap-v2/types.ts b/src/dex/uniswap-v2/types.ts index 961aee636..7cfc0138d 100644 --- a/src/dex/uniswap-v2/types.ts +++ b/src/dex/uniswap-v2/types.ts @@ -120,7 +120,7 @@ export type UniswapV2Data = { wethAddress?: string; }; -export type DexParams = { +export interface DexParams { subgraphURL?: string; factoryAddress: Address; initCode: string; @@ -128,9 +128,7 @@ export type DexParams = { feeCode: number; router?: Address; adapters?: { [side: string]: { name: string; index: number }[] | null }; - stableFee?: number; - volatileFee?: number; -}; +} export interface UniswapV2PoolOrderedParams { tokenIn: string; diff --git a/src/dex/uniswap-v2/uniswap-v2-e2e-polygon.test.ts b/src/dex/uniswap-v2/uniswap-v2-e2e-polygon.test.ts index eddf8a45f..470077d6e 100644 --- a/src/dex/uniswap-v2/uniswap-v2-e2e-polygon.test.ts +++ b/src/dex/uniswap-v2/uniswap-v2-e2e-polygon.test.ts @@ -1235,194 +1235,194 @@ describe('UniswapV2 E2E Polygon', () => { }); }); - describe('Dystopia', () => { - const dexKey = 'Dystopia'; - const usdAmount = '1000000'; + // describe('Dystopia', () => { + // const dexKey = 'Dystopia'; + // const usdAmount = '1000000'; - describe('Dystopia UniswapV2 Pools', () => { - const maticAmount = '1000000000000000000'; + // describe('Dystopia UniswapV2 Pools', () => { + // const maticAmount = '1000000000000000000'; - describe('simpleSwap', () => { - it('MATIC -> TOKEN', async () => { - await testE2E( - tokens.MATIC, - tokens.WETH, - holders.MATIC, - maticAmount, - SwapSide.SELL, - dexKey, - ContractMethod.simpleSwap, - network, - provider, - ); - }); + // describe('simpleSwap', () => { + // it('MATIC -> TOKEN', async () => { + // await testE2E( + // tokens.MATIC, + // tokens.WETH, + // holders.MATIC, + // maticAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.simpleSwap, + // network, + // provider, + // ); + // }); - it('Token -> MATIC', async () => { - await testE2E( - tokens.USDT, - tokens.MATIC, - holders.USDT, - usdAmount, - SwapSide.SELL, - dexKey, - ContractMethod.simpleSwap, - network, - provider, - ); - }); + // it('Token -> MATIC', async () => { + // await testE2E( + // tokens.USDT, + // tokens.MATIC, + // holders.USDT, + // usdAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.simpleSwap, + // network, + // provider, + // ); + // }); - it('Token -> Token', async () => { - await testE2E( - tokens.WMATIC, - tokens.WETH, - holders.WMATIC, - maticAmount, - SwapSide.SELL, - dexKey, - ContractMethod.simpleSwap, - network, - provider, - ); - }); - }); + // it('Token -> Token', async () => { + // await testE2E( + // tokens.WMATIC, + // tokens.WETH, + // holders.WMATIC, + // maticAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.simpleSwap, + // network, + // provider, + // ); + // }); + // }); - describe('multiSwap', () => { - it('MATIC -> TOKEN', async () => { - await testE2E( - tokens.MATIC, - tokens.WETH, - holders.MATIC, - maticAmount, - SwapSide.SELL, - dexKey, - ContractMethod.multiSwap, - network, - provider, - ); - }); + // describe('multiSwap', () => { + // it('MATIC -> TOKEN', async () => { + // await testE2E( + // tokens.MATIC, + // tokens.WETH, + // holders.MATIC, + // maticAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.multiSwap, + // network, + // provider, + // ); + // }); - it('Token -> MATIC', async () => { - await testE2E( - tokens.USDT, - tokens.MATIC, - holders.USDT, - usdAmount, - SwapSide.SELL, - dexKey, - ContractMethod.multiSwap, - network, - provider, - ); - }); + // it('Token -> MATIC', async () => { + // await testE2E( + // tokens.USDT, + // tokens.MATIC, + // holders.USDT, + // usdAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.multiSwap, + // network, + // provider, + // ); + // }); - it('Token -> Token', async () => { - await testE2E( - tokens.WMATIC, - tokens.WETH, - holders.WMATIC, - maticAmount, - SwapSide.SELL, - dexKey, - ContractMethod.multiSwap, - network, - provider, - ); - }); - }); + // it('Token -> Token', async () => { + // await testE2E( + // tokens.WMATIC, + // tokens.WETH, + // holders.WMATIC, + // maticAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.multiSwap, + // network, + // provider, + // ); + // }); + // }); - describe('megaSwap', () => { - it('MATIC -> TOKEN', async () => { - await testE2E( - tokens.USDT, - tokens.MATIC, - holders.USDT, - usdAmount, - SwapSide.SELL, - dexKey, - ContractMethod.megaSwap, - network, - provider, - ); - }); + // describe('megaSwap', () => { + // it('MATIC -> TOKEN', async () => { + // await testE2E( + // tokens.USDT, + // tokens.MATIC, + // holders.USDT, + // usdAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.megaSwap, + // network, + // provider, + // ); + // }); - it('Token -> MATIC', async () => { - await testE2E( - tokens.USDT, - tokens.MATIC, - holders.USDT, - usdAmount, - SwapSide.SELL, - dexKey, - ContractMethod.megaSwap, - network, - provider, - ); - }); + // it('Token -> MATIC', async () => { + // await testE2E( + // tokens.USDT, + // tokens.MATIC, + // holders.USDT, + // usdAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.megaSwap, + // network, + // provider, + // ); + // }); - it('Token -> Token', async () => { - await testE2E( - tokens.WMATIC, - tokens.WETH, - holders.WMATIC, - maticAmount, - SwapSide.SELL, - dexKey, - ContractMethod.megaSwap, - network, - provider, - ); - }); - }); - }); + // it('Token -> Token', async () => { + // await testE2E( + // tokens.WMATIC, + // tokens.WETH, + // holders.WMATIC, + // maticAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.megaSwap, + // network, + // provider, + // ); + // }); + // }); + // }); - describe('Dystopia Stable Pools', () => { - describe('simpleSwap', () => { - it('Token -> Token', async () => { - await testE2E( - tokens.USDC, - tokens.USDT, - holders.USDC, - usdAmount, - SwapSide.SELL, - dexKey, - ContractMethod.simpleSwap, - network, - provider, - ); - }); - }); + // describe('Dystopia Stable Pools', () => { + // describe('simpleSwap', () => { + // it('Token -> Token', async () => { + // await testE2E( + // tokens.USDC, + // tokens.USDT, + // holders.USDC, + // usdAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.simpleSwap, + // network, + // provider, + // ); + // }); + // }); - describe('multiSwap', () => { - it('Token -> Token', async () => { - await testE2E( - tokens.USDC, - tokens.USDT, - holders.USDC, - usdAmount, - SwapSide.SELL, - dexKey, - ContractMethod.multiSwap, - network, - provider, - ); - }); - }); + // describe('multiSwap', () => { + // it('Token -> Token', async () => { + // await testE2E( + // tokens.USDC, + // tokens.USDT, + // holders.USDC, + // usdAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.multiSwap, + // network, + // provider, + // ); + // }); + // }); - describe('megaSwap', () => { - it('Token -> Token', async () => { - await testE2E( - tokens.USDC, - tokens.USDT, - holders.USDC, - usdAmount, - SwapSide.SELL, - dexKey, - ContractMethod.megaSwap, - network, - provider, - ); - }); - }); - }); - }); + // describe('megaSwap', () => { + // it('Token -> Token', async () => { + // await testE2E( + // tokens.USDC, + // tokens.USDT, + // holders.USDC, + // usdAmount, + // SwapSide.SELL, + // dexKey, + // ContractMethod.megaSwap, + // network, + // provider, + // ); + // }); + // }); + // }); + // }); }); diff --git a/src/dex/velodrome.ts b/src/dex/velodrome.ts deleted file mode 100644 index 17894e46d..000000000 --- a/src/dex/velodrome.ts +++ /dev/null @@ -1,54 +0,0 @@ -import Web3 from 'web3'; -import { Address } from '../types'; -import { IDexTxBuilder } from './idex'; -import { IDexHelper } from '../dex-helper'; -import { DexParams, UniswapParam, UniswapV2Data } from './uniswap-v2/types'; -import { Dystopia } from './uniswap-v2/dystopia/dystopia'; -import { Network } from '../constants'; - -const dexKey = 'Velodrome'; - -export const VelodromConfig: Record = { - [Network.OPTIMISM]: { - subgraphURL: 'https://api.thegraph.com/subgraphs/name/dmihal/velodrome', - factoryAddress: '0x25cbddb98b35ab1ff77413456b31ec81a6b6b746', - // ParaSwap-compatible Router with stable pools support - router: '0xa2f581b012E0f2dcCDe86fCbfb529f4aC5dD4983', - initCode: - '0xc1ac28b1c4ebe53c0cff67bab5878c4eb68759bb1e9f73977cd266b247d149f0', - stableFee: 2, - volatileFee: 2, - poolGasCost: 180 * 1000, - - feeCode: 2, // Not used - set for type. TODO: clean up when move to fully event based - }, -}; - -export class Velodrome - extends Dystopia - implements IDexTxBuilder -{ - static dexKeys = [dexKey.toLowerCase()]; - - constructor( - augustusAddress: Address, - network: Network, - provider: Web3, - dexHelper?: IDexHelper, - ) { - if (dexHelper === undefined) - throw new Error(`DexHelper must be provided to ${dexKey}`); - super( - network, - dexKey, - dexHelper, - true, - VelodromConfig[network].factoryAddress, - VelodromConfig[network].subgraphURL, - VelodromConfig[network].initCode, - VelodromConfig[network].stableFee, - VelodromConfig[network].poolGasCost, - VelodromConfig[network].router, - ); - } -}