From b598e537f8f599aa87b6bede12c004f02c59088b Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Thu, 9 May 2024 17:45:05 +0200 Subject: [PATCH 1/8] ape-uni-sdk init commit --- examples/integrations/uniswap/test_funcs.py | 75 ++ .../integrations/uniswap/ASSETS/erc20.json | 222 ++++++ .../uniswap/ASSETS/nft_manager.json | 686 +++++++++++++++++ .../integrations/uniswap/ASSETS/pool.json | 692 ++++++++++++++++++ .../uniswap/ASSETS/pool_factory.json | 148 ++++ .../integrations/uniswap/ASSETS/quoter.json | 97 +++ .../integrations/uniswap/ASSETS/router.json | 548 ++++++++++++++ .../integrations/uniswap/addresses.py | 39 + .../integrations/uniswap/constants.py | 6 + .../integrations/uniswap/nft_manager.py | 99 +++ giza_actions/integrations/uniswap/pool.py | 37 + .../integrations/uniswap/pool_factory.py | 20 + giza_actions/integrations/uniswap/quoter.py | 20 + giza_actions/integrations/uniswap/router.py | 66 ++ giza_actions/integrations/uniswap/uniswap.py | 36 + giza_actions/integrations/uniswap/utils.py | 77 ++ 16 files changed, 2868 insertions(+) create mode 100644 examples/integrations/uniswap/test_funcs.py create mode 100644 giza_actions/integrations/uniswap/ASSETS/erc20.json create mode 100644 giza_actions/integrations/uniswap/ASSETS/nft_manager.json create mode 100644 giza_actions/integrations/uniswap/ASSETS/pool.json create mode 100644 giza_actions/integrations/uniswap/ASSETS/pool_factory.json create mode 100644 giza_actions/integrations/uniswap/ASSETS/quoter.json create mode 100644 giza_actions/integrations/uniswap/ASSETS/router.json create mode 100644 giza_actions/integrations/uniswap/addresses.py create mode 100644 giza_actions/integrations/uniswap/constants.py create mode 100644 giza_actions/integrations/uniswap/nft_manager.py create mode 100644 giza_actions/integrations/uniswap/pool.py create mode 100644 giza_actions/integrations/uniswap/pool_factory.py create mode 100644 giza_actions/integrations/uniswap/quoter.py create mode 100644 giza_actions/integrations/uniswap/router.py create mode 100644 giza_actions/integrations/uniswap/uniswap.py create mode 100644 giza_actions/integrations/uniswap/utils.py diff --git a/examples/integrations/uniswap/test_funcs.py b/examples/integrations/uniswap/test_funcs.py new file mode 100644 index 0000000..55c3df7 --- /dev/null +++ b/examples/integrations/uniswap/test_funcs.py @@ -0,0 +1,75 @@ +import os +from dotenv import load_dotenv, find_dotenv +from ape import networks, Contract, accounts +from giza_actions.integrations.uniswap.uniswap import Uniswap + +networks.parse_network_choice(f"ethereum:mainnet-fork:foundry").__enter__() +load_dotenv(find_dotenv()) + +dev_passphrase = os.environ.get("DEV_PASSPHRASE") +sender = accounts.load("dev") +sender.set_autosign(True, passphrase=dev_passphrase) + +weth_address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" +usdc_address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" +token0 = Contract(weth_address) +token1 = Contract(usdc_address) +fee = 500 + +### Uniswap ### +uni = Uniswap(sender=sender, version=3) +pool = uni.get_pool(token0, token1, fee) +price = pool.get_pool_price(invert=True) +print(f"--------- Pool Price: {price}") + +### Quoter ### +amount_in = int(1e8) +# calling using pool object +amount_out = uni.quoter.quote_exact_input_single(amount_in, pool=pool) +print(f"--------- Amount out: {amount_out}") +# # or by specifying the tokens and the fee +amount_out = uni.quoter.quote_exact_input_single(amount_in, token_in = token1, token_out = token0, fee = fee) +print(f"--------- Amount out: {amount_out}") + +### Router ### +sender.balance += int(2e18) # funding 1 eth more than we will use for gas +token0.approve(sender, int(1e18), sender=sender) +token0.deposit(value=int(1e18), sender=sender) +token0_balance = token0.balanceOf(sender) +print(f"--------- Balances before swap: {token0_balance} {token1.balanceOf(sender)}") +token0.approve(uni.router.contract, token0_balance, sender=sender) +uni.router.swap_exact_input_single(token0_balance, token_in = token0, token_out=token1, fee=fee) +print(f"--------- Balances after exactInputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}") +token1.approve(uni.router.contract, token1.balanceOf(sender), sender=sender) +token0_amount_out = int(1e16) # 0.01 eth +accepted_slippage = 0.01 # 1% +amount_in_max = int(token1.balanceOf(sender) * (1 - accepted_slippage)) +uni.router.swap_exact_output_single(token0_amount_out, token_in = token1, token_out=token0, fee=fee, amount_in_max=amount_in_max) +print(f"--------- Balances after exactOutputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}") + +### NFT Manager ### +token0.approve(uni.nft_manager.contract, token0.balanceOf(sender), sender=sender) +token1.approve(uni.nft_manager.contract, token1.balanceOf(sender), sender=sender) +user_positions = uni.nft_manager.get_all_user_positions() +print(f"--------- User Positions Init: {user_positions}") +amount0_to_mint = int(0.5 * token0.balanceOf(sender)) +amount1_to_mint = int(0.5 * token1.balanceOf(sender)) +price = pool.get_pool_price(invert=True) +pct_dev = 0.1 +lower_price = int(price * (1 - pct_dev)) +upper_price = int(price * (1 + pct_dev)) +uni.nft_manager.mint_position(pool, lower_price, upper_price, amount0=amount0_to_mint, amount1=amount1_to_mint, amount0_min=None, amount1_min=None, recipient=None, deadline=None, slippage_tolerance=1) +user_positions = uni.nft_manager.get_all_user_positions() +print(f"--------- User Positions after minting: {user_positions}") +nft_id = user_positions[0] +pos_info = uni.nft_manager.get_pos_info(nft_id) +print(f"--------- {nft_id} Info: {pos_info}") +increase_fraction = 0.1 +amount0_desired = int(amount0_to_mint*(1+increase_fraction)) +amount1_desired = int(amount1_to_mint*(1+increase_fraction)) +uni.nft_manager.add_liquidity(nft_id, amount0_desired, amount1_desired, amount0Min=0, amount1Min=0, deadline=None) +pos_info = uni.nft_manager.get_pos_info(nft_id) +print(f"--------- {nft_id} Info Add Liq: {pos_info}") +uni.nft_manager.close_position(nft_id) +user_positions = uni.nft_manager.get_all_user_positions() +print(f"--------- {nft_id} Burnt, user_pos: {user_positions}") \ No newline at end of file diff --git a/giza_actions/integrations/uniswap/ASSETS/erc20.json b/giza_actions/integrations/uniswap/ASSETS/erc20.json new file mode 100644 index 0000000..405d6b3 --- /dev/null +++ b/giza_actions/integrations/uniswap/ASSETS/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" + } +] diff --git a/giza_actions/integrations/uniswap/ASSETS/nft_manager.json b/giza_actions/integrations/uniswap/ASSETS/nft_manager.json new file mode 100644 index 0000000..720db54 --- /dev/null +++ b/giza_actions/integrations/uniswap/ASSETS/nft_manager.json @@ -0,0 +1,686 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_WETH9", "type": "address" }, + { + "internalType": "address", + "name": "_tokenDescriptor_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "DecreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "IncreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "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": [], + "name": "WETH9", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } + ], + "internalType": "struct INonfungiblePositionManager.CollectParams", + "name": "params", + "type": "tuple" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" } + ], + "name": "createAndInitializePoolIfNecessary", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManager.DecreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "decreaseLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "getApproved", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManager.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "isApprovedForAll", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManager.MintParams", + "name": "params", + "type": "tuple" + } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [ + { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "ownerOf", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "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": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "positions", + "outputs": [ + { "internalType": "uint96", "name": "nonce", "type": "uint96" }, + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { "internalType": "uint128", "name": "tokensOwed0", "type": "uint128" }, + { "internalType": "uint128", "name": "tokensOwed1", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "refundETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "_data", "type": "bytes" } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "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": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "expiry", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "expiry", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "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": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "bool", "name": "approved", "type": "bool" } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "tokenByIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "tokenURI", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Owed", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Owed", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/giza_actions/integrations/uniswap/ASSETS/pool.json b/giza_actions/integrations/uniswap/ASSETS/pool.json new file mode 100644 index 0000000..773ce15 --- /dev/null +++ b/giza_actions/integrations/uniswap/ASSETS/pool.json @@ -0,0 +1,692 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "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" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" } + ], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint32", "name": "blockTimestamp", "type": "uint32" }, + { "internalType": "int56", "name": "tickCumulative", "type": "int56" }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { "internalType": "bool", "name": "initialized", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32[]", "name": "secondsAgos", "type": "uint32[]" } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "positions", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { "internalType": "uint128", "name": "tokensOwed0", "type": "uint128" }, + { "internalType": "uint128", "name": "tokensOwed1", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { "internalType": "uint128", "name": "token0", "type": "uint128" }, + { "internalType": "uint128", "name": "token1", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint8", "name": "feeProtocol0", "type": "uint8" }, + { "internalType": "uint8", "name": "feeProtocol1", "type": "uint8" } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }, + { "internalType": "int24", "name": "tick", "type": "int24" }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { "internalType": "uint8", "name": "feeProtocol", "type": "uint8" }, + { "internalType": "bool", "name": "unlocked", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { "internalType": "uint32", "name": "secondsInside", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "bool", "name": "zeroForOne", "type": "bool" }, + { "internalType": "int256", "name": "amountSpecified", "type": "int256" }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [ + { "internalType": "int256", "name": "amount0", "type": "int256" }, + { "internalType": "int256", "name": "amount1", "type": "int256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "int16", "name": "", "type": "int16" }], + "name": "tickBitmap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "int24", "name": "", "type": "int24" }], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { "internalType": "int128", "name": "liquidityNet", "type": "int128" }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { "internalType": "uint32", "name": "secondsOutside", "type": "uint32" }, + { "internalType": "bool", "name": "initialized", "type": "bool" } + ], + "stateMutability": "view", + "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" + } +] diff --git a/giza_actions/integrations/uniswap/ASSETS/pool_factory.json b/giza_actions/integrations/uniswap/ASSETS/pool_factory.json new file mode 100644 index 0000000..1ab193f --- /dev/null +++ b/giza_actions/integrations/uniswap/ASSETS/pool_factory.json @@ -0,0 +1,148 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "FeeAmountEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" } + ], + "name": "createPool", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "int24", "name": "tickSpacing", "type": "int24" } + ], + "name": "enableFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], + "name": "feeAmountTickSpacing", + "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint24", "name": "", "type": "uint24" } + ], + "name": "getPool", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "parameters", + "outputs": [ + { "internalType": "address", "name": "factory", "type": "address" }, + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "int24", "name": "tickSpacing", "type": "int24" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/giza_actions/integrations/uniswap/ASSETS/quoter.json b/giza_actions/integrations/uniswap/ASSETS/quoter.json new file mode 100644 index 0000000..e9adacb --- /dev/null +++ b/giza_actions/integrations/uniswap/ASSETS/quoter.json @@ -0,0 +1,97 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_WETH9", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "WETH9", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "path", "type": "bytes" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "name": "quoteExactInput", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "address", "name": "tokenOut", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "name": "quoteExactInputSingle", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "path", "type": "bytes" }, + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "name": "quoteExactOutput", + "outputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "address", "name": "tokenOut", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "name": "quoteExactOutputSingle", + "outputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "int256", "name": "amount0Delta", "type": "int256" }, + { "internalType": "int256", "name": "amount1Delta", "type": "int256" }, + { "internalType": "bytes", "name": "path", "type": "bytes" } + ], + "name": "uniswapV3SwapCallback", + "outputs": [], + "stateMutability": "view", + "type": "function" + } +] diff --git a/giza_actions/integrations/uniswap/ASSETS/router.json b/giza_actions/integrations/uniswap/ASSETS/router.json new file mode 100644 index 0000000..a679349 --- /dev/null +++ b/giza_actions/integrations/uniswap/ASSETS/router.json @@ -0,0 +1,548 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_factoryV2", "type": "address" }, + { "internalType": "address", "name": "factoryV3", "type": "address" }, + { + "internalType": "address", + "name": "_positionManager", + "type": "address" + }, + { "internalType": "address", "name": "_WETH9", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "WETH9", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "approveMax", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "approveMaxMinusOne", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "approveZeroThenMax", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "approveZeroThenMaxMinusOne", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }], + "name": "callPositionManager", + "outputs": [{ "internalType": "bytes", "name": "result", "type": "bytes" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "paths", "type": "bytes[]" }, + { "internalType": "uint128[]", "name": "amounts", "type": "uint128[]" }, + { + "internalType": "uint24", + "name": "maximumTickDivergence", + "type": "uint24" + }, + { "internalType": "uint32", "name": "secondsAgo", "type": "uint32" } + ], + "name": "checkOracleSlippage", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "path", "type": "bytes" }, + { + "internalType": "uint24", + "name": "maximumTickDivergence", + "type": "uint24" + }, + { "internalType": "uint32", "name": "secondsAgo", "type": "uint32" } + ], + "name": "checkOracleSlippage", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bytes", "name": "path", "type": "bytes" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + } + ], + "internalType": "struct IV3SwapRouter.ExactInputParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInput", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "address", "name": "tokenOut", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "internalType": "struct IV3SwapRouter.ExactInputSingleParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInputSingle", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bytes", "name": "path", "type": "bytes" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amountInMaximum", + "type": "uint256" + } + ], + "internalType": "struct IV3SwapRouter.ExactOutputParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactOutput", + "outputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "address", "name": "tokenOut", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amountInMaximum", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "internalType": "struct IV3SwapRouter.ExactOutputSingleParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactOutputSingle", + "outputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factoryV2", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getApprovalType", + "outputs": [ + { + "internalType": "enum IApproveAndCall.ApprovalType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { "internalType": "uint256", "name": "amount1Min", "type": "uint256" } + ], + "internalType": "struct IApproveAndCall.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [{ "internalType": "bytes", "name": "result", "type": "bytes" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "internalType": "struct IApproveAndCall.MintParams", + "name": "params", + "type": "tuple" + } + ], + "name": "mint", + "outputs": [{ "internalType": "bytes", "name": "result", "type": "bytes" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "previousBlockhash", + "type": "bytes32" + }, + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [{ "internalType": "bytes[]", "name": "", "type": "bytes[]" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [{ "internalType": "bytes[]", "name": "", "type": "bytes[]" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [ + { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "positionManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "pull", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "refundETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "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": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "expiry", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "expiry", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "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": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" }, + { "internalType": "address[]", "name": "path", "type": "address[]" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, + { "internalType": "uint256", "name": "amountInMax", "type": "uint256" }, + { "internalType": "address[]", "name": "path", "type": "address[]" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "swapTokensForExactTokens", + "outputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, + { "internalType": "address", "name": "feeRecipient", "type": "address" } + ], + "name": "sweepTokenWithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, + { "internalType": "address", "name": "feeRecipient", "type": "address" } + ], + "name": "sweepTokenWithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "int256", "name": "amount0Delta", "type": "int256" }, + { "internalType": "int256", "name": "amount1Delta", "type": "int256" }, + { "internalType": "bytes", "name": "_data", "type": "bytes" } + ], + "name": "uniswapV3SwapCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, + { "internalType": "address", "name": "feeRecipient", "type": "address" } + ], + "name": "unwrapWETH9WithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, + { "internalType": "address", "name": "feeRecipient", "type": "address" } + ], + "name": "unwrapWETH9WithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "wrapETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/giza_actions/integrations/uniswap/addresses.py b/giza_actions/integrations/uniswap/addresses.py new file mode 100644 index 0000000..0dc20f8 --- /dev/null +++ b/giza_actions/integrations/uniswap/addresses.py @@ -0,0 +1,39 @@ +ADDRESSES = { + # mainnet + 1: { + 3: { + "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", + "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", + "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", + "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", + }, + }, + # sepolia + 11155111: { + 3: { + "PoolFactory": "0x0227628f3F023bb0B980b67D528571c95c6DaC1c", + "NonfungiblePositionManager": "0x1238536071E1c677A632429e3655c799b22cDA52", + "Router": "0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E", + "Quoter": "0xEd1f6473345F45b75F8179591dd5bA1888cf2FB3", + }, + }, + # goerli + 5: { + 3: { + "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", + "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", + "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", + "Quoter": "", + }, + }, + # arbitrum + 42161: { + 3: { + "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", + "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", + "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", + "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", + }, + }, + # TODO: fill remaining chains: https://github.com/Uniswap/v3-periphery/blob/main/deploys.md +} \ No newline at end of file diff --git a/giza_actions/integrations/uniswap/constants.py b/giza_actions/integrations/uniswap/constants.py new file mode 100644 index 0000000..dbf26f6 --- /dev/null +++ b/giza_actions/integrations/uniswap/constants.py @@ -0,0 +1,6 @@ +MIN_TICK = -887272 +MAX_TICK = -MIN_TICK +TICKS_Q = 1.0001 +Q96 = 2**96 +MAX_UINT_128 = 2 ** (128) - 1 +_tick_spacing = {100: 1, 500: 10, 3_000: 60, 10_000: 200} diff --git a/giza_actions/integrations/uniswap/nft_manager.py b/giza_actions/integrations/uniswap/nft_manager.py new file mode 100644 index 0000000..aea0d7b --- /dev/null +++ b/giza_actions/integrations/uniswap/nft_manager.py @@ -0,0 +1,99 @@ +from ape import Contract +from .utils import price_to_tick, nearest_tick, calc_amount0, calc_amount1, price_to_sqrtp, liquidity0, liquidity1 +from .constants import MAX_UINT_128 +import time +import os + +class NFTManager: + def __init__(self, address, sender): + self.contract = Contract(address, abi = os.path.join(os.path.dirname(__file__), "ASSETS/nft_manager.json")) + self.sender = sender + + def get_all_user_positions(self, user_address=None): + if user_address is None: + user_address = self.sender + n_positions = self.contract.balanceOf(user_address) + positions = [] + for n in range(n_positions): + position = self.contract.tokenOfOwnerByIndex(user_address, n) + positions.append(position) + return positions + + def get_pos_info(self, nft_id): + return self.contract.positions(nft_id) + + def close_position(self, nft_id, user_address=None): + if user_address is None: + user_address = self.sender + liquidity = self.get_pos_info(nft_id)['liquidity'] + if liquidity > 0: + self.decrease_liquidity(nft_id, liquidity=liquidity) + self.collect_fees(nft_id, user_address=user_address) + self.contract.burn(nft_id, sender=self.sender) + + def collect_fees(self, nft_id, user_address=None, amount0_max=MAX_UINT_128, amount1_max=MAX_UINT_128): + if user_address is None: + user_address = self.sender + receipt = self.contract.collect((nft_id, user_address, amount0_max, amount1_max), sender=self.sender) + return receipt + + def decrease_liquidity(self, nft_id, liquidity=None, amount0Min=0, amount1Min=0, deadline=None): + if liquidity is None: + liquidity = self.get_pos_info(nft_id)['liquidity'] + if deadline is None: + deadline = int(time.time() + 60) + receipt = self.contract.decreaseLiquidity((nft_id, liquidity, amount0Min, amount1Min, deadline), sender=self.sender) + return receipt + + def add_liquidity(self, nft_id, amount0Desired, amount1Desired, amount0Min=0, amount1Min=0, deadline=None): + if deadline is None: + deadline = int(time.time() + 60) + receipt = self.contract.increaseLiquidity((nft_id, amount0Desired, amount1Desired, amount0Min, amount1Min, deadline), sender=self.sender) + return receipt + + def mint_position(self, pool, lower_price, upper_price, amount0, amount1, amount0_min=None, amount1_min=None, recipient=None, deadline=None, slippage_tolerance=1): + fee = pool.fee + token0 = pool.token0 + token1 = pool.token1 + + lower_tick = price_to_tick(lower_price) + upper_tick = price_to_tick(upper_price) + lower_tick = nearest_tick(lower_tick, fee) + upper_tick = nearest_tick(upper_tick, fee) + + if lower_tick > upper_tick: + raise ValueError("Lower tick must be less than upper tick") + + sqrtp_cur = pool.get_pool_info()['sqrtPriceX96'] + sqrtp_low = price_to_sqrtp(lower_price) + sqrtp_upp = price_to_sqrtp(upper_price) + liq0 = liquidity0(amount0, sqrtp_cur, sqrtp_upp) + liq1 = liquidity1(amount1, sqrtp_cur, sqrtp_low) + liq = int(min(liq0, liq1)) + amount0 = calc_amount0(liq, sqrtp_upp, sqrtp_cur) + amount1 = calc_amount1(liq, sqrtp_low, sqrtp_cur) + + if recipient is None: + recipient = self.sender + if deadline is None: + deadline = int(time.time() + 60) + if amount0_min is None: + amount0_min = int(amount0 * (1 - slippage_tolerance)) + if amount1_min is None: + amount1_min = int(amount1 * (1 - slippage_tolerance)) + + mint_params = { + "token0": token0.address, + "token1": token1.address, + "fee": fee, + "tickLower": lower_tick, + "tickUpper": upper_tick, + "amount0Desired": amount0, + "amount1Desired": amount1, + "amount0Min": amount0_min, + "amount1Min": amount1_min, + "recipient": recipient, + "deadline": deadline, + } + return self.contract.mint(mint_params, sender=self.sender) + diff --git a/giza_actions/integrations/uniswap/pool.py b/giza_actions/integrations/uniswap/pool.py new file mode 100644 index 0000000..a74eb6a --- /dev/null +++ b/giza_actions/integrations/uniswap/pool.py @@ -0,0 +1,37 @@ +from ape import Contract, chain +from .utils import tick_to_price +import os + +class Pool: + def __init__(self, address, sender, token0=None, token1=None, fee=None): + self.contract = Contract(address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/pool.json")) + self.sender = sender + self.token0 = Contract(self.contract.token0(), abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json")) + self.token0_decimals = self.token0.decimals() + self.token1 = Contract(self.contract.token1(), abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json")) + self.token1_decimals = self.token1.decimals() + self.fee = self.contract.fee() if fee is None else fee + + + def get_pool_info(self, block_number=None): + if block_number is None: + block_number = chain.blocks.height + ( + sqrtPriceX96, tick, observationIndex, observationCardinality, observationCardinalityNext, feeProtocol, unlocked + ) = self.contract.slot0() + return { + "sqrtPriceX96": sqrtPriceX96, + "tick": tick, + "observationIndex": observationIndex, + "observationCardinality": observationCardinality, + "observationCardinalityNext": observationCardinalityNext, + "feeProtocol": feeProtocol, + "unlocked": unlocked, + } + + def get_pool_price(self, block_number=None, invert=False): + if block_number is None: + block_number = chain.blocks.height + tick = self.get_pool_info(block_number)['tick'] + return tick_to_price(tick, self.token0_decimals, self.token1_decimals, invert=invert) + diff --git a/giza_actions/integrations/uniswap/pool_factory.py b/giza_actions/integrations/uniswap/pool_factory.py new file mode 100644 index 0000000..009a355 --- /dev/null +++ b/giza_actions/integrations/uniswap/pool_factory.py @@ -0,0 +1,20 @@ +from ape import Contract +from .pool import Pool +import os + +class PoolFactory: + def __init__(self, address, sender): + self.contract = Contract(address, abi = os.path.join(os.path.dirname(__file__), "ASSETS/pool_factory.json")) + self.sender = sender + + def get_pool(self, token0, token1, fee): + if type(fee)==float: + fee = int(fee*1e6) + pool_address = self.contract.getPool(token0, token1, fee) + return Pool(pool_address, self.sender, token0=token0, token1=token1, fee=fee) + + + def create_pool(self, token0, token1, fee): + if type(fee)==float: + fee = int(fee*1e6) + return self.contract.createPool(token0, token1, fee, sender=self.sender) \ No newline at end of file diff --git a/giza_actions/integrations/uniswap/quoter.py b/giza_actions/integrations/uniswap/quoter.py new file mode 100644 index 0000000..7a2431d --- /dev/null +++ b/giza_actions/integrations/uniswap/quoter.py @@ -0,0 +1,20 @@ +from ape import Contract +import os + +class Quoter: + def __init__(self, address, sender): + self.contract = Contract(address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/quoter.json")) + self.sender = sender + + def quote_exact_input_single(self, amount_in, pool=None, token_in=None, token_out=None, fee=None, sqrt_price_limit_x96=0): + if pool is None and (token_in is None or token_out is None or fee is None): + raise Exception("Must provide pool or token_in, token_out, and fee") + + if (token_in is None or token_out is None or fee is None): + token_in = pool.token0 if token_in is None else token_in + token_out = pool.token1 if token_out is None else token_out + fee = pool.fee if fee is None else fee + + return self.contract.quoteExactInputSingle.call(token_in, token_out, fee, amount_in, sqrt_price_limit_x96) + + diff --git a/giza_actions/integrations/uniswap/router.py b/giza_actions/integrations/uniswap/router.py new file mode 100644 index 0000000..9eb7630 --- /dev/null +++ b/giza_actions/integrations/uniswap/router.py @@ -0,0 +1,66 @@ +from ape import Contract +import os +import time + + +class Router: + def __init__(self, address, sender): + self.contract = Contract(address, abi = os.path.join(os.path.dirname(__file__), "ASSETS/router.json")) + self.sender = sender + + def swap_exact_input_single(self, amount_in, pool=None, token_in=None, token_out=None, fee=None, amount_out_min=0, sqrt_price_limit_x96=0, deadline=None): + if deadline is None: + deadline = int(time.time()) + 60 + + if pool is None and (token_in is None or token_out is None or fee is None): + raise Exception("Must provide pool or token_in, token_out, and fee") + + if (token_in is None or token_out is None or fee is None): + token_in = pool.token0 if token_in is None else token_in + token_out = pool.token1 if token_out is None else token_out + fee = pool.fee if fee is None else fee + + # TODO: + # add slippage and pool price impact protection + # if amount_out_min or sqrt_price_limit_x96 are floats + + swap_params = { + "tokenIn": token_in, + "tokenOut": token_out, + "fee": fee, + "recipient": self.sender, + "amountIn": amount_in, + "amountOutMinimum": amount_out_min, + "sqrtPriceLimitX96": sqrt_price_limit_x96, + } + + return self.contract.exactInputSingle(swap_params, sender=self.sender) + + def swap_exact_output_single(self, amount_out, pool=None, token_in=None, token_out=None, fee=None, amount_in_max=0, sqrt_price_limit_x96=0, deadline=None): + if deadline is None: + deadline = int(time.time()) + 60 + + if pool is None and (token_in is None or token_out is None or fee is None): + raise Exception("Must provide pool or token_in, token_out, and fee") + + if (token_in is None or token_out is None or fee is None): + token_in = pool.token0 if token_in is None else token_in + token_out = pool.token1 if token_out is None else token_out + fee = pool.fee if fee is None else fee + + # TODO: + # add slippage and pool price impact protection + # if amount_out_min or sqrt_price_limit_x96 are floats + + swap_params = { + "tokenIn": token_in, + "tokenOut": token_out, + "fee": fee, + "recipient": self.sender, + "deadline": deadline, + "amountOut": amount_out, + "amountInMaximum": amount_in_max, + "sqrtPriceLimitX96": sqrt_price_limit_x96, + } + + return self.contract.exactOutputSingle(swap_params, sender=self.sender) \ No newline at end of file diff --git a/giza_actions/integrations/uniswap/uniswap.py b/giza_actions/integrations/uniswap/uniswap.py new file mode 100644 index 0000000..3facacf --- /dev/null +++ b/giza_actions/integrations/uniswap/uniswap.py @@ -0,0 +1,36 @@ +from ape import chain +from .addresses import ADDRESSES +from .pool_factory import PoolFactory +from .router import Router +from .quoter import Quoter +from .nft_manager import NFTManager + +class Uniswap: + def __init__(self, sender, version=3): + self.sender = sender + self._chain_id = chain.chain_id + self.version = version + self._load_contracts() + + def _load_contracts(self): + if self.version == 2: + # TODO + pass + elif self.version == 3: + self.pool_factory = PoolFactory(ADDRESSES[self._chain_id][self.version]["PoolFactory"], sender=self.sender) + self.router = Router(ADDRESSES[self._chain_id][self.version]["Router"], sender=self.sender) + self.quoter = Quoter(ADDRESSES[self._chain_id][self.version]["Quoter"], sender=self.sender) + self.nft_manager = NFTManager(ADDRESSES[self._chain_id][self.version]["NonfungiblePositionManager"], sender=self.sender) + else: + raise NotImplementedError("Uniswap version {} not supported".format(self.version)) + + def print_addresses(self): + print(f"PoolFactory: {self.pool_factory.contract.address}") + print(f"Router: {self.router.contract.address}") + print(f"Quoter: {self.quoter.contract.address}") + print(f"NFT Manager: {self.nft_manager.contract.address}") + + def get_pool(self, token0, token1, fee): + return self.pool_factory.get_pool(token0, token1, fee) + + diff --git a/giza_actions/integrations/uniswap/utils.py b/giza_actions/integrations/uniswap/utils.py new file mode 100644 index 0000000..174f61c --- /dev/null +++ b/giza_actions/integrations/uniswap/utils.py @@ -0,0 +1,77 @@ +from ape import Contract +import math +from .constants import TICKS_Q, Q96, MIN_TICK, MAX_TICK, _tick_spacing +import json + +def load_json(path): + with open(path) as f: + return json.load(f) + +def load_contract(address): + return Contract(address) + +def price_to_tick(price): + sqrtPriceX96 = int(price * 2**96) + tick = math.floor(math.log((sqrtPriceX96 / Q96) ** 2) / math.log(TICKS_Q)) + return tick + +def price_to_sqrtp(p): + return int(math.sqrt(p) * Q96) + + +def tick_to_price(tick, decimals0, decimals1, invert=False): + if invert: + return 1 / (TICKS_Q**tick / 10 ** (decimals1 - decimals0)) + else: + return TICKS_Q**tick / 10 ** (decimals1 - decimals0) + +def get_min_tick(fee): + min_tick_spacing = _tick_spacing[fee] + return -(MIN_TICK // -min_tick_spacing) * min_tick_spacing + + +def get_max_tick(fee): + max_tick_spacing = _tick_spacing[fee] + return (MAX_TICK // max_tick_spacing) * max_tick_spacing + + +def default_tick_range(fee): + min_tick = get_min_tick(fee) + max_tick = get_max_tick(fee) + return min_tick, max_tick + +# https://uniswapv3book.com/milestone_1/calculating-liquidity.html +def calc_amount0(liq, pa, pb): + if pa > pb: + pa, pb = pb, pa + return int(liq * Q96 * (pb - pa) / pa / pb) + + +def calc_amount1(liq, pa, pb): + if pa > pb: + pa, pb = pb, pa + return int(liq * (pb - pa) / Q96) + +def liquidity0(amount, pa, pb): + if pa > pb: + pa, pb = pb, pa + return (amount * (pa * pb) / Q96) / (pb - pa) + +def liquidity1(amount, pa, pb): + if pa > pb: + pa, pb = pb, pa + return amount * Q96 / (pb - pa) + +def nearest_tick(tick, fee): + min_tick, max_tick = default_tick_range(fee) + assert ( + min_tick <= tick <= max_tick + ), f"Provided tick is out of bounds: {(min_tick, max_tick)}" + tick_spacing = _tick_spacing[fee] + rounded_tick_spacing = round(tick / tick_spacing) * tick_spacing + if rounded_tick_spacing < min_tick: + return rounded_tick_spacing + tick_spacing + elif rounded_tick_spacing > max_tick: + return rounded_tick_spacing - tick_spacing + else: + return rounded_tick_spacing \ No newline at end of file From 18d87a25a93fc657577c1dd26f174a8755947b34 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Fri, 10 May 2024 11:28:24 +0200 Subject: [PATCH 2/8] formatting --- examples/integrations/uniswap/test_funcs.py | 59 +++++++++--- .../integrations/uniswap/addresses.py | 2 +- .../integrations/uniswap/nft_manager.py | 94 ++++++++++++++----- giza_actions/integrations/uniswap/pool.py | 37 ++++++-- .../integrations/uniswap/pool_factory.py | 21 +++-- giza_actions/integrations/uniswap/quoter.py | 28 ++++-- giza_actions/integrations/uniswap/router.py | 47 +++++++--- giza_actions/integrations/uniswap/uniswap.py | 32 +++++-- giza_actions/integrations/uniswap/utils.py | 23 +++-- 9 files changed, 250 insertions(+), 93 deletions(-) diff --git a/examples/integrations/uniswap/test_funcs.py b/examples/integrations/uniswap/test_funcs.py index 55c3df7..9a28283 100644 --- a/examples/integrations/uniswap/test_funcs.py +++ b/examples/integrations/uniswap/test_funcs.py @@ -1,6 +1,8 @@ import os -from dotenv import load_dotenv, find_dotenv -from ape import networks, Contract, accounts + +from ape import Contract, accounts, networks +from dotenv import find_dotenv, load_dotenv + from giza_actions.integrations.uniswap.uniswap import Uniswap networks.parse_network_choice(f"ethereum:mainnet-fork:foundry").__enter__() @@ -28,24 +30,38 @@ amount_out = uni.quoter.quote_exact_input_single(amount_in, pool=pool) print(f"--------- Amount out: {amount_out}") # # or by specifying the tokens and the fee -amount_out = uni.quoter.quote_exact_input_single(amount_in, token_in = token1, token_out = token0, fee = fee) +amount_out = uni.quoter.quote_exact_input_single( + amount_in, token_in=token1, token_out=token0, fee=fee +) print(f"--------- Amount out: {amount_out}") ### Router ### -sender.balance += int(2e18) # funding 1 eth more than we will use for gas +sender.balance += int(2e18) # funding 1 eth more than we will use for gas token0.approve(sender, int(1e18), sender=sender) token0.deposit(value=int(1e18), sender=sender) token0_balance = token0.balanceOf(sender) print(f"--------- Balances before swap: {token0_balance} {token1.balanceOf(sender)}") token0.approve(uni.router.contract, token0_balance, sender=sender) -uni.router.swap_exact_input_single(token0_balance, token_in = token0, token_out=token1, fee=fee) -print(f"--------- Balances after exactInputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}") +uni.router.swap_exact_input_single( + token0_balance, token_in=token0, token_out=token1, fee=fee +) +print( + f"--------- Balances after exactInputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" +) token1.approve(uni.router.contract, token1.balanceOf(sender), sender=sender) -token0_amount_out = int(1e16) # 0.01 eth -accepted_slippage = 0.01 # 1% +token0_amount_out = int(1e16) # 0.01 eth +accepted_slippage = 0.01 # 1% amount_in_max = int(token1.balanceOf(sender) * (1 - accepted_slippage)) -uni.router.swap_exact_output_single(token0_amount_out, token_in = token1, token_out=token0, fee=fee, amount_in_max=amount_in_max) -print(f"--------- Balances after exactOutputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}") +uni.router.swap_exact_output_single( + token0_amount_out, + token_in=token1, + token_out=token0, + fee=fee, + amount_in_max=amount_in_max, +) +print( + f"--------- Balances after exactOutputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" +) ### NFT Manager ### token0.approve(uni.nft_manager.contract, token0.balanceOf(sender), sender=sender) @@ -58,18 +74,31 @@ pct_dev = 0.1 lower_price = int(price * (1 - pct_dev)) upper_price = int(price * (1 + pct_dev)) -uni.nft_manager.mint_position(pool, lower_price, upper_price, amount0=amount0_to_mint, amount1=amount1_to_mint, amount0_min=None, amount1_min=None, recipient=None, deadline=None, slippage_tolerance=1) +uni.nft_manager.mint_position( + pool, + lower_price, + upper_price, + amount0=amount0_to_mint, + amount1=amount1_to_mint, + amount0_min=None, + amount1_min=None, + recipient=None, + deadline=None, + slippage_tolerance=1, +) user_positions = uni.nft_manager.get_all_user_positions() print(f"--------- User Positions after minting: {user_positions}") nft_id = user_positions[0] pos_info = uni.nft_manager.get_pos_info(nft_id) print(f"--------- {nft_id} Info: {pos_info}") increase_fraction = 0.1 -amount0_desired = int(amount0_to_mint*(1+increase_fraction)) -amount1_desired = int(amount1_to_mint*(1+increase_fraction)) -uni.nft_manager.add_liquidity(nft_id, amount0_desired, amount1_desired, amount0Min=0, amount1Min=0, deadline=None) +amount0_desired = int(amount0_to_mint * (1 + increase_fraction)) +amount1_desired = int(amount1_to_mint * (1 + increase_fraction)) +uni.nft_manager.add_liquidity( + nft_id, amount0_desired, amount1_desired, amount0Min=0, amount1Min=0, deadline=None +) pos_info = uni.nft_manager.get_pos_info(nft_id) print(f"--------- {nft_id} Info Add Liq: {pos_info}") uni.nft_manager.close_position(nft_id) user_positions = uni.nft_manager.get_all_user_positions() -print(f"--------- {nft_id} Burnt, user_pos: {user_positions}") \ No newline at end of file +print(f"--------- {nft_id} Burnt, user_pos: {user_positions}") diff --git a/giza_actions/integrations/uniswap/addresses.py b/giza_actions/integrations/uniswap/addresses.py index 0dc20f8..f28be4d 100644 --- a/giza_actions/integrations/uniswap/addresses.py +++ b/giza_actions/integrations/uniswap/addresses.py @@ -36,4 +36,4 @@ }, }, # TODO: fill remaining chains: https://github.com/Uniswap/v3-periphery/blob/main/deploys.md -} \ No newline at end of file +} diff --git a/giza_actions/integrations/uniswap/nft_manager.py b/giza_actions/integrations/uniswap/nft_manager.py index aea0d7b..c6b71bb 100644 --- a/giza_actions/integrations/uniswap/nft_manager.py +++ b/giza_actions/integrations/uniswap/nft_manager.py @@ -1,12 +1,26 @@ +import os +import time + from ape import Contract -from .utils import price_to_tick, nearest_tick, calc_amount0, calc_amount1, price_to_sqrtp, liquidity0, liquidity1 + from .constants import MAX_UINT_128 -import time -import os +from .utils import ( + calc_amount0, + calc_amount1, + liquidity0, + liquidity1, + nearest_tick, + price_to_sqrtp, + price_to_tick, +) + class NFTManager: def __init__(self, address, sender): - self.contract = Contract(address, abi = os.path.join(os.path.dirname(__file__), "ASSETS/nft_manager.json")) + self.contract = Contract( + address, + abi=os.path.join(os.path.dirname(__file__), "ASSETS/nft_manager.json"), + ) self.sender = sender def get_all_user_positions(self, user_address=None): @@ -18,40 +32,75 @@ def get_all_user_positions(self, user_address=None): position = self.contract.tokenOfOwnerByIndex(user_address, n) positions.append(position) return positions - + def get_pos_info(self, nft_id): return self.contract.positions(nft_id) def close_position(self, nft_id, user_address=None): if user_address is None: user_address = self.sender - liquidity = self.get_pos_info(nft_id)['liquidity'] + liquidity = self.get_pos_info(nft_id)["liquidity"] if liquidity > 0: self.decrease_liquidity(nft_id, liquidity=liquidity) self.collect_fees(nft_id, user_address=user_address) self.contract.burn(nft_id, sender=self.sender) - def collect_fees(self, nft_id, user_address=None, amount0_max=MAX_UINT_128, amount1_max=MAX_UINT_128): + def collect_fees( + self, + nft_id, + user_address=None, + amount0_max=MAX_UINT_128, + amount1_max=MAX_UINT_128, + ): if user_address is None: user_address = self.sender - receipt = self.contract.collect((nft_id, user_address, amount0_max, amount1_max), sender=self.sender) + receipt = self.contract.collect( + (nft_id, user_address, amount0_max, amount1_max), sender=self.sender + ) return receipt - def decrease_liquidity(self, nft_id, liquidity=None, amount0Min=0, amount1Min=0, deadline=None): + def decrease_liquidity( + self, nft_id, liquidity=None, amount0Min=0, amount1Min=0, deadline=None + ): if liquidity is None: - liquidity = self.get_pos_info(nft_id)['liquidity'] + liquidity = self.get_pos_info(nft_id)["liquidity"] if deadline is None: - deadline = int(time.time() + 60) - receipt = self.contract.decreaseLiquidity((nft_id, liquidity, amount0Min, amount1Min, deadline), sender=self.sender) + deadline = int(time.time() + 60) + receipt = self.contract.decreaseLiquidity( + (nft_id, liquidity, amount0Min, amount1Min, deadline), sender=self.sender + ) return receipt - - def add_liquidity(self, nft_id, amount0Desired, amount1Desired, amount0Min=0, amount1Min=0, deadline=None): + + def add_liquidity( + self, + nft_id, + amount0Desired, + amount1Desired, + amount0Min=0, + amount1Min=0, + deadline=None, + ): if deadline is None: - deadline = int(time.time() + 60) - receipt = self.contract.increaseLiquidity((nft_id, amount0Desired, amount1Desired, amount0Min, amount1Min, deadline), sender=self.sender) + deadline = int(time.time() + 60) + receipt = self.contract.increaseLiquidity( + (nft_id, amount0Desired, amount1Desired, amount0Min, amount1Min, deadline), + sender=self.sender, + ) return receipt - def mint_position(self, pool, lower_price, upper_price, amount0, amount1, amount0_min=None, amount1_min=None, recipient=None, deadline=None, slippage_tolerance=1): + def mint_position( + self, + pool, + lower_price, + upper_price, + amount0, + amount1, + amount0_min=None, + amount1_min=None, + recipient=None, + deadline=None, + slippage_tolerance=1, + ): fee = pool.fee token0 = pool.token0 token1 = pool.token1 @@ -60,11 +109,11 @@ def mint_position(self, pool, lower_price, upper_price, amount0, amount1, amount upper_tick = price_to_tick(upper_price) lower_tick = nearest_tick(lower_tick, fee) upper_tick = nearest_tick(upper_tick, fee) - + if lower_tick > upper_tick: raise ValueError("Lower tick must be less than upper tick") - - sqrtp_cur = pool.get_pool_info()['sqrtPriceX96'] + + sqrtp_cur = pool.get_pool_info()["sqrtPriceX96"] sqrtp_low = price_to_sqrtp(lower_price) sqrtp_upp = price_to_sqrtp(upper_price) liq0 = liquidity0(amount0, sqrtp_cur, sqrtp_upp) @@ -90,10 +139,9 @@ def mint_position(self, pool, lower_price, upper_price, amount0, amount1, amount "tickUpper": upper_tick, "amount0Desired": amount0, "amount1Desired": amount1, - "amount0Min": amount0_min, - "amount1Min": amount1_min, + "amount0Min": amount0_min, + "amount1Min": amount1_min, "recipient": recipient, "deadline": deadline, } return self.contract.mint(mint_params, sender=self.sender) - diff --git a/giza_actions/integrations/uniswap/pool.py b/giza_actions/integrations/uniswap/pool.py index a74eb6a..8d3f181 100644 --- a/giza_actions/integrations/uniswap/pool.py +++ b/giza_actions/integrations/uniswap/pool.py @@ -1,23 +1,39 @@ +import os + from ape import Contract, chain + from .utils import tick_to_price -import os + class Pool: def __init__(self, address, sender, token0=None, token1=None, fee=None): - self.contract = Contract(address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/pool.json")) + self.contract = Contract( + address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/pool.json") + ) self.sender = sender - self.token0 = Contract(self.contract.token0(), abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json")) + self.token0 = Contract( + self.contract.token0(), + abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json"), + ) self.token0_decimals = self.token0.decimals() - self.token1 = Contract(self.contract.token1(), abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json")) + self.token1 = Contract( + self.contract.token1(), + abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json"), + ) self.token1_decimals = self.token1.decimals() self.fee = self.contract.fee() if fee is None else fee - def get_pool_info(self, block_number=None): if block_number is None: block_number = chain.blocks.height ( - sqrtPriceX96, tick, observationIndex, observationCardinality, observationCardinalityNext, feeProtocol, unlocked + sqrtPriceX96, + tick, + observationIndex, + observationCardinality, + observationCardinalityNext, + feeProtocol, + unlocked, ) = self.contract.slot0() return { "sqrtPriceX96": sqrtPriceX96, @@ -27,11 +43,12 @@ def get_pool_info(self, block_number=None): "observationCardinalityNext": observationCardinalityNext, "feeProtocol": feeProtocol, "unlocked": unlocked, - } + } def get_pool_price(self, block_number=None, invert=False): if block_number is None: block_number = chain.blocks.height - tick = self.get_pool_info(block_number)['tick'] - return tick_to_price(tick, self.token0_decimals, self.token1_decimals, invert=invert) - + tick = self.get_pool_info(block_number)["tick"] + return tick_to_price( + tick, self.token0_decimals, self.token1_decimals, invert=invert + ) diff --git a/giza_actions/integrations/uniswap/pool_factory.py b/giza_actions/integrations/uniswap/pool_factory.py index 009a355..b5836f0 100644 --- a/giza_actions/integrations/uniswap/pool_factory.py +++ b/giza_actions/integrations/uniswap/pool_factory.py @@ -1,20 +1,25 @@ +import os + from ape import Contract + from .pool import Pool -import os + class PoolFactory: def __init__(self, address, sender): - self.contract = Contract(address, abi = os.path.join(os.path.dirname(__file__), "ASSETS/pool_factory.json")) + self.contract = Contract( + address, + abi=os.path.join(os.path.dirname(__file__), "ASSETS/pool_factory.json"), + ) self.sender = sender def get_pool(self, token0, token1, fee): - if type(fee)==float: - fee = int(fee*1e6) + if type(fee) == float: + fee = int(fee * 1e6) pool_address = self.contract.getPool(token0, token1, fee) return Pool(pool_address, self.sender, token0=token0, token1=token1, fee=fee) - def create_pool(self, token0, token1, fee): - if type(fee)==float: - fee = int(fee*1e6) - return self.contract.createPool(token0, token1, fee, sender=self.sender) \ No newline at end of file + if type(fee) == float: + fee = int(fee * 1e6) + return self.contract.createPool(token0, token1, fee, sender=self.sender) diff --git a/giza_actions/integrations/uniswap/quoter.py b/giza_actions/integrations/uniswap/quoter.py index 7a2431d..10177ad 100644 --- a/giza_actions/integrations/uniswap/quoter.py +++ b/giza_actions/integrations/uniswap/quoter.py @@ -1,20 +1,32 @@ -from ape import Contract import os +from ape import Contract + + class Quoter: def __init__(self, address, sender): - self.contract = Contract(address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/quoter.json")) + self.contract = Contract( + address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/quoter.json") + ) self.sender = sender - def quote_exact_input_single(self, amount_in, pool=None, token_in=None, token_out=None, fee=None, sqrt_price_limit_x96=0): + def quote_exact_input_single( + self, + amount_in, + pool=None, + token_in=None, + token_out=None, + fee=None, + sqrt_price_limit_x96=0, + ): if pool is None and (token_in is None or token_out is None or fee is None): raise Exception("Must provide pool or token_in, token_out, and fee") - - if (token_in is None or token_out is None or fee is None): + + if token_in is None or token_out is None or fee is None: token_in = pool.token0 if token_in is None else token_in token_out = pool.token1 if token_out is None else token_out fee = pool.fee if fee is None else fee - return self.contract.quoteExactInputSingle.call(token_in, token_out, fee, amount_in, sqrt_price_limit_x96) - - + return self.contract.quoteExactInputSingle.call( + token_in, token_out, fee, amount_in, sqrt_price_limit_x96 + ) diff --git a/giza_actions/integrations/uniswap/router.py b/giza_actions/integrations/uniswap/router.py index 9eb7630..a160b31 100644 --- a/giza_actions/integrations/uniswap/router.py +++ b/giza_actions/integrations/uniswap/router.py @@ -1,27 +1,40 @@ -from ape import Contract import os import time +from ape import Contract + class Router: def __init__(self, address, sender): - self.contract = Contract(address, abi = os.path.join(os.path.dirname(__file__), "ASSETS/router.json")) + self.contract = Contract( + address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/router.json") + ) self.sender = sender - def swap_exact_input_single(self, amount_in, pool=None, token_in=None, token_out=None, fee=None, amount_out_min=0, sqrt_price_limit_x96=0, deadline=None): + def swap_exact_input_single( + self, + amount_in, + pool=None, + token_in=None, + token_out=None, + fee=None, + amount_out_min=0, + sqrt_price_limit_x96=0, + deadline=None, + ): if deadline is None: deadline = int(time.time()) + 60 if pool is None and (token_in is None or token_out is None or fee is None): raise Exception("Must provide pool or token_in, token_out, and fee") - - if (token_in is None or token_out is None or fee is None): + + if token_in is None or token_out is None or fee is None: token_in = pool.token0 if token_in is None else token_in token_out = pool.token1 if token_out is None else token_out fee = pool.fee if fee is None else fee # TODO: - # add slippage and pool price impact protection + # add slippage and pool price impact protection # if amount_out_min or sqrt_price_limit_x96 are floats swap_params = { @@ -35,21 +48,31 @@ def swap_exact_input_single(self, amount_in, pool=None, token_in=None, token_out } return self.contract.exactInputSingle(swap_params, sender=self.sender) - - def swap_exact_output_single(self, amount_out, pool=None, token_in=None, token_out=None, fee=None, amount_in_max=0, sqrt_price_limit_x96=0, deadline=None): + + def swap_exact_output_single( + self, + amount_out, + pool=None, + token_in=None, + token_out=None, + fee=None, + amount_in_max=0, + sqrt_price_limit_x96=0, + deadline=None, + ): if deadline is None: deadline = int(time.time()) + 60 if pool is None and (token_in is None or token_out is None or fee is None): raise Exception("Must provide pool or token_in, token_out, and fee") - - if (token_in is None or token_out is None or fee is None): + + if token_in is None or token_out is None or fee is None: token_in = pool.token0 if token_in is None else token_in token_out = pool.token1 if token_out is None else token_out fee = pool.fee if fee is None else fee # TODO: - # add slippage and pool price impact protection + # add slippage and pool price impact protection # if amount_out_min or sqrt_price_limit_x96 are floats swap_params = { @@ -63,4 +86,4 @@ def swap_exact_output_single(self, amount_out, pool=None, token_in=None, token_o "sqrtPriceLimitX96": sqrt_price_limit_x96, } - return self.contract.exactOutputSingle(swap_params, sender=self.sender) \ No newline at end of file + return self.contract.exactOutputSingle(swap_params, sender=self.sender) diff --git a/giza_actions/integrations/uniswap/uniswap.py b/giza_actions/integrations/uniswap/uniswap.py index 3facacf..652920e 100644 --- a/giza_actions/integrations/uniswap/uniswap.py +++ b/giza_actions/integrations/uniswap/uniswap.py @@ -1,9 +1,11 @@ from ape import chain + from .addresses import ADDRESSES +from .nft_manager import NFTManager from .pool_factory import PoolFactory -from .router import Router from .quoter import Quoter -from .nft_manager import NFTManager +from .router import Router + class Uniswap: def __init__(self, sender, version=3): @@ -17,13 +19,25 @@ def _load_contracts(self): # TODO pass elif self.version == 3: - self.pool_factory = PoolFactory(ADDRESSES[self._chain_id][self.version]["PoolFactory"], sender=self.sender) - self.router = Router(ADDRESSES[self._chain_id][self.version]["Router"], sender=self.sender) - self.quoter = Quoter(ADDRESSES[self._chain_id][self.version]["Quoter"], sender=self.sender) - self.nft_manager = NFTManager(ADDRESSES[self._chain_id][self.version]["NonfungiblePositionManager"], sender=self.sender) + self.pool_factory = PoolFactory( + ADDRESSES[self._chain_id][self.version]["PoolFactory"], + sender=self.sender, + ) + self.router = Router( + ADDRESSES[self._chain_id][self.version]["Router"], sender=self.sender + ) + self.quoter = Quoter( + ADDRESSES[self._chain_id][self.version]["Quoter"], sender=self.sender + ) + self.nft_manager = NFTManager( + ADDRESSES[self._chain_id][self.version]["NonfungiblePositionManager"], + sender=self.sender, + ) else: - raise NotImplementedError("Uniswap version {} not supported".format(self.version)) - + raise NotImplementedError( + "Uniswap version {} not supported".format(self.version) + ) + def print_addresses(self): print(f"PoolFactory: {self.pool_factory.contract.address}") print(f"Router: {self.router.contract.address}") @@ -32,5 +46,3 @@ def print_addresses(self): def get_pool(self, token0, token1, fee): return self.pool_factory.get_pool(token0, token1, fee) - - diff --git a/giza_actions/integrations/uniswap/utils.py b/giza_actions/integrations/uniswap/utils.py index 174f61c..017f697 100644 --- a/giza_actions/integrations/uniswap/utils.py +++ b/giza_actions/integrations/uniswap/utils.py @@ -1,20 +1,26 @@ -from ape import Contract +import json import math -from .constants import TICKS_Q, Q96, MIN_TICK, MAX_TICK, _tick_spacing -import json + +from ape import Contract + +from .constants import MAX_TICK, MIN_TICK, Q96, TICKS_Q, _tick_spacing + def load_json(path): with open(path) as f: return json.load(f) - + + def load_contract(address): return Contract(address) + def price_to_tick(price): sqrtPriceX96 = int(price * 2**96) tick = math.floor(math.log((sqrtPriceX96 / Q96) ** 2) / math.log(TICKS_Q)) return tick + def price_to_sqrtp(p): return int(math.sqrt(p) * Q96) @@ -24,7 +30,8 @@ def tick_to_price(tick, decimals0, decimals1, invert=False): return 1 / (TICKS_Q**tick / 10 ** (decimals1 - decimals0)) else: return TICKS_Q**tick / 10 ** (decimals1 - decimals0) - + + def get_min_tick(fee): min_tick_spacing = _tick_spacing[fee] return -(MIN_TICK // -min_tick_spacing) * min_tick_spacing @@ -40,6 +47,7 @@ def default_tick_range(fee): max_tick = get_max_tick(fee) return min_tick, max_tick + # https://uniswapv3book.com/milestone_1/calculating-liquidity.html def calc_amount0(liq, pa, pb): if pa > pb: @@ -52,16 +60,19 @@ def calc_amount1(liq, pa, pb): pa, pb = pb, pa return int(liq * (pb - pa) / Q96) + def liquidity0(amount, pa, pb): if pa > pb: pa, pb = pb, pa return (amount * (pa * pb) / Q96) / (pb - pa) + def liquidity1(amount, pa, pb): if pa > pb: pa, pb = pb, pa return amount * Q96 / (pb - pa) + def nearest_tick(tick, fee): min_tick, max_tick = default_tick_range(fee) assert ( @@ -74,4 +85,4 @@ def nearest_tick(tick, fee): elif rounded_tick_spacing > max_tick: return rounded_tick_spacing - tick_spacing else: - return rounded_tick_spacing \ No newline at end of file + return rounded_tick_spacing From f5c027e986f21a656e2fa465f7c89af980502f46 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Mon, 13 May 2024 12:49:21 +0200 Subject: [PATCH 3/8] moved addresses to constants.py, refactored for Uniswap class to be a frontend for all contract interactions, added type hints --- examples/integrations/uniswap/test_funcs.py | 183 +++++++++--------- .../integrations/uniswap/addresses.py | 39 ---- .../integrations/uniswap/constants.py | 41 ++++ .../integrations/uniswap/nft_manager.py | 74 +++---- giza_actions/integrations/uniswap/pool.py | 23 ++- .../integrations/uniswap/pool_factory.py | 10 +- giza_actions/integrations/uniswap/quoter.py | 34 ++-- giza_actions/integrations/uniswap/router.py | 38 ++-- giza_actions/integrations/uniswap/uniswap.py | 176 +++++++++++++++-- giza_actions/integrations/uniswap/utils.py | 13 +- 10 files changed, 405 insertions(+), 226 deletions(-) delete mode 100644 giza_actions/integrations/uniswap/addresses.py diff --git a/examples/integrations/uniswap/test_funcs.py b/examples/integrations/uniswap/test_funcs.py index 9a28283..7906a94 100644 --- a/examples/integrations/uniswap/test_funcs.py +++ b/examples/integrations/uniswap/test_funcs.py @@ -2,103 +2,106 @@ from ape import Contract, accounts, networks from dotenv import find_dotenv, load_dotenv +import logging from giza_actions.integrations.uniswap.uniswap import Uniswap -networks.parse_network_choice(f"ethereum:mainnet-fork:foundry").__enter__() load_dotenv(find_dotenv()) - dev_passphrase = os.environ.get("DEV_PASSPHRASE") -sender = accounts.load("dev") -sender.set_autosign(True, passphrase=dev_passphrase) -weth_address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" -usdc_address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" -token0 = Contract(weth_address) -token1 = Contract(usdc_address) -fee = 500 +logger = logging.getLogger(__name__) + +with networks.parse_network_choice(f"ethereum:mainnet-fork:foundry"): + sender = accounts.load("dev") + sender.set_autosign(True, passphrase=dev_passphrase) + + weth_address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" + usdc_address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" + token0 = Contract(weth_address) + token1 = Contract(usdc_address) + fee = 500 -### Uniswap ### -uni = Uniswap(sender=sender, version=3) -pool = uni.get_pool(token0, token1, fee) -price = pool.get_pool_price(invert=True) -print(f"--------- Pool Price: {price}") + ### Uniswap ### + uni = Uniswap(sender=sender, version=3) + pool = uni.get_pool(token0, token1, fee) + price = pool.get_pool_price(invert=True) + logger.info(f"--------- Pool Price: {price}") -### Quoter ### -amount_in = int(1e8) -# calling using pool object -amount_out = uni.quoter.quote_exact_input_single(amount_in, pool=pool) -print(f"--------- Amount out: {amount_out}") -# # or by specifying the tokens and the fee -amount_out = uni.quoter.quote_exact_input_single( - amount_in, token_in=token1, token_out=token0, fee=fee -) -print(f"--------- Amount out: {amount_out}") + ### Quoter ### + amount_in = int(1e8) + # calling using pool object + amount_out = uni.quote_exact_input_single(amount_in, pool=pool) + logger.info(f"--------- Amount out: {amount_out}") + # # or by specifying the tokens and the fee + amount_out = uni.quote_exact_input_single( + amount_in, token_in=token1, token_out=token0, fee=fee + ) + logger.info(f"--------- Amount out: {amount_out}") -### Router ### -sender.balance += int(2e18) # funding 1 eth more than we will use for gas -token0.approve(sender, int(1e18), sender=sender) -token0.deposit(value=int(1e18), sender=sender) -token0_balance = token0.balanceOf(sender) -print(f"--------- Balances before swap: {token0_balance} {token1.balanceOf(sender)}") -token0.approve(uni.router.contract, token0_balance, sender=sender) -uni.router.swap_exact_input_single( - token0_balance, token_in=token0, token_out=token1, fee=fee -) -print( - f"--------- Balances after exactInputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" -) -token1.approve(uni.router.contract, token1.balanceOf(sender), sender=sender) -token0_amount_out = int(1e16) # 0.01 eth -accepted_slippage = 0.01 # 1% -amount_in_max = int(token1.balanceOf(sender) * (1 - accepted_slippage)) -uni.router.swap_exact_output_single( - token0_amount_out, - token_in=token1, - token_out=token0, - fee=fee, - amount_in_max=amount_in_max, -) -print( - f"--------- Balances after exactOutputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" -) + ### Router ### + sender.balance += int(2e18) # funding 1 eth more than we will use for gas + token0.approve(sender, int(1e18), sender=sender) + token0.deposit(value=int(1e18), sender=sender) + token0_balance = token0.balanceOf(sender) + logger.info(f"--------- Balances before swap: {token0_balance} {token1.balanceOf(sender)}") + token0.approve(uni.router.contract, token0_balance, sender=sender) + uni.swap_exact_input_single( + token0_balance, token_in=token0, token_out=token1, fee=fee + ) + logger.info( + f"--------- Balances after exactInputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" + ) + token1.approve(uni.router.contract, token1.balanceOf(sender), sender=sender) + token0_amount_out = int(1e16) # 0.01 eth + accepted_slippage = 0.01 # 1% + amount_in_max = int(token1.balanceOf(sender) * (1 - accepted_slippage)) + uni.swap_exact_output_single( + token0_amount_out, + token_in=token1, + token_out=token0, + fee=fee, + amount_in_max=amount_in_max, + ) + logger.info( + f"--------- Balances after exactOutputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" + ) -### NFT Manager ### -token0.approve(uni.nft_manager.contract, token0.balanceOf(sender), sender=sender) -token1.approve(uni.nft_manager.contract, token1.balanceOf(sender), sender=sender) -user_positions = uni.nft_manager.get_all_user_positions() -print(f"--------- User Positions Init: {user_positions}") -amount0_to_mint = int(0.5 * token0.balanceOf(sender)) -amount1_to_mint = int(0.5 * token1.balanceOf(sender)) -price = pool.get_pool_price(invert=True) -pct_dev = 0.1 -lower_price = int(price * (1 - pct_dev)) -upper_price = int(price * (1 + pct_dev)) -uni.nft_manager.mint_position( - pool, - lower_price, - upper_price, - amount0=amount0_to_mint, - amount1=amount1_to_mint, - amount0_min=None, - amount1_min=None, - recipient=None, - deadline=None, - slippage_tolerance=1, -) -user_positions = uni.nft_manager.get_all_user_positions() -print(f"--------- User Positions after minting: {user_positions}") -nft_id = user_positions[0] -pos_info = uni.nft_manager.get_pos_info(nft_id) -print(f"--------- {nft_id} Info: {pos_info}") -increase_fraction = 0.1 -amount0_desired = int(amount0_to_mint * (1 + increase_fraction)) -amount1_desired = int(amount1_to_mint * (1 + increase_fraction)) -uni.nft_manager.add_liquidity( - nft_id, amount0_desired, amount1_desired, amount0Min=0, amount1Min=0, deadline=None -) -pos_info = uni.nft_manager.get_pos_info(nft_id) -print(f"--------- {nft_id} Info Add Liq: {pos_info}") -uni.nft_manager.close_position(nft_id) -user_positions = uni.nft_manager.get_all_user_positions() -print(f"--------- {nft_id} Burnt, user_pos: {user_positions}") + ### NFT Manager ### + token0.approve(uni.nft_manager.contract, token0.balanceOf(sender), sender=sender) + token1.approve(uni.nft_manager.contract, token1.balanceOf(sender), sender=sender) + user_positions = uni.get_all_user_positions() + logger.info(f"--------- User Positions Init: {user_positions}") + amount0_to_mint = int(0.5 * token0.balanceOf(sender)) + amount1_to_mint = int(0.5 * token1.balanceOf(sender)) + price = pool.get_pool_price(invert=True) + pct_dev = 0.1 + lower_price = int(price * (1 - pct_dev)) + upper_price = int(price * (1 + pct_dev)) + uni.mint_position( + pool, + lower_price, + upper_price, + amount0=amount0_to_mint, + amount1=amount1_to_mint, + amount0Min=None, + amount1Min=None, + recipient=None, + deadline=None, + slippage_tolerance=1, + ) + user_positions = uni.get_all_user_positions() + logger.info(f"--------- User Positions after minting: {user_positions}") + nft_id = user_positions[0] + pos_info = uni.get_pos_info(nft_id) + logger.info(f"--------- {nft_id} Info: {pos_info}") + increase_fraction = 0.1 + amount0_desired = int(amount0_to_mint * (1 + increase_fraction)) + amount1_desired = int(amount1_to_mint * (1 + increase_fraction)) + uni.add_liquidity( + nft_id, amount0_desired, amount1_desired, amount0Min=0, amount1Min=0, deadline=None + ) + pos_info = uni.get_pos_info(nft_id) + logger.info(f"--------- {nft_id} Info Add Liq: {pos_info}") + uni.close_position(nft_id) + user_positions = uni.get_all_user_positions() + logger.info(f"--------- {nft_id} Burnt, user_pos: {user_positions}") diff --git a/giza_actions/integrations/uniswap/addresses.py b/giza_actions/integrations/uniswap/addresses.py deleted file mode 100644 index f28be4d..0000000 --- a/giza_actions/integrations/uniswap/addresses.py +++ /dev/null @@ -1,39 +0,0 @@ -ADDRESSES = { - # mainnet - 1: { - 3: { - "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", - "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", - "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", - "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", - }, - }, - # sepolia - 11155111: { - 3: { - "PoolFactory": "0x0227628f3F023bb0B980b67D528571c95c6DaC1c", - "NonfungiblePositionManager": "0x1238536071E1c677A632429e3655c799b22cDA52", - "Router": "0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E", - "Quoter": "0xEd1f6473345F45b75F8179591dd5bA1888cf2FB3", - }, - }, - # goerli - 5: { - 3: { - "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", - "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", - "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", - "Quoter": "", - }, - }, - # arbitrum - 42161: { - 3: { - "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", - "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", - "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", - "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", - }, - }, - # TODO: fill remaining chains: https://github.com/Uniswap/v3-periphery/blob/main/deploys.md -} diff --git a/giza_actions/integrations/uniswap/constants.py b/giza_actions/integrations/uniswap/constants.py index dbf26f6..696a020 100644 --- a/giza_actions/integrations/uniswap/constants.py +++ b/giza_actions/integrations/uniswap/constants.py @@ -4,3 +4,44 @@ Q96 = 2**96 MAX_UINT_128 = 2 ** (128) - 1 _tick_spacing = {100: 1, 500: 10, 3_000: 60, 10_000: 200} + + +ADDRESSES = { + # mainnet + 1: { + 3: { + "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", + "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", + "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", + "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", + }, + }, + # sepolia + 11155111: { + 3: { + "PoolFactory": "0x0227628f3F023bb0B980b67D528571c95c6DaC1c", + "NonfungiblePositionManager": "0x1238536071E1c677A632429e3655c799b22cDA52", + "Router": "0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E", + "Quoter": "0xEd1f6473345F45b75F8179591dd5bA1888cf2FB3", + }, + }, + # goerli + 5: { + 3: { + "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", + "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", + "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", + "Quoter": "", + }, + }, + # arbitrum + 42161: { + 3: { + "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", + "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", + "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", + "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", + }, + }, + # TODO: fill remaining chains: https://github.com/Uniswap/v3-periphery/blob/main/deploys.md +} diff --git a/giza_actions/integrations/uniswap/nft_manager.py b/giza_actions/integrations/uniswap/nft_manager.py index c6b71bb..7b42e27 100644 --- a/giza_actions/integrations/uniswap/nft_manager.py +++ b/giza_actions/integrations/uniswap/nft_manager.py @@ -3,8 +3,8 @@ from ape import Contract -from .constants import MAX_UINT_128 -from .utils import ( +from giza_actions.integrations.uniswap.constants import MAX_UINT_128 +from giza_actions.integrations.uniswap.utils import ( calc_amount0, calc_amount1, liquidity0, @@ -16,14 +16,14 @@ class NFTManager: - def __init__(self, address, sender): + def __init__(self, address: str, sender: str): self.contract = Contract( address, - abi=os.path.join(os.path.dirname(__file__), "ASSETS/nft_manager.json"), + abi=os.path.join(os.path.dirname(__file__), "assets/nft_manager.json"), ) self.sender = sender - def get_all_user_positions(self, user_address=None): + def get_all_user_positions(self, user_address: str = None): if user_address is None: user_address = self.sender n_positions = self.contract.balanceOf(user_address) @@ -33,13 +33,10 @@ def get_all_user_positions(self, user_address=None): positions.append(position) return positions - def get_pos_info(self, nft_id): - return self.contract.positions(nft_id) - - def close_position(self, nft_id, user_address=None): + def close_position(self, nft_id: int, user_address: str = None): if user_address is None: user_address = self.sender - liquidity = self.get_pos_info(nft_id)["liquidity"] + liquidity = self.contract.positions(nft_id)["liquidity"] if liquidity > 0: self.decrease_liquidity(nft_id, liquidity=liquidity) self.collect_fees(nft_id, user_address=user_address) @@ -47,10 +44,10 @@ def close_position(self, nft_id, user_address=None): def collect_fees( self, - nft_id, - user_address=None, - amount0_max=MAX_UINT_128, - amount1_max=MAX_UINT_128, + nft_id: int, + user_address: str = None, + amount0_max: int = MAX_UINT_128, + amount1_max: int = MAX_UINT_128, ): if user_address is None: user_address = self.sender @@ -60,7 +57,12 @@ def collect_fees( return receipt def decrease_liquidity( - self, nft_id, liquidity=None, amount0Min=0, amount1Min=0, deadline=None + self, + nft_id: int, + liquidity: int = None, + amount0Min: int = 0, + amount1Min: int = 0, + deadline: int = None, ): if liquidity is None: liquidity = self.get_pos_info(nft_id)["liquidity"] @@ -73,12 +75,12 @@ def decrease_liquidity( def add_liquidity( self, - nft_id, - amount0Desired, - amount1Desired, - amount0Min=0, - amount1Min=0, - deadline=None, + nft_id: int, + amount0Desired: int, + amount1Desired: int, + amount0Min: int = 0, + amount1Min: int = 0, + deadline: int = None, ): if deadline is None: deadline = int(time.time() + 60) @@ -91,15 +93,15 @@ def add_liquidity( def mint_position( self, pool, - lower_price, - upper_price, - amount0, - amount1, - amount0_min=None, - amount1_min=None, - recipient=None, - deadline=None, - slippage_tolerance=1, + lower_price: float, + upper_price: float, + amount0: int, + amount1: int, + amount0Min: int = None, + amount1Min: int = None, + recipient: str = None, + deadline: int = None, + slippage_tolerance: float = 1, ): fee = pool.fee token0 = pool.token0 @@ -126,10 +128,10 @@ def mint_position( recipient = self.sender if deadline is None: deadline = int(time.time() + 60) - if amount0_min is None: - amount0_min = int(amount0 * (1 - slippage_tolerance)) - if amount1_min is None: - amount1_min = int(amount1 * (1 - slippage_tolerance)) + if amount0Min is None: + amount0Min = int(amount0 * (1 - slippage_tolerance)) + if amount1Min is None: + amount1Min = int(amount1 * (1 - slippage_tolerance)) mint_params = { "token0": token0.address, @@ -139,8 +141,8 @@ def mint_position( "tickUpper": upper_tick, "amount0Desired": amount0, "amount1Desired": amount1, - "amount0Min": amount0_min, - "amount1Min": amount1_min, + "amount0Min": amount0Min, + "amount1Min": amount1Min, "recipient": recipient, "deadline": deadline, } diff --git a/giza_actions/integrations/uniswap/pool.py b/giza_actions/integrations/uniswap/pool.py index 8d3f181..1b24dc9 100644 --- a/giza_actions/integrations/uniswap/pool.py +++ b/giza_actions/integrations/uniswap/pool.py @@ -2,28 +2,35 @@ from ape import Contract, chain -from .utils import tick_to_price +from giza_actions.integrations.uniswap.utils import tick_to_price class Pool: - def __init__(self, address, sender, token0=None, token1=None, fee=None): + def __init__( + self, + address: str, + sender: str, + token0: str = None, + token1: str = None, + fee: int = None, + ): self.contract = Contract( - address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/pool.json") + address, abi=os.path.join(os.path.dirname(__file__), "assets/pool.json") ) self.sender = sender self.token0 = Contract( self.contract.token0(), - abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json"), + abi=os.path.join(os.path.dirname(__file__), "assets/erc20.json"), ) self.token0_decimals = self.token0.decimals() self.token1 = Contract( self.contract.token1(), - abi=os.path.join(os.path.dirname(__file__), "ASSETS/erc20.json"), + abi=os.path.join(os.path.dirname(__file__), "assets/erc20.json"), ) self.token1_decimals = self.token1.decimals() self.fee = self.contract.fee() if fee is None else fee - def get_pool_info(self, block_number=None): + def get_pool_info(self, block_number: int = None): if block_number is None: block_number = chain.blocks.height ( @@ -34,7 +41,7 @@ def get_pool_info(self, block_number=None): observationCardinalityNext, feeProtocol, unlocked, - ) = self.contract.slot0() + ) = self.contract.slot0(block_identifier=block_number) return { "sqrtPriceX96": sqrtPriceX96, "tick": tick, @@ -45,7 +52,7 @@ def get_pool_info(self, block_number=None): "unlocked": unlocked, } - def get_pool_price(self, block_number=None, invert=False): + def get_pool_price(self, block_number: int = None, invert: bool = False): if block_number is None: block_number = chain.blocks.height tick = self.get_pool_info(block_number)["tick"] diff --git a/giza_actions/integrations/uniswap/pool_factory.py b/giza_actions/integrations/uniswap/pool_factory.py index b5836f0..ed171e2 100644 --- a/giza_actions/integrations/uniswap/pool_factory.py +++ b/giza_actions/integrations/uniswap/pool_factory.py @@ -2,24 +2,24 @@ from ape import Contract -from .pool import Pool +from giza_actions.integrations.uniswap.pool import Pool class PoolFactory: - def __init__(self, address, sender): + def __init__(self, address: str, sender: str): self.contract = Contract( address, - abi=os.path.join(os.path.dirname(__file__), "ASSETS/pool_factory.json"), + abi=os.path.join(os.path.dirname(__file__), "assets/pool_factory.json"), ) self.sender = sender - def get_pool(self, token0, token1, fee): + def get_pool(self, token0: str, token1: str, fee: int): if type(fee) == float: fee = int(fee * 1e6) pool_address = self.contract.getPool(token0, token1, fee) return Pool(pool_address, self.sender, token0=token0, token1=token1, fee=fee) - def create_pool(self, token0, token1, fee): + def create_pool(self, token0: str, token1: str, fee: int): if type(fee) == float: fee = int(fee * 1e6) return self.contract.createPool(token0, token1, fee, sender=self.sender) diff --git a/giza_actions/integrations/uniswap/quoter.py b/giza_actions/integrations/uniswap/quoter.py index 10177ad..20e8c60 100644 --- a/giza_actions/integrations/uniswap/quoter.py +++ b/giza_actions/integrations/uniswap/quoter.py @@ -1,23 +1,25 @@ import os from ape import Contract +from ape.contracts import ContractInstance class Quoter: - def __init__(self, address, sender): + def __init__(self, address: str, sender: str): self.contract = Contract( - address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/quoter.json") + address, abi=os.path.join(os.path.dirname(__file__), "assets/quoter.json") ) self.sender = sender def quote_exact_input_single( self, - amount_in, - pool=None, - token_in=None, - token_out=None, - fee=None, - sqrt_price_limit_x96=0, + amount_in: int, + pool: ContractInstance = None, + token_in: str = None, + token_out: str = None, + fee: int = None, + sqrt_price_limit_x96: int = 0, + block_number: int = None, ): if pool is None and (token_in is None or token_out is None or fee is None): raise Exception("Must provide pool or token_in, token_out, and fee") @@ -27,6 +29,16 @@ def quote_exact_input_single( token_out = pool.token1 if token_out is None else token_out fee = pool.fee if fee is None else fee - return self.contract.quoteExactInputSingle.call( - token_in, token_out, fee, amount_in, sqrt_price_limit_x96 - ) + if block_number is None: + return self.contract.quoteExactInputSingle.call( + token_in, token_out, fee, amount_in, sqrt_price_limit_x96 + ) + else: + return self.contract.quoteExactInputSingle.call( + token_in, + token_out, + fee, + amount_in, + sqrt_price_limit_x96, + block_identifier=block_number, + ) diff --git a/giza_actions/integrations/uniswap/router.py b/giza_actions/integrations/uniswap/router.py index a160b31..9129cac 100644 --- a/giza_actions/integrations/uniswap/router.py +++ b/giza_actions/integrations/uniswap/router.py @@ -3,24 +3,26 @@ from ape import Contract +from giza_actions.integrations.uniswap.pool import Pool + class Router: - def __init__(self, address, sender): + def __init__(self, address: str, sender: str): self.contract = Contract( - address, abi=os.path.join(os.path.dirname(__file__), "ASSETS/router.json") + address, abi=os.path.join(os.path.dirname(__file__), "assets/router.json") ) self.sender = sender def swap_exact_input_single( self, - amount_in, - pool=None, - token_in=None, - token_out=None, - fee=None, - amount_out_min=0, - sqrt_price_limit_x96=0, - deadline=None, + amount_in: int, + pool: Pool = None, + token_in: str = None, + token_out: str = None, + fee: int = None, + amount_out_min: int = 0, + sqrt_price_limit_x96: int = 0, + deadline: int = None, ): if deadline is None: deadline = int(time.time()) + 60 @@ -51,14 +53,14 @@ def swap_exact_input_single( def swap_exact_output_single( self, - amount_out, - pool=None, - token_in=None, - token_out=None, - fee=None, - amount_in_max=0, - sqrt_price_limit_x96=0, - deadline=None, + amount_out: int, + pool: Pool = None, + token_in: str = None, + token_out: str = None, + fee: int = None, + amount_in_max: int = 0, + sqrt_price_limit_x96: int = 0, + deadline: int = None, ): if deadline is None: deadline = int(time.time()) + 60 diff --git a/giza_actions/integrations/uniswap/uniswap.py b/giza_actions/integrations/uniswap/uniswap.py index 652920e..45d10cf 100644 --- a/giza_actions/integrations/uniswap/uniswap.py +++ b/giza_actions/integrations/uniswap/uniswap.py @@ -1,14 +1,15 @@ from ape import chain -from .addresses import ADDRESSES -from .nft_manager import NFTManager -from .pool_factory import PoolFactory -from .quoter import Quoter -from .router import Router +from giza_actions.integrations.uniswap.constants import ADDRESSES, MAX_UINT_128 +from giza_actions.integrations.uniswap.nft_manager import NFTManager +from giza_actions.integrations.uniswap.pool import Pool +from giza_actions.integrations.uniswap.pool_factory import PoolFactory +from giza_actions.integrations.uniswap.quoter import Quoter +from giza_actions.integrations.uniswap.router import Router class Uniswap: - def __init__(self, sender, version=3): + def __init__(self, sender: str, version: int = 3): self.sender = sender self._chain_id = chain.chain_id self.version = version @@ -38,11 +39,160 @@ def _load_contracts(self): "Uniswap version {} not supported".format(self.version) ) - def print_addresses(self): - print(f"PoolFactory: {self.pool_factory.contract.address}") - print(f"Router: {self.router.contract.address}") - print(f"Quoter: {self.quoter.contract.address}") - print(f"NFT Manager: {self.nft_manager.contract.address}") - - def get_pool(self, token0, token1, fee): + def get_pool(self, token0: str, token1: str, fee: int): return self.pool_factory.get_pool(token0, token1, fee) + + def create_pool(self, token0: str, token1: str, fee: int): + return self.pool_factory.create_pool(token0, token1, fee) + + def get_all_user_positions(self, user_address: str = None): + return self.nft_manager.get_all_user_positions(user_address=user_address) + + def get_pos_info(self, nft_id: int, block_number: str = None): + if block_number is None: + return self.nft_manager.contract.positions(nft_id) + else: + return self.nft_manager.contract.positions( + nft_id, block_identifier=block_number + ) + + def close_position(self, nft_id: int, user_address: str = None): + return self.nft_manager.close_position(nft_id, user_address=user_address) + + def collect_fees( + self, + nft_id: int, + user_address: str = None, + amount0_max: int = MAX_UINT_128, + amount1_max: int = MAX_UINT_128, + ): + return self.nft_manager.collect_fees( + nft_id, + user_address=user_address, + amount0_max=amount0_max, + amount1_max=amount1_max, + ) + + def decrease_liquidity( + self, + nft_id: int, + liquidity: int = None, + amount0Min: int = 0, + amount1Min: int = 0, + deadline: int = None, + ): + return self.nft_manager.decrease_liquidity( + nft_id, + liquidity=liquidity, + amount0Min=amount0Min, + amount1Min=amount1Min, + deadline=deadline, + ) + + def add_liquidity( + self, + nft_id: int, + amount0_desired: int, + amount1_desired: int, + amount0Min: int = 0, + amount1Min: int = 0, + deadline: int = None, + ): + return self.nft_manager.add_liquidity( + nft_id, + amount0_desired, + amount1_desired, + amount0Min=amount0Min, + amount1Min=amount1Min, + deadline=deadline, + ) + + def mint_position( + self, + pool: Pool, + lower_price: float, + upper_price: float, + amount0: int, + amount1: int, + amount0Min: int = None, + amount1Min: int = None, + recipient: str = None, + deadline: int = None, + slippage_tolerance: float = 1, + ): + self.nft_manager.mint_position( + pool, + lower_price=lower_price, + upper_price=upper_price, + amount0=amount0, + amount1=amount1, + amount0Min=amount0Min, + amount1Min=amount1Min, + recipient=recipient, + deadline=deadline, + slippage_tolerance=slippage_tolerance, + ) + + def quote_exact_input_single( + self, + amount_in: int, + pool: Pool = None, + token_in: str = None, + token_out: str = None, + fee: int = None, + sqrt_price_limit_x96: int = 0, + block_number: int = None, + ): + return self.quoter.quote_exact_input_single( + amount_in, + pool=pool, + token_in=token_in, + token_out=token_out, + fee=fee, + sqrt_price_limit_x96=sqrt_price_limit_x96, + block_number=block_number, + ) + + def swap_exact_input_single( + self, + amount_in: int, + pool: Pool = None, + token_in: str = None, + token_out: str = None, + fee: int = None, + amount_out_min: int = 0, + sqrt_price_limit_x96: int = 0, + deadline: int = None, + ): + return self.router.swap_exact_input_single( + amount_in=amount_in, + pool=pool, + token_in=token_in, + token_out=token_out, + fee=fee, + amount_out_min=amount_out_min, + sqrt_price_limit_x96=sqrt_price_limit_x96, + deadline=deadline, + ) + + def swap_exact_output_single( + self, + amount_out: int, + pool: Pool = None, + token_in: str = None, + token_out: str = None, + fee: int = None, + amount_in_max: int = 0, + sqrt_price_limit_x96: int = 0, + deadline: int = None, + ): + return self.router.swap_exact_output_single( + amount_out=amount_out, + pool=pool, + token_in=token_in, + token_out=token_out, + fee=fee, + amount_in_max=amount_in_max, + sqrt_price_limit_x96=sqrt_price_limit_x96, + deadline=deadline, + ) diff --git a/giza_actions/integrations/uniswap/utils.py b/giza_actions/integrations/uniswap/utils.py index 017f697..50bf254 100644 --- a/giza_actions/integrations/uniswap/utils.py +++ b/giza_actions/integrations/uniswap/utils.py @@ -3,12 +3,13 @@ from ape import Contract -from .constants import MAX_TICK, MIN_TICK, Q96, TICKS_Q, _tick_spacing - - -def load_json(path): - with open(path) as f: - return json.load(f) +from giza_actions.integrations.uniswap.constants import ( + MAX_TICK, + MIN_TICK, + Q96, + TICKS_Q, + _tick_spacing, +) def load_contract(address): From 9e6d071f0cd4b72f84bd5ab533e16c2632db9cd3 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Tue, 14 May 2024 15:46:27 +0200 Subject: [PATCH 4/8] agent accepts abis alongside contract addresses --- examples/uni_v3_lp/action_agent.py | 22 ++++---- examples/uni_v3_lp/mint_position.py | 87 +++++++++++++++-------------- giza_actions/agent.py | 25 ++++++--- 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/examples/uni_v3_lp/action_agent.py b/examples/uni_v3_lp/action_agent.py index 0562022..e371020 100644 --- a/examples/uni_v3_lp/action_agent.py +++ b/examples/uni_v3_lp/action_agent.py @@ -17,20 +17,19 @@ # Here we load a custom sepolia rpc url from the environment sepolia_rpc_url = os.environ.get("SEPOLIA_RPC_URL") -MODEL_ID = ... # Update with your model ID +MODEL_ID = ... # Update with your model ID VERSION_ID = ... # Update with your version ID -@task(name="Data processing") +@task def process_data(realized_vol, dec_price_change): pct_change_sq = (100 * dec_price_change) ** 2 X = np.array([[realized_vol, pct_change_sq]]) - return X # Get image -@task(name="Get volatility and price change data") +@task def get_data(): # TODO: implement fetching onchain or from some other source realized_vol = 4.20 @@ -38,7 +37,7 @@ def get_data(): return realized_vol, dec_price_change -@task(name="Create a Giza agent for the Volatility prediction model") +@task def create_agent( model_id: int, version_id: int, chain: str, contracts: dict, account: str ): @@ -55,7 +54,7 @@ def create_agent( return agent -@task(name="Predict the digit in an image.") +@task def predict(agent: GizaAgent, X: np.ndarray): """ Predict the digit in an image. @@ -70,7 +69,7 @@ def predict(agent: GizaAgent, X: np.ndarray): return prediction -@task(name="Get the value from the prediction.") +@task def get_pred_val(prediction: AgentResult): """ Get the value from the prediction. @@ -86,7 +85,7 @@ def get_pred_val(prediction: AgentResult): # Create Action -@action(log_prints=True) +@action def transmission( pred_model_id, pred_version_id, @@ -111,9 +110,10 @@ def transmission( logger.info(f"Input data: {realized_vol}, {dec_price_change}") X = process_data(realized_vol, dec_price_change) + nft_manager_abi_path = "nft_manager_abi.json" contracts = { - "nft_manager": nft_manager_address, - "tokenA": tokenA_address, + "nft_manager": [nft_manager_address, nft_manager_abi_path], + "tokenA": [tokenA_address], "tokenB": tokenB_address, "pool": pool_address, } @@ -147,7 +147,7 @@ def transmission( curr_tick, predicted_value, tokenA_decimals, tokenB_decimals, pool_fee ) mint_params = get_mint_params( - user_address, tokenA_amount, tokenB_amount, pool_fee, lower_tick, upper_tick + tokenA_address, tokenB_address, user_address, tokenA_amount, tokenB_amount, pool_fee, lower_tick, upper_tick ) # step 5: mint new position logger.info("Minting new position...") diff --git a/examples/uni_v3_lp/mint_position.py b/examples/uni_v3_lp/mint_position.py index 338926d..127aa77 100644 --- a/examples/uni_v3_lp/mint_position.py +++ b/examples/uni_v3_lp/mint_position.py @@ -14,6 +14,8 @@ def get_mint_params( user_address, + token0_address, + token1_address, amount0, amount1, pool_fee, @@ -25,8 +27,8 @@ def get_mint_params( if deadline is None: deadline = int(time.time()) + 60 mint_params = { - "token0": tokenA.address, - "token1": tokenB.address, + "token0": token0_address, + "token1": token1_address, "fee": pool_fee, "tickLower": lower_tick, "tickUpper": upper_tick, @@ -74,44 +76,45 @@ def close_position(user_address, nft_manager, nft_id): nft_manager.collect((nft_id, user_address, MAX_UINT_128, MAX_UINT_128)) -networks.parse_network_choice(f"ethereum:sepolia:{sepolia_rpc_url}").__enter__() -chain_id = chain.chain_id +if __name__ == "__main__": + networks.parse_network_choice(f"ethereum:sepolia:{sepolia_rpc_url}").__enter__() + chain_id = chain.chain_id -# step 1: set params -tokenA_amount = 1000 -tokenB_amount = 1000 -pct_dev = 0.1 -pool_fee = 3000 -# step 2: load contracts -tokenA = Contract(ADDRESSES["UNI"][chain_id]) -tokenB = Contract(ADDRESSES["WETH"][chain_id]) -nft_manager = Contract(ADDRESSES["NonfungiblePositionManager"][chain_id]) -pool_factory = Contract(ADDRESSES["PoolFactory"][chain_id]) -pool_address = pool_factory.getPool(tokenA.address, tokenB.address, pool_fee) -pool = Contract(pool_address) -dev = accounts.load("dev") -dev.set_autosign(True, passphrase=dev_passphrase) -user_address = dev.address -with accounts.use_sender("dev"): - # step 3: fetch open positions - positions = get_all_user_positions(nft_manager, user_address) - print(f"Fouund the following open positions: {positions}") - # step 4: close all positions - print("Closing all open positions...") - for nft_id in positions: - close_position(user_address, nft_manager, nft_id) - # step 4: calculate mint params - print("Calculating mint params...") - _, curr_tick, _, _, _, _, _ = pool.slot0() - tokenA_decimals = tokenA.decimals() - tokenB_decimals = tokenB.decimals() - curr_price = tick_to_price(curr_tick, tokenA_decimals, tokenB_decimals) - lower_tick, upper_tick = get_tick_range( - curr_tick, pct_dev, tokenA_decimals, tokenB_decimals, pool_fee - ) - mint_params = get_mint_params( - user_address, tokenA_amount, tokenB_amount, pool_fee, lower_tick, upper_tick - ) - # step 5: mint new position - print("Minting new position...") - nft_manager.mint(mint_params) + # step 1: set params + tokenA_amount = 1000 + tokenB_amount = 1000 + pct_dev = 0.1 + pool_fee = 3000 + # step 2: load contracts + tokenA = Contract(ADDRESSES["UNI"][chain_id]) + tokenB = Contract(ADDRESSES["WETH"][chain_id]) + nft_manager = Contract(ADDRESSES["NonfungiblePositionManager"][chain_id]) + pool_factory = Contract(ADDRESSES["PoolFactory"][chain_id]) + pool_address = pool_factory.getPool(tokenA.address, tokenB.address, pool_fee) + pool = Contract(pool_address) + dev = accounts.load("dev") + dev.set_autosign(True, passphrase=dev_passphrase) + user_address = dev.address + with accounts.use_sender("dev"): + # step 3: fetch open positions + positions = get_all_user_positions(nft_manager, user_address) + print(f"Fouund the following open positions: {positions}") + # step 4: close all positions + print("Closing all open positions...") + for nft_id in positions: + close_position(user_address, nft_manager, nft_id) + # step 4: calculate mint params + print("Calculating mint params...") + _, curr_tick, _, _, _, _, _ = pool.slot0() + tokenA_decimals = tokenA.decimals() + tokenB_decimals = tokenB.decimals() + curr_price = tick_to_price(curr_tick, tokenA_decimals, tokenB_decimals) + lower_tick, upper_tick = get_tick_range( + curr_tick, pct_dev, tokenA_decimals, tokenB_decimals, pool_fee + ) + mint_params = get_mint_params( + user_address, tokenA_amount, tokenB_amount, pool_fee, lower_tick, upper_tick + ) + # step 5: mint new position + print("Minting new position...") + nft_manager.mint(mint_params) diff --git a/giza_actions/agent.py b/giza_actions/agent.py index 66629ad..a32e9d1 100644 --- a/giza_actions/agent.py +++ b/giza_actions/agent.py @@ -4,7 +4,7 @@ import time from contextlib import contextmanager from pathlib import Path -from typing import Any, Callable, Dict, Optional, Self, Tuple, Union +from typing import Any, Callable, Dict, List, Optional, Self, Tuple, Union from ape import Contract, accounts, networks from ape.contracts import ContractInstance @@ -34,7 +34,7 @@ def __init__( self, id: int, version_id: int, - contracts: Dict[str, str], + contracts: Dict[str, Union[str, List[str]]], chain: Optional[str] = None, account: Optional[str] = None, **kwargs: Any, @@ -450,7 +450,7 @@ class ContractHandler: which means that it should be done insede the GizaAgent's execute context. """ - def __init__(self, contracts: Dict[str, str]) -> None: + def __init__(self, contracts: Dict[str, Union[str, List[str]]]) -> None: self._contracts = contracts self._contracts_instances: Dict[str, ContractInstance] = {} @@ -460,19 +460,30 @@ def __getattr__(self, name: str) -> ContractInstance: """ return self._contracts_instances[name] - def _initiate_contract(self, address: str) -> ContractInstance: + def _initiate_contract(self, address: str, abi: Optional[str] = None) -> ContractInstance: """ Initiate the contract. """ - return Contract(address=address) + if not abi: + return Contract(address=address) + return Contract(address=address, abi=abi) def handle(self) -> Self: """ Handle the contracts. """ try: - for name, address in self._contracts.items(): - self._contracts_instances[name] = self._initiate_contract(address) + for name, contract_data in self._contracts.items(): + if isinstance(contract_data, str): + address = contract_data + self._contracts_instances[name] = self._initiate_contract(address) + elif isinstance(contract_data, list): + if len(contract_data) == 1: + address = contract_data[0] + self._contracts_instances[name] = self._initiate_contract(address) + else: + address, abi = contract_data + self._contracts_instances[name] = self._initiate_contract(address, abi) except NetworkError as e: logger.error(f"Failed to initiate contract: {e}") raise ValueError( From 0bc77bd88b0b8f880f67da84e64fc7d1fef52597 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Thu, 16 May 2024 10:49:27 +0200 Subject: [PATCH 5/8] removed the accidentally added issue#49 changes --- .../integrations/uniswap/ASSETS/erc20.json | 222 ------ .../uniswap/ASSETS/nft_manager.json | 686 ----------------- .../integrations/uniswap/ASSETS/pool.json | 692 ------------------ .../uniswap/ASSETS/pool_factory.json | 148 ---- .../integrations/uniswap/ASSETS/quoter.json | 97 --- .../integrations/uniswap/ASSETS/router.json | 548 -------------- .../integrations/uniswap/constants.py | 47 -- .../integrations/uniswap/nft_manager.py | 149 ---- giza_actions/integrations/uniswap/pool.py | 61 -- .../integrations/uniswap/pool_factory.py | 25 - giza_actions/integrations/uniswap/quoter.py | 44 -- giza_actions/integrations/uniswap/router.py | 91 --- giza_actions/integrations/uniswap/uniswap.py | 198 ----- giza_actions/integrations/uniswap/utils.py | 89 --- 14 files changed, 3097 deletions(-) delete mode 100644 giza_actions/integrations/uniswap/ASSETS/erc20.json delete mode 100644 giza_actions/integrations/uniswap/ASSETS/nft_manager.json delete mode 100644 giza_actions/integrations/uniswap/ASSETS/pool.json delete mode 100644 giza_actions/integrations/uniswap/ASSETS/pool_factory.json delete mode 100644 giza_actions/integrations/uniswap/ASSETS/quoter.json delete mode 100644 giza_actions/integrations/uniswap/ASSETS/router.json delete mode 100644 giza_actions/integrations/uniswap/constants.py delete mode 100644 giza_actions/integrations/uniswap/nft_manager.py delete mode 100644 giza_actions/integrations/uniswap/pool.py delete mode 100644 giza_actions/integrations/uniswap/pool_factory.py delete mode 100644 giza_actions/integrations/uniswap/quoter.py delete mode 100644 giza_actions/integrations/uniswap/router.py delete mode 100644 giza_actions/integrations/uniswap/uniswap.py delete mode 100644 giza_actions/integrations/uniswap/utils.py diff --git a/giza_actions/integrations/uniswap/ASSETS/erc20.json b/giza_actions/integrations/uniswap/ASSETS/erc20.json deleted file mode 100644 index 405d6b3..0000000 --- a/giza_actions/integrations/uniswap/ASSETS/erc20.json +++ /dev/null @@ -1,222 +0,0 @@ -[ - { - "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" - } -] diff --git a/giza_actions/integrations/uniswap/ASSETS/nft_manager.json b/giza_actions/integrations/uniswap/ASSETS/nft_manager.json deleted file mode 100644 index 720db54..0000000 --- a/giza_actions/integrations/uniswap/ASSETS/nft_manager.json +++ /dev/null @@ -1,686 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "address", "name": "_factory", "type": "address" }, - { "internalType": "address", "name": "_WETH9", "type": "address" }, - { - "internalType": "address", - "name": "_tokenDescriptor_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Collect", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "DecreaseLiquidity", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "IncreaseLiquidity", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "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": [], - "name": "WETH9", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" } - ], - "name": "balanceOf", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "burn", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { - "internalType": "uint128", - "name": "amount0Max", - "type": "uint128" - }, - { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } - ], - "internalType": "struct INonfungiblePositionManager.CollectParams", - "name": "params", - "type": "tuple" - } - ], - "name": "collect", - "outputs": [ - { "internalType": "uint256", "name": "amount0", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token0", "type": "address" }, - { "internalType": "address", "name": "token1", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" } - ], - "name": "createAndInitializePoolIfNecessary", - "outputs": [ - { "internalType": "address", "name": "pool", "type": "address" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Min", - "type": "uint256" - }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" } - ], - "internalType": "struct INonfungiblePositionManager.DecreaseLiquidityParams", - "name": "params", - "type": "tuple" - } - ], - "name": "decreaseLiquidity", - "outputs": [ - { "internalType": "uint256", "name": "amount0", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "getApproved", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { - "internalType": "uint256", - "name": "amount0Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Min", - "type": "uint256" - }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" } - ], - "internalType": "struct INonfungiblePositionManager.IncreaseLiquidityParams", - "name": "params", - "type": "tuple" - } - ], - "name": "increaseLiquidity", - "outputs": [ - { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, - { "internalType": "uint256", "name": "amount0", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "address", "name": "operator", "type": "address" } - ], - "name": "isApprovedForAll", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "token0", "type": "address" }, - { "internalType": "address", "name": "token1", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "int24", "name": "tickLower", "type": "int24" }, - { "internalType": "int24", "name": "tickUpper", "type": "int24" }, - { - "internalType": "uint256", - "name": "amount0Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Min", - "type": "uint256" - }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" } - ], - "internalType": "struct INonfungiblePositionManager.MintParams", - "name": "params", - "type": "tuple" - } - ], - "name": "mint", - "outputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, - { "internalType": "uint256", "name": "amount0", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } - ], - "name": "multicall", - "outputs": [ - { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "ownerOf", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "spender", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "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": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "positions", - "outputs": [ - { "internalType": "uint96", "name": "nonce", "type": "uint96" }, - { "internalType": "address", "name": "operator", "type": "address" }, - { "internalType": "address", "name": "token0", "type": "address" }, - { "internalType": "address", "name": "token1", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "int24", "name": "tickLower", "type": "int24" }, - { "internalType": "int24", "name": "tickUpper", "type": "int24" }, - { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, - { - "internalType": "uint256", - "name": "feeGrowthInside0LastX128", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feeGrowthInside1LastX128", - "type": "uint256" - }, - { "internalType": "uint128", "name": "tokensOwed0", "type": "uint128" }, - { "internalType": "uint128", "name": "tokensOwed1", "type": "uint128" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "refundETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from", "type": "address" }, - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from", "type": "address" }, - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "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": "selfPermit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "uint256", "name": "expiry", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "name": "selfPermitAllowed", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "uint256", "name": "expiry", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "name": "selfPermitAllowedIfNecessary", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "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": "selfPermitIfNecessary", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "operator", "type": "address" }, - { "internalType": "bool", "name": "approved", "type": "bool" } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" } - ], - "name": "sweepToken", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "index", "type": "uint256" } - ], - "name": "tokenByIndex", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "uint256", "name": "index", "type": "uint256" } - ], - "name": "tokenOfOwnerByIndex", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "tokenURI", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from", "type": "address" }, - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amount0Owed", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1Owed", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "uniswapV3MintCallback", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" } - ], - "name": "unwrapWETH9", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { "stateMutability": "payable", "type": "receive" } -] diff --git a/giza_actions/integrations/uniswap/ASSETS/pool.json b/giza_actions/integrations/uniswap/ASSETS/pool.json deleted file mode 100644 index 773ce15..0000000 --- a/giza_actions/integrations/uniswap/ASSETS/pool.json +++ /dev/null @@ -1,692 +0,0 @@ -[ - { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "int24", - "name": "tickLower", - "type": "int24" - }, - { - "indexed": true, - "internalType": "int24", - "name": "tickUpper", - "type": "int24" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "amount", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Burn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "int24", - "name": "tickLower", - "type": "int24" - }, - { - "indexed": true, - "internalType": "int24", - "name": "tickUpper", - "type": "int24" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "amount0", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "amount1", - "type": "uint128" - } - ], - "name": "Collect", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "amount0", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "amount1", - "type": "uint128" - } - ], - "name": "CollectProtocol", - "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" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "paid0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "paid1", - "type": "uint256" - } - ], - "name": "Flash", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "observationCardinalityNextOld", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint16", - "name": "observationCardinalityNextNew", - "type": "uint16" - } - ], - "name": "IncreaseObservationCardinalityNext", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint160", - "name": "sqrtPriceX96", - "type": "uint160" - }, - { - "indexed": false, - "internalType": "int24", - "name": "tick", - "type": "int24" - } - ], - "name": "Initialize", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "int24", - "name": "tickLower", - "type": "int24" - }, - { - "indexed": true, - "internalType": "int24", - "name": "tickUpper", - "type": "int24" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "amount", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Mint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "feeProtocol0Old", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "uint8", - "name": "feeProtocol1Old", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "uint8", - "name": "feeProtocol0New", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "uint8", - "name": "feeProtocol1New", - "type": "uint8" - } - ], - "name": "SetFeeProtocol", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "int256", - "name": "amount0", - "type": "int256" - }, - { - "indexed": false, - "internalType": "int256", - "name": "amount1", - "type": "int256" - }, - { - "indexed": false, - "internalType": "uint160", - "name": "sqrtPriceX96", - "type": "uint160" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "int24", - "name": "tick", - "type": "int24" - } - ], - "name": "Swap", - "type": "event" - }, - { - "inputs": [ - { "internalType": "int24", "name": "tickLower", "type": "int24" }, - { "internalType": "int24", "name": "tickUpper", "type": "int24" }, - { "internalType": "uint128", "name": "amount", "type": "uint128" } - ], - "name": "burn", - "outputs": [ - { "internalType": "uint256", "name": "amount0", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "int24", "name": "tickLower", "type": "int24" }, - { "internalType": "int24", "name": "tickUpper", "type": "int24" }, - { - "internalType": "uint128", - "name": "amount0Requested", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "amount1Requested", - "type": "uint128" - } - ], - "name": "collect", - "outputs": [ - { "internalType": "uint128", "name": "amount0", "type": "uint128" }, - { "internalType": "uint128", "name": "amount1", "type": "uint128" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { - "internalType": "uint128", - "name": "amount0Requested", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "amount1Requested", - "type": "uint128" - } - ], - "name": "collectProtocol", - "outputs": [ - { "internalType": "uint128", "name": "amount0", "type": "uint128" }, - { "internalType": "uint128", "name": "amount1", "type": "uint128" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "fee", - "outputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "feeGrowthGlobal0X128", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "feeGrowthGlobal1X128", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "amount0", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "flash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "observationCardinalityNext", - "type": "uint16" - } - ], - "name": "increaseObservationCardinalityNext", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "liquidity", - "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxLiquidityPerTick", - "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "int24", "name": "tickLower", "type": "int24" }, - { "internalType": "int24", "name": "tickUpper", "type": "int24" }, - { "internalType": "uint128", "name": "amount", "type": "uint128" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "mint", - "outputs": [ - { "internalType": "uint256", "name": "amount0", "type": "uint256" }, - { "internalType": "uint256", "name": "amount1", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "name": "observations", - "outputs": [ - { "internalType": "uint32", "name": "blockTimestamp", "type": "uint32" }, - { "internalType": "int56", "name": "tickCumulative", "type": "int56" }, - { - "internalType": "uint160", - "name": "secondsPerLiquidityCumulativeX128", - "type": "uint160" - }, - { "internalType": "bool", "name": "initialized", "type": "bool" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint32[]", "name": "secondsAgos", "type": "uint32[]" } - ], - "name": "observe", - "outputs": [ - { - "internalType": "int56[]", - "name": "tickCumulatives", - "type": "int56[]" - }, - { - "internalType": "uint160[]", - "name": "secondsPerLiquidityCumulativeX128s", - "type": "uint160[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "name": "positions", - "outputs": [ - { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, - { - "internalType": "uint256", - "name": "feeGrowthInside0LastX128", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feeGrowthInside1LastX128", - "type": "uint256" - }, - { "internalType": "uint128", "name": "tokensOwed0", "type": "uint128" }, - { "internalType": "uint128", "name": "tokensOwed1", "type": "uint128" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "protocolFees", - "outputs": [ - { "internalType": "uint128", "name": "token0", "type": "uint128" }, - { "internalType": "uint128", "name": "token1", "type": "uint128" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint8", "name": "feeProtocol0", "type": "uint8" }, - { "internalType": "uint8", "name": "feeProtocol1", "type": "uint8" } - ], - "name": "setFeeProtocol", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "slot0", - "outputs": [ - { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }, - { "internalType": "int24", "name": "tick", "type": "int24" }, - { - "internalType": "uint16", - "name": "observationIndex", - "type": "uint16" - }, - { - "internalType": "uint16", - "name": "observationCardinality", - "type": "uint16" - }, - { - "internalType": "uint16", - "name": "observationCardinalityNext", - "type": "uint16" - }, - { "internalType": "uint8", "name": "feeProtocol", "type": "uint8" }, - { "internalType": "bool", "name": "unlocked", "type": "bool" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "int24", "name": "tickLower", "type": "int24" }, - { "internalType": "int24", "name": "tickUpper", "type": "int24" } - ], - "name": "snapshotCumulativesInside", - "outputs": [ - { - "internalType": "int56", - "name": "tickCumulativeInside", - "type": "int56" - }, - { - "internalType": "uint160", - "name": "secondsPerLiquidityInsideX128", - "type": "uint160" - }, - { "internalType": "uint32", "name": "secondsInside", "type": "uint32" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "bool", "name": "zeroForOne", "type": "bool" }, - { "internalType": "int256", "name": "amountSpecified", "type": "int256" }, - { - "internalType": "uint160", - "name": "sqrtPriceLimitX96", - "type": "uint160" - }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "swap", - "outputs": [ - { "internalType": "int256", "name": "amount0", "type": "int256" }, - { "internalType": "int256", "name": "amount1", "type": "int256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "int16", "name": "", "type": "int16" }], - "name": "tickBitmap", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tickSpacing", - "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [{ "internalType": "int24", "name": "", "type": "int24" }], - "name": "ticks", - "outputs": [ - { - "internalType": "uint128", - "name": "liquidityGross", - "type": "uint128" - }, - { "internalType": "int128", "name": "liquidityNet", "type": "int128" }, - { - "internalType": "uint256", - "name": "feeGrowthOutside0X128", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feeGrowthOutside1X128", - "type": "uint256" - }, - { - "internalType": "int56", - "name": "tickCumulativeOutside", - "type": "int56" - }, - { - "internalType": "uint160", - "name": "secondsPerLiquidityOutsideX128", - "type": "uint160" - }, - { "internalType": "uint32", "name": "secondsOutside", "type": "uint32" }, - { "internalType": "bool", "name": "initialized", "type": "bool" } - ], - "stateMutability": "view", - "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" - } -] diff --git a/giza_actions/integrations/uniswap/ASSETS/pool_factory.json b/giza_actions/integrations/uniswap/ASSETS/pool_factory.json deleted file mode 100644 index 1ab193f..0000000 --- a/giza_actions/integrations/uniswap/ASSETS/pool_factory.json +++ /dev/null @@ -1,148 +0,0 @@ -[ - { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint24", - "name": "fee", - "type": "uint24" - }, - { - "indexed": true, - "internalType": "int24", - "name": "tickSpacing", - "type": "int24" - } - ], - "name": "FeeAmountEnabled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "oldOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token0", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "token1", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint24", - "name": "fee", - "type": "uint24" - }, - { - "indexed": false, - "internalType": "int24", - "name": "tickSpacing", - "type": "int24" - }, - { - "indexed": false, - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolCreated", - "type": "event" - }, - { - "inputs": [ - { "internalType": "address", "name": "tokenA", "type": "address" }, - { "internalType": "address", "name": "tokenB", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" } - ], - "name": "createPool", - "outputs": [ - { "internalType": "address", "name": "pool", "type": "address" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "int24", "name": "tickSpacing", "type": "int24" } - ], - "name": "enableFeeAmount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], - "name": "feeAmountTickSpacing", - "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint24", "name": "", "type": "uint24" } - ], - "name": "getPool", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "parameters", - "outputs": [ - { "internalType": "address", "name": "factory", "type": "address" }, - { "internalType": "address", "name": "token0", "type": "address" }, - { "internalType": "address", "name": "token1", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "int24", "name": "tickSpacing", "type": "int24" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_owner", "type": "address" } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/giza_actions/integrations/uniswap/ASSETS/quoter.json b/giza_actions/integrations/uniswap/ASSETS/quoter.json deleted file mode 100644 index e9adacb..0000000 --- a/giza_actions/integrations/uniswap/ASSETS/quoter.json +++ /dev/null @@ -1,97 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "address", "name": "_factory", "type": "address" }, - { "internalType": "address", "name": "_WETH9", "type": "address" } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "WETH9", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "path", "type": "bytes" }, - { "internalType": "uint256", "name": "amountIn", "type": "uint256" } - ], - "name": "quoteExactInput", - "outputs": [ - { "internalType": "uint256", "name": "amountOut", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "tokenIn", "type": "address" }, - { "internalType": "address", "name": "tokenOut", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, - { - "internalType": "uint160", - "name": "sqrtPriceLimitX96", - "type": "uint160" - } - ], - "name": "quoteExactInputSingle", - "outputs": [ - { "internalType": "uint256", "name": "amountOut", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "path", "type": "bytes" }, - { "internalType": "uint256", "name": "amountOut", "type": "uint256" } - ], - "name": "quoteExactOutput", - "outputs": [ - { "internalType": "uint256", "name": "amountIn", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "tokenIn", "type": "address" }, - { "internalType": "address", "name": "tokenOut", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, - { - "internalType": "uint160", - "name": "sqrtPriceLimitX96", - "type": "uint160" - } - ], - "name": "quoteExactOutputSingle", - "outputs": [ - { "internalType": "uint256", "name": "amountIn", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "int256", "name": "amount0Delta", "type": "int256" }, - { "internalType": "int256", "name": "amount1Delta", "type": "int256" }, - { "internalType": "bytes", "name": "path", "type": "bytes" } - ], - "name": "uniswapV3SwapCallback", - "outputs": [], - "stateMutability": "view", - "type": "function" - } -] diff --git a/giza_actions/integrations/uniswap/ASSETS/router.json b/giza_actions/integrations/uniswap/ASSETS/router.json deleted file mode 100644 index a679349..0000000 --- a/giza_actions/integrations/uniswap/ASSETS/router.json +++ /dev/null @@ -1,548 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "address", "name": "_factoryV2", "type": "address" }, - { "internalType": "address", "name": "factoryV3", "type": "address" }, - { - "internalType": "address", - "name": "_positionManager", - "type": "address" - }, - { "internalType": "address", "name": "_WETH9", "type": "address" } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "WETH9", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" } - ], - "name": "approveMax", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" } - ], - "name": "approveMaxMinusOne", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" } - ], - "name": "approveZeroThenMax", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" } - ], - "name": "approveZeroThenMaxMinusOne", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }], - "name": "callPositionManager", - "outputs": [{ "internalType": "bytes", "name": "result", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes[]", "name": "paths", "type": "bytes[]" }, - { "internalType": "uint128[]", "name": "amounts", "type": "uint128[]" }, - { - "internalType": "uint24", - "name": "maximumTickDivergence", - "type": "uint24" - }, - { "internalType": "uint32", "name": "secondsAgo", "type": "uint32" } - ], - "name": "checkOracleSlippage", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "path", "type": "bytes" }, - { - "internalType": "uint24", - "name": "maximumTickDivergence", - "type": "uint24" - }, - { "internalType": "uint32", "name": "secondsAgo", "type": "uint32" } - ], - "name": "checkOracleSlippage", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "bytes", "name": "path", "type": "bytes" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, - { - "internalType": "uint256", - "name": "amountOutMinimum", - "type": "uint256" - } - ], - "internalType": "struct IV3SwapRouter.ExactInputParams", - "name": "params", - "type": "tuple" - } - ], - "name": "exactInput", - "outputs": [ - { "internalType": "uint256", "name": "amountOut", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "tokenIn", "type": "address" }, - { "internalType": "address", "name": "tokenOut", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, - { - "internalType": "uint256", - "name": "amountOutMinimum", - "type": "uint256" - }, - { - "internalType": "uint160", - "name": "sqrtPriceLimitX96", - "type": "uint160" - } - ], - "internalType": "struct IV3SwapRouter.ExactInputSingleParams", - "name": "params", - "type": "tuple" - } - ], - "name": "exactInputSingle", - "outputs": [ - { "internalType": "uint256", "name": "amountOut", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "bytes", "name": "path", "type": "bytes" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, - { - "internalType": "uint256", - "name": "amountInMaximum", - "type": "uint256" - } - ], - "internalType": "struct IV3SwapRouter.ExactOutputParams", - "name": "params", - "type": "tuple" - } - ], - "name": "exactOutput", - "outputs": [ - { "internalType": "uint256", "name": "amountIn", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "tokenIn", "type": "address" }, - { "internalType": "address", "name": "tokenOut", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, - { - "internalType": "uint256", - "name": "amountInMaximum", - "type": "uint256" - }, - { - "internalType": "uint160", - "name": "sqrtPriceLimitX96", - "type": "uint160" - } - ], - "internalType": "struct IV3SwapRouter.ExactOutputSingleParams", - "name": "params", - "type": "tuple" - } - ], - "name": "exactOutputSingle", - "outputs": [ - { "internalType": "uint256", "name": "amountIn", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "factoryV2", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "getApprovalType", - "outputs": [ - { - "internalType": "enum IApproveAndCall.ApprovalType", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "token0", "type": "address" }, - { "internalType": "address", "name": "token1", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { "internalType": "uint256", "name": "amount1Min", "type": "uint256" } - ], - "internalType": "struct IApproveAndCall.IncreaseLiquidityParams", - "name": "params", - "type": "tuple" - } - ], - "name": "increaseLiquidity", - "outputs": [{ "internalType": "bytes", "name": "result", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "token0", "type": "address" }, - { "internalType": "address", "name": "token1", "type": "address" }, - { "internalType": "uint24", "name": "fee", "type": "uint24" }, - { "internalType": "int24", "name": "tickLower", "type": "int24" }, - { "internalType": "int24", "name": "tickUpper", "type": "int24" }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Min", - "type": "uint256" - }, - { "internalType": "address", "name": "recipient", "type": "address" } - ], - "internalType": "struct IApproveAndCall.MintParams", - "name": "params", - "type": "tuple" - } - ], - "name": "mint", - "outputs": [{ "internalType": "bytes", "name": "result", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "previousBlockhash", - "type": "bytes32" - }, - { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } - ], - "name": "multicall", - "outputs": [{ "internalType": "bytes[]", "name": "", "type": "bytes[]" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "deadline", "type": "uint256" }, - { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } - ], - "name": "multicall", - "outputs": [{ "internalType": "bytes[]", "name": "", "type": "bytes[]" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } - ], - "name": "multicall", - "outputs": [ - { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "positionManager", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "value", "type": "uint256" } - ], - "name": "pull", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "refundETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "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": "selfPermit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "uint256", "name": "expiry", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "name": "selfPermitAllowed", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "uint256", "name": "expiry", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "name": "selfPermitAllowedIfNecessary", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "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": "selfPermitIfNecessary", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, - { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" }, - { "internalType": "address[]", "name": "path", "type": "address[]" }, - { "internalType": "address", "name": "to", "type": "address" } - ], - "name": "swapExactTokensForTokens", - "outputs": [ - { "internalType": "uint256", "name": "amountOut", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, - { "internalType": "uint256", "name": "amountInMax", "type": "uint256" }, - { "internalType": "address[]", "name": "path", "type": "address[]" }, - { "internalType": "address", "name": "to", "type": "address" } - ], - "name": "swapTokensForExactTokens", - "outputs": [ - { "internalType": "uint256", "name": "amountIn", "type": "uint256" } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" } - ], - "name": "sweepToken", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" } - ], - "name": "sweepToken", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, - { "internalType": "address", "name": "feeRecipient", "type": "address" } - ], - "name": "sweepTokenWithFee", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, - { "internalType": "address", "name": "feeRecipient", "type": "address" } - ], - "name": "sweepTokenWithFee", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "int256", "name": "amount0Delta", "type": "int256" }, - { "internalType": "int256", "name": "amount1Delta", "type": "int256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "uniswapV3SwapCallback", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" } - ], - "name": "unwrapWETH9", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" } - ], - "name": "unwrapWETH9", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, - { "internalType": "address", "name": "feeRecipient", "type": "address" } - ], - "name": "unwrapWETH9WithFee", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, - { "internalType": "uint256", "name": "feeBips", "type": "uint256" }, - { "internalType": "address", "name": "feeRecipient", "type": "address" } - ], - "name": "unwrapWETH9WithFee", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "value", "type": "uint256" } - ], - "name": "wrapETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { "stateMutability": "payable", "type": "receive" } -] diff --git a/giza_actions/integrations/uniswap/constants.py b/giza_actions/integrations/uniswap/constants.py deleted file mode 100644 index 696a020..0000000 --- a/giza_actions/integrations/uniswap/constants.py +++ /dev/null @@ -1,47 +0,0 @@ -MIN_TICK = -887272 -MAX_TICK = -MIN_TICK -TICKS_Q = 1.0001 -Q96 = 2**96 -MAX_UINT_128 = 2 ** (128) - 1 -_tick_spacing = {100: 1, 500: 10, 3_000: 60, 10_000: 200} - - -ADDRESSES = { - # mainnet - 1: { - 3: { - "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", - "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", - "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", - "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", - }, - }, - # sepolia - 11155111: { - 3: { - "PoolFactory": "0x0227628f3F023bb0B980b67D528571c95c6DaC1c", - "NonfungiblePositionManager": "0x1238536071E1c677A632429e3655c799b22cDA52", - "Router": "0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E", - "Quoter": "0xEd1f6473345F45b75F8179591dd5bA1888cf2FB3", - }, - }, - # goerli - 5: { - 3: { - "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", - "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", - "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", - "Quoter": "", - }, - }, - # arbitrum - 42161: { - 3: { - "PoolFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984", - "NonfungiblePositionManager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", - "Router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", - "Quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", - }, - }, - # TODO: fill remaining chains: https://github.com/Uniswap/v3-periphery/blob/main/deploys.md -} diff --git a/giza_actions/integrations/uniswap/nft_manager.py b/giza_actions/integrations/uniswap/nft_manager.py deleted file mode 100644 index 7b42e27..0000000 --- a/giza_actions/integrations/uniswap/nft_manager.py +++ /dev/null @@ -1,149 +0,0 @@ -import os -import time - -from ape import Contract - -from giza_actions.integrations.uniswap.constants import MAX_UINT_128 -from giza_actions.integrations.uniswap.utils import ( - calc_amount0, - calc_amount1, - liquidity0, - liquidity1, - nearest_tick, - price_to_sqrtp, - price_to_tick, -) - - -class NFTManager: - def __init__(self, address: str, sender: str): - self.contract = Contract( - address, - abi=os.path.join(os.path.dirname(__file__), "assets/nft_manager.json"), - ) - self.sender = sender - - def get_all_user_positions(self, user_address: str = None): - if user_address is None: - user_address = self.sender - n_positions = self.contract.balanceOf(user_address) - positions = [] - for n in range(n_positions): - position = self.contract.tokenOfOwnerByIndex(user_address, n) - positions.append(position) - return positions - - def close_position(self, nft_id: int, user_address: str = None): - if user_address is None: - user_address = self.sender - liquidity = self.contract.positions(nft_id)["liquidity"] - if liquidity > 0: - self.decrease_liquidity(nft_id, liquidity=liquidity) - self.collect_fees(nft_id, user_address=user_address) - self.contract.burn(nft_id, sender=self.sender) - - def collect_fees( - self, - nft_id: int, - user_address: str = None, - amount0_max: int = MAX_UINT_128, - amount1_max: int = MAX_UINT_128, - ): - if user_address is None: - user_address = self.sender - receipt = self.contract.collect( - (nft_id, user_address, amount0_max, amount1_max), sender=self.sender - ) - return receipt - - def decrease_liquidity( - self, - nft_id: int, - liquidity: int = None, - amount0Min: int = 0, - amount1Min: int = 0, - deadline: int = None, - ): - if liquidity is None: - liquidity = self.get_pos_info(nft_id)["liquidity"] - if deadline is None: - deadline = int(time.time() + 60) - receipt = self.contract.decreaseLiquidity( - (nft_id, liquidity, amount0Min, amount1Min, deadline), sender=self.sender - ) - return receipt - - def add_liquidity( - self, - nft_id: int, - amount0Desired: int, - amount1Desired: int, - amount0Min: int = 0, - amount1Min: int = 0, - deadline: int = None, - ): - if deadline is None: - deadline = int(time.time() + 60) - receipt = self.contract.increaseLiquidity( - (nft_id, amount0Desired, amount1Desired, amount0Min, amount1Min, deadline), - sender=self.sender, - ) - return receipt - - def mint_position( - self, - pool, - lower_price: float, - upper_price: float, - amount0: int, - amount1: int, - amount0Min: int = None, - amount1Min: int = None, - recipient: str = None, - deadline: int = None, - slippage_tolerance: float = 1, - ): - fee = pool.fee - token0 = pool.token0 - token1 = pool.token1 - - lower_tick = price_to_tick(lower_price) - upper_tick = price_to_tick(upper_price) - lower_tick = nearest_tick(lower_tick, fee) - upper_tick = nearest_tick(upper_tick, fee) - - if lower_tick > upper_tick: - raise ValueError("Lower tick must be less than upper tick") - - sqrtp_cur = pool.get_pool_info()["sqrtPriceX96"] - sqrtp_low = price_to_sqrtp(lower_price) - sqrtp_upp = price_to_sqrtp(upper_price) - liq0 = liquidity0(amount0, sqrtp_cur, sqrtp_upp) - liq1 = liquidity1(amount1, sqrtp_cur, sqrtp_low) - liq = int(min(liq0, liq1)) - amount0 = calc_amount0(liq, sqrtp_upp, sqrtp_cur) - amount1 = calc_amount1(liq, sqrtp_low, sqrtp_cur) - - if recipient is None: - recipient = self.sender - if deadline is None: - deadline = int(time.time() + 60) - if amount0Min is None: - amount0Min = int(amount0 * (1 - slippage_tolerance)) - if amount1Min is None: - amount1Min = int(amount1 * (1 - slippage_tolerance)) - - mint_params = { - "token0": token0.address, - "token1": token1.address, - "fee": fee, - "tickLower": lower_tick, - "tickUpper": upper_tick, - "amount0Desired": amount0, - "amount1Desired": amount1, - "amount0Min": amount0Min, - "amount1Min": amount1Min, - "recipient": recipient, - "deadline": deadline, - } - return self.contract.mint(mint_params, sender=self.sender) diff --git a/giza_actions/integrations/uniswap/pool.py b/giza_actions/integrations/uniswap/pool.py deleted file mode 100644 index 1b24dc9..0000000 --- a/giza_actions/integrations/uniswap/pool.py +++ /dev/null @@ -1,61 +0,0 @@ -import os - -from ape import Contract, chain - -from giza_actions.integrations.uniswap.utils import tick_to_price - - -class Pool: - def __init__( - self, - address: str, - sender: str, - token0: str = None, - token1: str = None, - fee: int = None, - ): - self.contract = Contract( - address, abi=os.path.join(os.path.dirname(__file__), "assets/pool.json") - ) - self.sender = sender - self.token0 = Contract( - self.contract.token0(), - abi=os.path.join(os.path.dirname(__file__), "assets/erc20.json"), - ) - self.token0_decimals = self.token0.decimals() - self.token1 = Contract( - self.contract.token1(), - abi=os.path.join(os.path.dirname(__file__), "assets/erc20.json"), - ) - self.token1_decimals = self.token1.decimals() - self.fee = self.contract.fee() if fee is None else fee - - def get_pool_info(self, block_number: int = None): - if block_number is None: - block_number = chain.blocks.height - ( - sqrtPriceX96, - tick, - observationIndex, - observationCardinality, - observationCardinalityNext, - feeProtocol, - unlocked, - ) = self.contract.slot0(block_identifier=block_number) - return { - "sqrtPriceX96": sqrtPriceX96, - "tick": tick, - "observationIndex": observationIndex, - "observationCardinality": observationCardinality, - "observationCardinalityNext": observationCardinalityNext, - "feeProtocol": feeProtocol, - "unlocked": unlocked, - } - - def get_pool_price(self, block_number: int = None, invert: bool = False): - if block_number is None: - block_number = chain.blocks.height - tick = self.get_pool_info(block_number)["tick"] - return tick_to_price( - tick, self.token0_decimals, self.token1_decimals, invert=invert - ) diff --git a/giza_actions/integrations/uniswap/pool_factory.py b/giza_actions/integrations/uniswap/pool_factory.py deleted file mode 100644 index ed171e2..0000000 --- a/giza_actions/integrations/uniswap/pool_factory.py +++ /dev/null @@ -1,25 +0,0 @@ -import os - -from ape import Contract - -from giza_actions.integrations.uniswap.pool import Pool - - -class PoolFactory: - def __init__(self, address: str, sender: str): - self.contract = Contract( - address, - abi=os.path.join(os.path.dirname(__file__), "assets/pool_factory.json"), - ) - self.sender = sender - - def get_pool(self, token0: str, token1: str, fee: int): - if type(fee) == float: - fee = int(fee * 1e6) - pool_address = self.contract.getPool(token0, token1, fee) - return Pool(pool_address, self.sender, token0=token0, token1=token1, fee=fee) - - def create_pool(self, token0: str, token1: str, fee: int): - if type(fee) == float: - fee = int(fee * 1e6) - return self.contract.createPool(token0, token1, fee, sender=self.sender) diff --git a/giza_actions/integrations/uniswap/quoter.py b/giza_actions/integrations/uniswap/quoter.py deleted file mode 100644 index 20e8c60..0000000 --- a/giza_actions/integrations/uniswap/quoter.py +++ /dev/null @@ -1,44 +0,0 @@ -import os - -from ape import Contract -from ape.contracts import ContractInstance - - -class Quoter: - def __init__(self, address: str, sender: str): - self.contract = Contract( - address, abi=os.path.join(os.path.dirname(__file__), "assets/quoter.json") - ) - self.sender = sender - - def quote_exact_input_single( - self, - amount_in: int, - pool: ContractInstance = None, - token_in: str = None, - token_out: str = None, - fee: int = None, - sqrt_price_limit_x96: int = 0, - block_number: int = None, - ): - if pool is None and (token_in is None or token_out is None or fee is None): - raise Exception("Must provide pool or token_in, token_out, and fee") - - if token_in is None or token_out is None or fee is None: - token_in = pool.token0 if token_in is None else token_in - token_out = pool.token1 if token_out is None else token_out - fee = pool.fee if fee is None else fee - - if block_number is None: - return self.contract.quoteExactInputSingle.call( - token_in, token_out, fee, amount_in, sqrt_price_limit_x96 - ) - else: - return self.contract.quoteExactInputSingle.call( - token_in, - token_out, - fee, - amount_in, - sqrt_price_limit_x96, - block_identifier=block_number, - ) diff --git a/giza_actions/integrations/uniswap/router.py b/giza_actions/integrations/uniswap/router.py deleted file mode 100644 index 9129cac..0000000 --- a/giza_actions/integrations/uniswap/router.py +++ /dev/null @@ -1,91 +0,0 @@ -import os -import time - -from ape import Contract - -from giza_actions.integrations.uniswap.pool import Pool - - -class Router: - def __init__(self, address: str, sender: str): - self.contract = Contract( - address, abi=os.path.join(os.path.dirname(__file__), "assets/router.json") - ) - self.sender = sender - - def swap_exact_input_single( - self, - amount_in: int, - pool: Pool = None, - token_in: str = None, - token_out: str = None, - fee: int = None, - amount_out_min: int = 0, - sqrt_price_limit_x96: int = 0, - deadline: int = None, - ): - if deadline is None: - deadline = int(time.time()) + 60 - - if pool is None and (token_in is None or token_out is None or fee is None): - raise Exception("Must provide pool or token_in, token_out, and fee") - - if token_in is None or token_out is None or fee is None: - token_in = pool.token0 if token_in is None else token_in - token_out = pool.token1 if token_out is None else token_out - fee = pool.fee if fee is None else fee - - # TODO: - # add slippage and pool price impact protection - # if amount_out_min or sqrt_price_limit_x96 are floats - - swap_params = { - "tokenIn": token_in, - "tokenOut": token_out, - "fee": fee, - "recipient": self.sender, - "amountIn": amount_in, - "amountOutMinimum": amount_out_min, - "sqrtPriceLimitX96": sqrt_price_limit_x96, - } - - return self.contract.exactInputSingle(swap_params, sender=self.sender) - - def swap_exact_output_single( - self, - amount_out: int, - pool: Pool = None, - token_in: str = None, - token_out: str = None, - fee: int = None, - amount_in_max: int = 0, - sqrt_price_limit_x96: int = 0, - deadline: int = None, - ): - if deadline is None: - deadline = int(time.time()) + 60 - - if pool is None and (token_in is None or token_out is None or fee is None): - raise Exception("Must provide pool or token_in, token_out, and fee") - - if token_in is None or token_out is None or fee is None: - token_in = pool.token0 if token_in is None else token_in - token_out = pool.token1 if token_out is None else token_out - fee = pool.fee if fee is None else fee - - # TODO: - # add slippage and pool price impact protection - # if amount_out_min or sqrt_price_limit_x96 are floats - - swap_params = { - "tokenIn": token_in, - "tokenOut": token_out, - "fee": fee, - "recipient": self.sender, - "deadline": deadline, - "amountOut": amount_out, - "amountInMaximum": amount_in_max, - "sqrtPriceLimitX96": sqrt_price_limit_x96, - } - - return self.contract.exactOutputSingle(swap_params, sender=self.sender) diff --git a/giza_actions/integrations/uniswap/uniswap.py b/giza_actions/integrations/uniswap/uniswap.py deleted file mode 100644 index 45d10cf..0000000 --- a/giza_actions/integrations/uniswap/uniswap.py +++ /dev/null @@ -1,198 +0,0 @@ -from ape import chain - -from giza_actions.integrations.uniswap.constants import ADDRESSES, MAX_UINT_128 -from giza_actions.integrations.uniswap.nft_manager import NFTManager -from giza_actions.integrations.uniswap.pool import Pool -from giza_actions.integrations.uniswap.pool_factory import PoolFactory -from giza_actions.integrations.uniswap.quoter import Quoter -from giza_actions.integrations.uniswap.router import Router - - -class Uniswap: - def __init__(self, sender: str, version: int = 3): - self.sender = sender - self._chain_id = chain.chain_id - self.version = version - self._load_contracts() - - def _load_contracts(self): - if self.version == 2: - # TODO - pass - elif self.version == 3: - self.pool_factory = PoolFactory( - ADDRESSES[self._chain_id][self.version]["PoolFactory"], - sender=self.sender, - ) - self.router = Router( - ADDRESSES[self._chain_id][self.version]["Router"], sender=self.sender - ) - self.quoter = Quoter( - ADDRESSES[self._chain_id][self.version]["Quoter"], sender=self.sender - ) - self.nft_manager = NFTManager( - ADDRESSES[self._chain_id][self.version]["NonfungiblePositionManager"], - sender=self.sender, - ) - else: - raise NotImplementedError( - "Uniswap version {} not supported".format(self.version) - ) - - def get_pool(self, token0: str, token1: str, fee: int): - return self.pool_factory.get_pool(token0, token1, fee) - - def create_pool(self, token0: str, token1: str, fee: int): - return self.pool_factory.create_pool(token0, token1, fee) - - def get_all_user_positions(self, user_address: str = None): - return self.nft_manager.get_all_user_positions(user_address=user_address) - - def get_pos_info(self, nft_id: int, block_number: str = None): - if block_number is None: - return self.nft_manager.contract.positions(nft_id) - else: - return self.nft_manager.contract.positions( - nft_id, block_identifier=block_number - ) - - def close_position(self, nft_id: int, user_address: str = None): - return self.nft_manager.close_position(nft_id, user_address=user_address) - - def collect_fees( - self, - nft_id: int, - user_address: str = None, - amount0_max: int = MAX_UINT_128, - amount1_max: int = MAX_UINT_128, - ): - return self.nft_manager.collect_fees( - nft_id, - user_address=user_address, - amount0_max=amount0_max, - amount1_max=amount1_max, - ) - - def decrease_liquidity( - self, - nft_id: int, - liquidity: int = None, - amount0Min: int = 0, - amount1Min: int = 0, - deadline: int = None, - ): - return self.nft_manager.decrease_liquidity( - nft_id, - liquidity=liquidity, - amount0Min=amount0Min, - amount1Min=amount1Min, - deadline=deadline, - ) - - def add_liquidity( - self, - nft_id: int, - amount0_desired: int, - amount1_desired: int, - amount0Min: int = 0, - amount1Min: int = 0, - deadline: int = None, - ): - return self.nft_manager.add_liquidity( - nft_id, - amount0_desired, - amount1_desired, - amount0Min=amount0Min, - amount1Min=amount1Min, - deadline=deadline, - ) - - def mint_position( - self, - pool: Pool, - lower_price: float, - upper_price: float, - amount0: int, - amount1: int, - amount0Min: int = None, - amount1Min: int = None, - recipient: str = None, - deadline: int = None, - slippage_tolerance: float = 1, - ): - self.nft_manager.mint_position( - pool, - lower_price=lower_price, - upper_price=upper_price, - amount0=amount0, - amount1=amount1, - amount0Min=amount0Min, - amount1Min=amount1Min, - recipient=recipient, - deadline=deadline, - slippage_tolerance=slippage_tolerance, - ) - - def quote_exact_input_single( - self, - amount_in: int, - pool: Pool = None, - token_in: str = None, - token_out: str = None, - fee: int = None, - sqrt_price_limit_x96: int = 0, - block_number: int = None, - ): - return self.quoter.quote_exact_input_single( - amount_in, - pool=pool, - token_in=token_in, - token_out=token_out, - fee=fee, - sqrt_price_limit_x96=sqrt_price_limit_x96, - block_number=block_number, - ) - - def swap_exact_input_single( - self, - amount_in: int, - pool: Pool = None, - token_in: str = None, - token_out: str = None, - fee: int = None, - amount_out_min: int = 0, - sqrt_price_limit_x96: int = 0, - deadline: int = None, - ): - return self.router.swap_exact_input_single( - amount_in=amount_in, - pool=pool, - token_in=token_in, - token_out=token_out, - fee=fee, - amount_out_min=amount_out_min, - sqrt_price_limit_x96=sqrt_price_limit_x96, - deadline=deadline, - ) - - def swap_exact_output_single( - self, - amount_out: int, - pool: Pool = None, - token_in: str = None, - token_out: str = None, - fee: int = None, - amount_in_max: int = 0, - sqrt_price_limit_x96: int = 0, - deadline: int = None, - ): - return self.router.swap_exact_output_single( - amount_out=amount_out, - pool=pool, - token_in=token_in, - token_out=token_out, - fee=fee, - amount_in_max=amount_in_max, - sqrt_price_limit_x96=sqrt_price_limit_x96, - deadline=deadline, - ) diff --git a/giza_actions/integrations/uniswap/utils.py b/giza_actions/integrations/uniswap/utils.py deleted file mode 100644 index 50bf254..0000000 --- a/giza_actions/integrations/uniswap/utils.py +++ /dev/null @@ -1,89 +0,0 @@ -import json -import math - -from ape import Contract - -from giza_actions.integrations.uniswap.constants import ( - MAX_TICK, - MIN_TICK, - Q96, - TICKS_Q, - _tick_spacing, -) - - -def load_contract(address): - return Contract(address) - - -def price_to_tick(price): - sqrtPriceX96 = int(price * 2**96) - tick = math.floor(math.log((sqrtPriceX96 / Q96) ** 2) / math.log(TICKS_Q)) - return tick - - -def price_to_sqrtp(p): - return int(math.sqrt(p) * Q96) - - -def tick_to_price(tick, decimals0, decimals1, invert=False): - if invert: - return 1 / (TICKS_Q**tick / 10 ** (decimals1 - decimals0)) - else: - return TICKS_Q**tick / 10 ** (decimals1 - decimals0) - - -def get_min_tick(fee): - min_tick_spacing = _tick_spacing[fee] - return -(MIN_TICK // -min_tick_spacing) * min_tick_spacing - - -def get_max_tick(fee): - max_tick_spacing = _tick_spacing[fee] - return (MAX_TICK // max_tick_spacing) * max_tick_spacing - - -def default_tick_range(fee): - min_tick = get_min_tick(fee) - max_tick = get_max_tick(fee) - return min_tick, max_tick - - -# https://uniswapv3book.com/milestone_1/calculating-liquidity.html -def calc_amount0(liq, pa, pb): - if pa > pb: - pa, pb = pb, pa - return int(liq * Q96 * (pb - pa) / pa / pb) - - -def calc_amount1(liq, pa, pb): - if pa > pb: - pa, pb = pb, pa - return int(liq * (pb - pa) / Q96) - - -def liquidity0(amount, pa, pb): - if pa > pb: - pa, pb = pb, pa - return (amount * (pa * pb) / Q96) / (pb - pa) - - -def liquidity1(amount, pa, pb): - if pa > pb: - pa, pb = pb, pa - return amount * Q96 / (pb - pa) - - -def nearest_tick(tick, fee): - min_tick, max_tick = default_tick_range(fee) - assert ( - min_tick <= tick <= max_tick - ), f"Provided tick is out of bounds: {(min_tick, max_tick)}" - tick_spacing = _tick_spacing[fee] - rounded_tick_spacing = round(tick / tick_spacing) * tick_spacing - if rounded_tick_spacing < min_tick: - return rounded_tick_spacing + tick_spacing - elif rounded_tick_spacing > max_tick: - return rounded_tick_spacing - tick_spacing - else: - return rounded_tick_spacing From d6eabb579643f37af6be0fdef5fe7144cdaed755 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Thu, 16 May 2024 12:02:37 +0200 Subject: [PATCH 6/8] fixed formatting with poetry pre-commit --- examples/agents/action_agent.py | 22 ++++++---- examples/agents/read_contracts.py | 2 +- examples/imagenet/inference.py | 38 ++++++++++------- examples/integrations/uniswap/test_funcs.py | 11 ++++- examples/simple/example.py | 4 +- examples/simple/example_cron.py | 4 +- examples/simple/example_interval.py | 4 +- examples/simple/example_parameters.py | 8 +++- examples/uni_v3_lp/action_agent.py | 11 ++++- examples/uni_v3_lp/mint_position.py | 2 +- .../deployments/pytorch_mnist_deployment.py | 41 +++++++++---------- giza_actions/agent.py | 12 ++++-- 12 files changed, 100 insertions(+), 59 deletions(-) diff --git a/examples/agents/action_agent.py b/examples/agents/action_agent.py index 764e286..2e3c549 100644 --- a/examples/agents/action_agent.py +++ b/examples/agents/action_agent.py @@ -7,30 +7,33 @@ from prefect import get_run_logger + # Process the image @task def process_image(img): - img = np.resize(img, (28,28)) - img = img.reshape(1,1,28,28) - img = img/255.0 + img = np.resize(img, (28, 28)) + img = img.reshape(1, 1, 28, 28) + img = img / 255.0 print(img.shape) # For now, we will just use a small tensor as input to a single-layer softmax. We will change this when the PoC works - tensor = np.random.rand(1,3) + tensor = np.random.rand(1, 3) return tensor - + + # Get the image @task def get_image(path): with Image.open(path) as img: - img = img.convert('L') + img = img.convert("L") img = np.array(img) return img + # Create the Action @action(log_prints=True) def transmission(): logger = get_run_logger() - img_path = 'seven.png' + img_path = "seven.png" img = get_image(img_path) img = process_image(img) id = ... @@ -43,7 +46,7 @@ def transmission(): id=id, chain="ethereum:sepolia:geth", version_id=version, - account=account + account=account, ) result = agent.predict(input_feed={"image": img}, verifiable=True) @@ -58,4 +61,5 @@ def transmission(): pprint.pprint(contract_result.__dict__) logger.info("Finished") -transmission() \ No newline at end of file + +transmission() diff --git a/examples/agents/read_contracts.py b/examples/agents/read_contracts.py index 4ca61fd..6983195 100644 --- a/examples/agents/read_contracts.py +++ b/examples/agents/read_contracts.py @@ -29,7 +29,7 @@ contracts={ "mnist": "0x17807a00bE76716B91d5ba1232dd1647c4414912", "token": "0xeF7cCAE97ea69F5CdC89e496b0eDa2687C95D93B", - }, + }, chain="ethereum:sepolia:geth", account=ACCOUNT_ALIAS, ) diff --git a/examples/imagenet/inference.py b/examples/imagenet/inference.py index 8c05334..76a8ef2 100644 --- a/examples/imagenet/inference.py +++ b/examples/imagenet/inference.py @@ -10,63 +10,70 @@ @task def download_image(): - image_url = 'https://s3.amazonaws.com/model-server/inputs/kitten.jpg' + image_url = "https://s3.amazonaws.com/model-server/inputs/kitten.jpg" image_data = requests.get(image_url).content - with open('kitten.jpg', 'wb') as handler: + with open("kitten.jpg", "wb") as handler: handler.write(image_data) + @task def download_labels(): - labels_url = 'https://s3.amazonaws.com/onnx-model-zoo/synset.txt' + labels_url = "https://s3.amazonaws.com/onnx-model-zoo/synset.txt" labels_data = requests.get(labels_url).content - with open('synset.txt', 'wb') as handler: + with open("synset.txt", "wb") as handler: handler.write(labels_data) + @task def download_model(): - model_url = 'https://github.com/onnx/models/raw/main/vision/classification/resnet/model/resnet50-v1-12.onnx' + model_url = "https://github.com/onnx/models/raw/main/vision/classification/resnet/model/resnet50-v1-12.onnx" model_data = requests.get(model_url).content - with open('resnet50-v1-12.onnx', 'wb') as handler: + with open("resnet50-v1-12.onnx", "wb") as handler: handler.write(model_data) + @task def read_labels(): - with open('synset.txt') as f: + with open("synset.txt") as f: labels = [l.rstrip() for l in f] return labels + @task def get_image(path): with Image.open(path) as img: - img = np.array(img.convert('RGB')) + img = np.array(img.convert("RGB")) return img + @task def preprocess(img): - img = img / 255. + img = img / 255.0 img = cv2.resize(img, (256, 256)) h, w = img.shape[0], img.shape[1] y0 = (h - 224) // 2 x0 = (w - 224) // 2 - img = img[y0 : y0+224, x0 : x0+224, :] + img = img[y0 : y0 + 224, x0 : x0 + 224, :] img = (img - [0.485, 0.456, 0.406]) / [0.229, 0.224, 0.225] img = np.transpose(img, axes=[2, 0, 1]) img = img.astype(np.float32) img = np.expand_dims(img, axis=0) return img + @task def predict(model, labels, img, verifiable: bool = False): ort_inputs = {model.session.get_inputs()[0].name: img} preds = model.predict(ort_inputs, verifiable=verifiable) preds = np.squeeze(preds) a = np.argsort(preds)[::-1] - print('class=%s ; probability=%f' %(labels[a[0]],preds[a[0]])) + print("class={} ; probability={:f}".format(labels[a[0]], preds[a[0]])) + @action(log_prints=True) def execution(): - model_path = 'resnet50-v1-12.onnx' - img_path = 'kitten.jpg' + model_path = "resnet50-v1-12.onnx" + img_path = "kitten.jpg" verifiable = False download_model() @@ -78,6 +85,7 @@ def execution(): img = preprocess(img) predict(model, labels, img, verifiable=verifiable) -if __name__ == '__main__': + +if __name__ == "__main__": action_deploy = Action(entrypoint=execution, name="inference-local-action") - action_deploy.serve(name="imagenet-local-action") \ No newline at end of file + action_deploy.serve(name="imagenet-local-action") diff --git a/examples/integrations/uniswap/test_funcs.py b/examples/integrations/uniswap/test_funcs.py index 7906a94..cc2af4b 100644 --- a/examples/integrations/uniswap/test_funcs.py +++ b/examples/integrations/uniswap/test_funcs.py @@ -43,7 +43,9 @@ token0.approve(sender, int(1e18), sender=sender) token0.deposit(value=int(1e18), sender=sender) token0_balance = token0.balanceOf(sender) - logger.info(f"--------- Balances before swap: {token0_balance} {token1.balanceOf(sender)}") + logger.info( + f"--------- Balances before swap: {token0_balance} {token1.balanceOf(sender)}" + ) token0.approve(uni.router.contract, token0_balance, sender=sender) uni.swap_exact_input_single( token0_balance, token_in=token0, token_out=token1, fee=fee @@ -98,7 +100,12 @@ amount0_desired = int(amount0_to_mint * (1 + increase_fraction)) amount1_desired = int(amount1_to_mint * (1 + increase_fraction)) uni.add_liquidity( - nft_id, amount0_desired, amount1_desired, amount0Min=0, amount1Min=0, deadline=None + nft_id, + amount0_desired, + amount1_desired, + amount0Min=0, + amount1Min=0, + deadline=None, ) pos_info = uni.get_pos_info(nft_id) logger.info(f"--------- {nft_id} Info Add Liq: {pos_info}") diff --git a/examples/simple/example.py b/examples/simple/example.py index e3b703f..3448499 100644 --- a/examples/simple/example.py +++ b/examples/simple/example.py @@ -2,6 +2,7 @@ from giza_actions.model import GizaModel from giza_actions.task import task + @task def preprocess(): print(f"Preprocessing...") @@ -17,6 +18,7 @@ def inference(): preprocess() transform() -if __name__ == '__main__': + +if __name__ == "__main__": action_deploy = Action(entrypoint=inference, name="inference-local-action") action_deploy.serve(name="inference-local-action") diff --git a/examples/simple/example_cron.py b/examples/simple/example_cron.py index 68ad9ae..760cffb 100644 --- a/examples/simple/example_cron.py +++ b/examples/simple/example_cron.py @@ -2,6 +2,7 @@ from giza_actions.model import GizaModel from giza_actions.task import task + @task def preprocess(): print(f"Preprocessing...") @@ -17,6 +18,7 @@ def inference(): preprocess() transform() -if __name__ == '__main__': + +if __name__ == "__main__": action_deploy = Action(entrypoint=inference, name="inference-local-action") action_deploy.serve(name="inference-local-action", cron="* * * * *") diff --git a/examples/simple/example_interval.py b/examples/simple/example_interval.py index fd588c7..2aea5f7 100644 --- a/examples/simple/example_interval.py +++ b/examples/simple/example_interval.py @@ -2,6 +2,7 @@ from giza_actions.model import GizaModel from giza_actions.task import task + @task def preprocess(): print(f"Preprocessing...") @@ -17,6 +18,7 @@ def inference(): preprocess() transform() -if __name__ == '__main__': + +if __name__ == "__main__": action_deploy = Action(entrypoint=inference, name="inference-local-action") action_deploy.serve(name="inference-local-action", interval=10) diff --git a/examples/simple/example_parameters.py b/examples/simple/example_parameters.py index 4a2c297..8269f84 100644 --- a/examples/simple/example_parameters.py +++ b/examples/simple/example_parameters.py @@ -2,6 +2,7 @@ from giza_actions.model import GizaModel from giza_actions.task import task + @task def preprocess(example_parameter: bool = False): print(f"Preprocessing with example={example_parameter}") @@ -20,6 +21,9 @@ def inference(example_parameter: bool = False): preprocess(example_parameter=example_parameter) transform(example_parameter=example_parameter) -if __name__ == '__main__': + +if __name__ == "__main__": action_deploy = Action(entrypoint=inference, name="inference-local-action") - action_deploy.serve(name="inference-local-action", parameters={"example_parameter": False}) + action_deploy.serve( + name="inference-local-action", parameters={"example_parameter": False} + ) diff --git a/examples/uni_v3_lp/action_agent.py b/examples/uni_v3_lp/action_agent.py index e371020..909f630 100644 --- a/examples/uni_v3_lp/action_agent.py +++ b/examples/uni_v3_lp/action_agent.py @@ -17,7 +17,7 @@ # Here we load a custom sepolia rpc url from the environment sepolia_rpc_url = os.environ.get("SEPOLIA_RPC_URL") -MODEL_ID = ... # Update with your model ID +MODEL_ID = ... # Update with your model ID VERSION_ID = ... # Update with your version ID @@ -147,7 +147,14 @@ def transmission( curr_tick, predicted_value, tokenA_decimals, tokenB_decimals, pool_fee ) mint_params = get_mint_params( - tokenA_address, tokenB_address, user_address, tokenA_amount, tokenB_amount, pool_fee, lower_tick, upper_tick + tokenA_address, + tokenB_address, + user_address, + tokenA_amount, + tokenB_amount, + pool_fee, + lower_tick, + upper_tick, ) # step 5: mint new position logger.info("Minting new position...") diff --git a/examples/uni_v3_lp/mint_position.py b/examples/uni_v3_lp/mint_position.py index 127aa77..6d7547e 100644 --- a/examples/uni_v3_lp/mint_position.py +++ b/examples/uni_v3_lp/mint_position.py @@ -14,7 +14,7 @@ def get_mint_params( user_address, - token0_address, + token0_address, token1_address, amount0, amount1, diff --git a/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py b/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py index 88c47ec..dbbbae5 100644 --- a/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py +++ b/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py @@ -9,7 +9,7 @@ from torch.utils.data import DataLoader, TensorDataset -device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") input_size = 196 # 14x14 hidden_size = 10 @@ -42,20 +42,17 @@ def resize_images(images): async def prepare_datasets(): print("Prepare dataset ...") - train_dataset = torchvision.datasets.MNIST( - root='./data', train=True, download=True) - test_dataset = torchvision.datasets.MNIST(root='./data', train=False) + train_dataset = torchvision.datasets.MNIST(root="./data", train=True, download=True) + test_dataset = torchvision.datasets.MNIST(root="./data", train=False) x_train = resize_images(train_dataset) x_test = resize_images(test_dataset) - x_train = torch.tensor(x_train.reshape(-1, 14*14).astype('float32') / 255) - y_train = torch.tensor( - [label for _, label in train_dataset], dtype=torch.long) + x_train = torch.tensor(x_train.reshape(-1, 14 * 14).astype("float32") / 255) + y_train = torch.tensor([label for _, label in train_dataset], dtype=torch.long) - x_test = torch.tensor(x_test.reshape(-1, 14*14).astype('float32') / 255) - y_test = torch.tensor( - [label for _, label in test_dataset], dtype=torch.long) + x_test = torch.tensor(x_test.reshape(-1, 14 * 14).astype("float32") / 255) + y_test = torch.tensor([label for _, label in test_dataset], dtype=torch.long) return x_train, y_train, x_test, y_test @@ -63,10 +60,12 @@ async def prepare_datasets(): async def create_data_loaders(x_train, y_train, x_test, y_test): print("Create data loaders ...") - train_loader = DataLoader(TensorDataset( - x_train, y_train), batch_size=batch_size, shuffle=True) - test_loader = DataLoader(TensorDataset( - x_test, y_test), batch_size=batch_size, shuffle=False) + train_loader = DataLoader( + TensorDataset(x_train, y_train), batch_size=batch_size, shuffle=True + ) + test_loader = DataLoader( + TensorDataset(x_test, y_test), batch_size=batch_size, shuffle=False + ) return train_loader, test_loader @@ -80,7 +79,7 @@ async def train_model(train_loader): for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): - images = images.to(device).reshape(-1, 14*14) + images = images.to(device).reshape(-1, 14 * 14) labels = labels.to(device) outputs = model(images) @@ -92,7 +91,8 @@ async def train_model(train_loader): if (i + 1) % 100 == 0: print( - f'Epoch [{epoch + 1}/{num_epochs}], Step [{i + 1}/{len(train_loader)}], Loss: {loss.item():.4f}') + f"Epoch [{epoch + 1}/{num_epochs}], Step [{i + 1}/{len(train_loader)}], Loss: {loss.item():.4f}" + ) return model @@ -102,7 +102,7 @@ async def test_model(model, test_loader): n_correct = 0 n_samples = 0 for images, labels in test_loader: - images = images.to(device).reshape(-1, 14*14) + images = images.to(device).reshape(-1, 14 * 14) labels = labels.to(device) outputs = model(images) _, predicted = torch.max(outputs.data, 1) @@ -110,18 +110,17 @@ async def test_model(model, test_loader): n_correct += (predicted == labels).sum().item() acc = 100.0 * n_correct / n_samples - print(f'Accuracy of the network on the 10000 test images: {acc} %') + print(f"Accuracy of the network on the 10000 test images: {acc} %") @action(log_prints=True) def execution(): x_train, y_train, x_test, y_test = prepare_datasets() - train_loader, test_loader = create_data_loaders( - x_train, y_train, x_test, y_test) + train_loader, test_loader = create_data_loaders(x_train, y_train, x_test, y_test) model = train_model(train_loader) test_model(model, test_loader) -if __name__ == '__main__': +if __name__ == "__main__": action_deploy = Action(entrypoint=execution, name="pytorch-mnist-action") action_deploy.serve(name="pytorch-mnist-deployment") diff --git a/giza_actions/agent.py b/giza_actions/agent.py index a32e9d1..677dc1d 100644 --- a/giza_actions/agent.py +++ b/giza_actions/agent.py @@ -460,7 +460,9 @@ def __getattr__(self, name: str) -> ContractInstance: """ return self._contracts_instances[name] - def _initiate_contract(self, address: str, abi: Optional[str] = None) -> ContractInstance: + def _initiate_contract( + self, address: str, abi: Optional[str] = None + ) -> ContractInstance: """ Initiate the contract. """ @@ -480,10 +482,14 @@ def handle(self) -> Self: elif isinstance(contract_data, list): if len(contract_data) == 1: address = contract_data[0] - self._contracts_instances[name] = self._initiate_contract(address) + self._contracts_instances[name] = self._initiate_contract( + address + ) else: address, abi = contract_data - self._contracts_instances[name] = self._initiate_contract(address, abi) + self._contracts_instances[name] = self._initiate_contract( + address, abi + ) except NetworkError as e: logger.error(f"Failed to initiate contract: {e}") raise ValueError( From 9e50ec387ab926191b7b956d8b992a82bbdf2d6d Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Thu, 16 May 2024 12:06:55 +0200 Subject: [PATCH 7/8] removed old integration file --- examples/integrations/uniswap/test_funcs.py | 114 -------------------- 1 file changed, 114 deletions(-) delete mode 100644 examples/integrations/uniswap/test_funcs.py diff --git a/examples/integrations/uniswap/test_funcs.py b/examples/integrations/uniswap/test_funcs.py deleted file mode 100644 index cc2af4b..0000000 --- a/examples/integrations/uniswap/test_funcs.py +++ /dev/null @@ -1,114 +0,0 @@ -import os - -from ape import Contract, accounts, networks -from dotenv import find_dotenv, load_dotenv -import logging - -from giza_actions.integrations.uniswap.uniswap import Uniswap - -load_dotenv(find_dotenv()) -dev_passphrase = os.environ.get("DEV_PASSPHRASE") - -logger = logging.getLogger(__name__) - -with networks.parse_network_choice(f"ethereum:mainnet-fork:foundry"): - sender = accounts.load("dev") - sender.set_autosign(True, passphrase=dev_passphrase) - - weth_address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" - usdc_address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" - token0 = Contract(weth_address) - token1 = Contract(usdc_address) - fee = 500 - - ### Uniswap ### - uni = Uniswap(sender=sender, version=3) - pool = uni.get_pool(token0, token1, fee) - price = pool.get_pool_price(invert=True) - logger.info(f"--------- Pool Price: {price}") - - ### Quoter ### - amount_in = int(1e8) - # calling using pool object - amount_out = uni.quote_exact_input_single(amount_in, pool=pool) - logger.info(f"--------- Amount out: {amount_out}") - # # or by specifying the tokens and the fee - amount_out = uni.quote_exact_input_single( - amount_in, token_in=token1, token_out=token0, fee=fee - ) - logger.info(f"--------- Amount out: {amount_out}") - - ### Router ### - sender.balance += int(2e18) # funding 1 eth more than we will use for gas - token0.approve(sender, int(1e18), sender=sender) - token0.deposit(value=int(1e18), sender=sender) - token0_balance = token0.balanceOf(sender) - logger.info( - f"--------- Balances before swap: {token0_balance} {token1.balanceOf(sender)}" - ) - token0.approve(uni.router.contract, token0_balance, sender=sender) - uni.swap_exact_input_single( - token0_balance, token_in=token0, token_out=token1, fee=fee - ) - logger.info( - f"--------- Balances after exactInputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" - ) - token1.approve(uni.router.contract, token1.balanceOf(sender), sender=sender) - token0_amount_out = int(1e16) # 0.01 eth - accepted_slippage = 0.01 # 1% - amount_in_max = int(token1.balanceOf(sender) * (1 - accepted_slippage)) - uni.swap_exact_output_single( - token0_amount_out, - token_in=token1, - token_out=token0, - fee=fee, - amount_in_max=amount_in_max, - ) - logger.info( - f"--------- Balances after exactOutputSingle swap: {token0.balanceOf(sender)} {token1.balanceOf(sender)}" - ) - - ### NFT Manager ### - token0.approve(uni.nft_manager.contract, token0.balanceOf(sender), sender=sender) - token1.approve(uni.nft_manager.contract, token1.balanceOf(sender), sender=sender) - user_positions = uni.get_all_user_positions() - logger.info(f"--------- User Positions Init: {user_positions}") - amount0_to_mint = int(0.5 * token0.balanceOf(sender)) - amount1_to_mint = int(0.5 * token1.balanceOf(sender)) - price = pool.get_pool_price(invert=True) - pct_dev = 0.1 - lower_price = int(price * (1 - pct_dev)) - upper_price = int(price * (1 + pct_dev)) - uni.mint_position( - pool, - lower_price, - upper_price, - amount0=amount0_to_mint, - amount1=amount1_to_mint, - amount0Min=None, - amount1Min=None, - recipient=None, - deadline=None, - slippage_tolerance=1, - ) - user_positions = uni.get_all_user_positions() - logger.info(f"--------- User Positions after minting: {user_positions}") - nft_id = user_positions[0] - pos_info = uni.get_pos_info(nft_id) - logger.info(f"--------- {nft_id} Info: {pos_info}") - increase_fraction = 0.1 - amount0_desired = int(amount0_to_mint * (1 + increase_fraction)) - amount1_desired = int(amount1_to_mint * (1 + increase_fraction)) - uni.add_liquidity( - nft_id, - amount0_desired, - amount1_desired, - amount0Min=0, - amount1Min=0, - deadline=None, - ) - pos_info = uni.get_pos_info(nft_id) - logger.info(f"--------- {nft_id} Info Add Liq: {pos_info}") - uni.close_position(nft_id) - user_positions = uni.get_all_user_positions() - logger.info(f"--------- {nft_id} Burnt, user_pos: {user_positions}") From ef7121abb0f56c90c25182d62f2dbe5fe4311ac3 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Wed, 29 May 2024 15:39:21 +0200 Subject: [PATCH 8/8] mnist fix --- .../deployments/pytorch_mnist_deployment.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py b/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py index 89626ee..2f4d47d 100644 --- a/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py +++ b/examples/verifiable_mnist/deployments/pytorch_mnist_deployment.py @@ -113,11 +113,4 @@ def execution(): model = train_model(train_loader) test_model(model, test_loader) -<<<<<<< HEAD - -if __name__ == "__main__": - action_deploy = Action(entrypoint=execution, name="pytorch-mnist-action") - action_deploy.serve(name="pytorch-mnist-deployment") -======= execution() ->>>>>>> main