From 67c2c57c402375f1d6167c2624311e3cd30b8e0c Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 4 Mar 2024 17:25:21 +0300 Subject: [PATCH 01/47] add: farming abi, farming addresses --- src/abis/farming/algebraEternalFarming.ts | 1153 +++++++++++++++++++++ src/abis/farming/farmingCenter.ts | 392 +++++++ src/abis/farming/index.ts | 2 + src/abis/index.ts | 15 +- src/constants/addresses.ts | 29 +- 5 files changed, 1576 insertions(+), 15 deletions(-) create mode 100644 src/abis/farming/algebraEternalFarming.ts create mode 100644 src/abis/farming/farmingCenter.ts create mode 100644 src/abis/farming/index.ts diff --git a/src/abis/farming/algebraEternalFarming.ts b/src/abis/farming/algebraEternalFarming.ts new file mode 100644 index 0000000..e77ca37 --- /dev/null +++ b/src/abis/farming/algebraEternalFarming.ts @@ -0,0 +1,1153 @@ +export const algebraEternalFarming = { + _format: 'hh-sol-artifact-1', + contractName: 'AlgebraEternalFarming', + sourceName: 'contracts/farmings/AlgebraEternalFarming.sol', + abi: [ + { + inputs: [ + { + internalType: 'contract IAlgebraPoolDeployer', + name: '_deployer', + type: 'address', + }, + { + internalType: 'contract INonfungiblePositionManager', + name: '_nonfungiblePositionManager', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'anotherFarmingIsActive', + type: 'error', + }, + { + inputs: [], + name: 'claimToZeroAddress', + type: 'error', + }, + { + inputs: [], + name: 'emergencyActivated', + type: 'error', + }, + { + inputs: [], + name: 'farmDoesNotExist', + type: 'error', + }, + { + inputs: [], + name: 'incentiveNotExist', + type: 'error', + }, + { + inputs: [], + name: 'incentiveStopped', + type: 'error', + }, + { + inputs: [], + name: 'invalidPool', + type: 'error', + }, + { + inputs: [], + name: 'invalidTokenAmount', + type: 'error', + }, + { + inputs: [], + name: 'minimalPositionWidthTooWide', + type: 'error', + }, + { + inputs: [], + name: 'pluginNotConnected', + type: 'error', + }, + { + inputs: [], + name: 'poolReentrancyLock', + type: 'error', + }, + { + inputs: [], + name: 'positionIsTooNarrow', + type: 'error', + }, + { + inputs: [], + name: 'reentrancyLock', + type: 'error', + }, + { + inputs: [], + name: 'tokenAlreadyFarmed', + type: 'error', + }, + { + inputs: [], + name: 'zeroLiquidity', + type: 'error', + }, + { + inputs: [], + name: 'zeroRewardAmount', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'newStatus', + type: 'bool', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'virtualPool', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint24', + name: 'minimalAllowedPositionWidth', + type: 'uint24', + }, + ], + name: 'EternalFarmingCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'rewardAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'bonusRewardToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + ], + name: 'FarmEnded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint128', + name: 'liquidity', + type: 'uint128', + }, + ], + name: 'FarmEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'farmingCenter', + type: 'address', + }, + ], + name: 'FarmingCenter', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'IncentiveDeactivated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusRewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'RewardAmountsDecreased', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'rewardAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'RewardClaimed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusRewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'RewardsAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusRewardAmount', + type: 'uint256', + }, + ], + name: 'RewardsCollected', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint128', + name: 'rewardRate', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint128', + name: 'bonusRewardRate', + type: 'uint128', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'RewardsRatesChanged', + type: 'event', + }, + { + inputs: [], + name: 'FARMINGS_ADMINISTRATOR_ROLE', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'INCENTIVE_MAKER_ROLE', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'rewardAmount', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardAmount', + type: 'uint128', + }, + ], + name: 'addRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountRequested', + type: 'uint256', + }, + ], + name: 'claimReward', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountRequested', + type: 'uint256', + }, + ], + name: 'claimRewardFrom', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + name: 'collectRewards', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint128', + name: 'reward', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusReward', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'rewardRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardRate', + type: 'uint128', + }, + { + internalType: 'uint24', + name: 'minimalPositionWidth', + type: 'uint24', + }, + ], + internalType: + 'struct IAlgebraEternalFarming.IncentiveParams', + name: 'params', + type: 'tuple', + }, + { + internalType: 'address', + name: 'plugin', + type: 'address', + }, + ], + name: 'createEternalFarming', + outputs: [ + { + internalType: 'address', + name: 'virtualPool', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + ], + name: 'deactivateIncentive', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'rewardAmount', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardAmount', + type: 'uint128', + }, + ], + name: 'decreaseRewardsAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'enterFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + name: 'exitFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'farmingCenter', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'farms', + outputs: [ + { + internalType: 'uint128', + name: 'liquidity', + type: 'uint128', + }, + { + internalType: 'int24', + name: 'tickLower', + type: 'int24', + }, + { + internalType: 'int24', + name: 'tickUpper', + type: 'int24', + }, + { + internalType: 'uint256', + name: 'innerRewardGrowth0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'innerRewardGrowth1', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'getRewardInfo', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'incentives', + outputs: [ + { + internalType: 'uint128', + name: 'totalReward', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusReward', + type: 'uint128', + }, + { + internalType: 'address', + name: 'virtualPoolAddress', + type: 'address', + }, + { + internalType: 'uint24', + name: 'minimalPositionWidth', + type: 'uint24', + }, + { + internalType: 'bool', + name: 'deactivated', + type: 'bool', + }, + { + internalType: 'address', + name: 'pluginAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isEmergencyWithdrawActivated', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'isIncentiveDeactivated', + outputs: [ + { + internalType: 'bool', + name: 'res', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'nonfungiblePositionManager', + outputs: [ + { + internalType: 'contract INonfungiblePositionManager', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'numOfIncentives', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + ], + name: 'rewards', + outputs: [ + { + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'newStatus', + type: 'bool', + }, + ], + name: 'setEmergencyWithdrawStatus', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_farmingCenter', + type: 'address', + }, + ], + name: 'setFarmingCenterAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'rewardRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardRate', + type: 'uint128', + }, + ], + name: 'setRates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + bytecode: + '0x60e06040526000805460ff60a81b1916600160a81b1790553480156200002457600080fd5b5060405162006005380380620060058339810160408190526200004791620000ed565b6001600160a01b03808216608081905290831660a0526040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa15801562000099573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000bf91906200012c565b6001600160a01b031660c05250620001539050565b6001600160a01b0381168114620000ea57600080fd5b50565b600080604083850312156200010157600080fd5b82516200010e81620000d4565b60208401519092506200012181620000d4565b809150509250929050565b6000602082840312156200013f57600080fd5b81516200014c81620000d4565b9392505050565b60805160a05160c051615e7b6200018a600039600061200e0152600061270d0152600081816104f9015261272e0152615e7b6000f3fe60806040523480156200001157600080fd5b5060043610620001ad5760003560e01c80638433524111620000f5578063dd56e5d81162000097578063f2256319116200006e578063f225631914620005d1578063f26ebf7a14620005f7578063f6de3cae146200060e57600080fd5b8063dd56e5d8146200056b578063df42efda146200058c578063e70b9e2714620005a357600080fd5b8063b44a272211620000cc578063b44a272214620004f3578063b5bae00a146200051b578063b8883c50146200054357600080fd5b80638433524114620004ae578063890cdcb314620004c557806396da9bd514620004dc57600080fd5b806336808b19116200015f5780635739f0b911620001365780635739f0b9146200037657806360777795146200038d57806382bd79ea14620004a457600080fd5b806336808b1914620002fa5780633c6d07151462000311578063547b6da9146200033957600080fd5b806327e6a99a116200019457806327e6a99a14620002095780632912bf1014620002ca5780632f2d783d14620002e357600080fd5b8063046ec16614620001b25780630a53075414620001e3575b600080fd5b620001c9620001c33660046200343a565b62000625565b604080519283526020830191909152015b60405180910390f35b620001fa620001f436600462003480565b620007dc565b604051908152602001620001da565b620002886200021a366004620034d8565b6002602081815260009384526040808520909152918352912080546001820154918301546fffffffffffffffffffffffffffffffff8216937001000000000000000000000000000000008304810b93730100000000000000000000000000000000000000909304900b919085565b604080516fffffffffffffffffffffffffffffffff9096168652600294850b60208701529290930b918401919091526060830152608082015260a001620001da565b620002e1620002db366004620034fb565b620007ff565b005b620001fa620002f43660046200351a565b62000ad2565b620002e16200030b3660046200343a565b62000aec565b620001fa7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39581565b620003506200034a3660046200357f565b62000c94565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001da565b620002e16200038736600462003669565b62001259565b620004406200039e36600462003697565b60016020819052600091825260409091208054918101546002909101546fffffffffffffffffffffffffffffffff808416937001000000000000000000000000000000009004169173ffffffffffffffffffffffffffffffffffffffff8082169274010000000000000000000000000000000000000000830462ffffff169277010000000000000000000000000000000000000000000000900460ff16911686565b604080516fffffffffffffffffffffffffffffffff978816815296909516602087015273ffffffffffffffffffffffffffffffffffffffff9384169486019490945262ffffff9091166060850152151560808401521660a082015260c001620001da565b620001fa60035481565b620002e1620004bf366004620036b1565b62001455565b620002e1620004d636600462003706565b62001526565b620001c9620004ed36600462003669565b620015f6565b620003507f000000000000000000000000000000000000000000000000000000000000000081565b620005326200052c36600462003697565b62001654565b6040519015158152602001620001da565b620001fa7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221981565b600054620003509073ffffffffffffffffffffffffffffffffffffffff1681565b620002e16200059d36600462003726565b62001673565b620001fa620005b436600462003746565b600460209081526000928352604080842090915290825290205481565b600054620005329074010000000000000000000000000000000000000000900460ff1681565b620002e162000608366004620036b1565b62001734565b620002e16200061f366004620036b1565b620017e0565b6000806200063262001b7c565b600080620006408762001ba3565b91509150600062000652878462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff166200067b8162001d6c565b6000806200068a838562001dd1565b809450819550829a50839b50505050506000600260008c8152602001908152602001600020600088815260200190815260200160002090508281600101819055508181600201819055506000600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050896000146200074d578c5173ffffffffffffffffffffffffffffffffffffffff16600090815260208290526040902080548b0190555b881562000784576020808e015173ffffffffffffffffffffffffffffffffffffffff166000908152908290526040902080548a0190555b604080518d8152602081018a90529081018b9052606081018a90527f15b2e0f32b50efdbbdee9ec7884ed3c61e6209b1b395e5762011a6734b86f7b59060800160405180910390a15050505050505050935093915050565b6000620007e862001b7c565b620007f68585858562001e74565b95945050505050565b6200082a7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b600080620008388362001ba3565b6001810154919350915077010000000000000000000000000000000000000000000000900460ff161562000898576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101805460028301547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff82167701000000000000000000000000000000000000000000000017909255604080517f51b42b00000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff928316939092169183916351b42b0091600480830192600092919082900301818387803b1580156200095257600080fd5b505af115801562000967573d6000803e3d6000fd5b505050506000808373ffffffffffffffffffffffffffffffffffffffff1663a88a5c166040518163ffffffff1660e01b81526004016040805180830381865afa158015620009b9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009df919062003791565b915091508082176fffffffffffffffffffffffffffffffff1660001462000a0f5762000a0f84600080896200209e565b6000546040517f2bd34c4800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015290911690632bd34c4890604401600060405180830381600087803b15801562000a8557600080fd5b505af115801562000a9a573d6000803e3d6000fd5b50506040518892507f907b91fb061b1c46367da11a5a0e8b2c0bd5fecd22eb92967e626cffa5ef63869150600090a250505050505050565b600062000ae28433858562001e74565b90505b9392505050565b62000af662001b7c565b600062000b688460408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b9050600062000b78848362001c7d565b9050600080600060149054906101000a900460ff1662000bd25762000bcc8388868862000bbb88600001516fffffffffffffffffffffffffffffffff1662002195565b62000bc690620037f4565b620021ac565b90925090505b6000868152600260208181526040808420888552825280842080547fffffffffffffffffffff000000000000000000000000000000000000000000001681556001810185905590920192909255885189830151825173ffffffffffffffffffffffffffffffffffffffff918216815289821694810194909452918301859052606083018490521690859088907f7f2557bb15dcf63e3d029ef1dcb4333563fcd78edf263b8fe42ed3adb925ff849060800160405180910390a450505050505050565b600062000cc17fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000846040015173ffffffffffffffffffffffffffffffffffffffff1663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d13573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d39919062003842565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158062000d8b575073ffffffffffffffffffffffffffffffffffffffff8116155b1562000dc3576040517f093d6f1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16631d4632ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000e27573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e4d919062003842565b73ffffffffffffffffffffffffffffffffffffffff161462000e9b576040517f47146bcc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b308160405162000eab90620032fd565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f08015801562000eec573d6000803e3d6000fd5b506000546040517fd68516bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8084166004830152848116602483015292945091169063d68516bc90604401600060405180830381600087803b15801562000f6557600080fd5b505af115801562000f7a573d6000803e3d6000fd5b50506003805492509050600062000f918362003862565b90915550606086015260006200100c8660408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b60008181526001602090815260409091208751918801519293509162001035918991846200234a565b6fffffffffffffffffffffffffffffffff9081166020890152168087526000036200108c576040517f36ab0f6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080860151621b13d062ffffff9091161315620010d5576040517f1db9891100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181018054608088015162ffffff811674010000000000000000000000000000000000000000027fffffffffffffffffff000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff80891691909117929092179092556002830180548683167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790556040808a01516020808c01518c5160608e01518d51938e01519551948716979287169691909116947fcef9468c62cd8a6eca3a887fc30674c037943e423de07ab3a122bdf2f73c77e1946200121b948d9490929173ffffffffffffffffffffffffffffffffffffffff95909516855260208501939093526fffffffffffffffffffffffffffffffff918216604085015216606083015262ffffff16608082015260a00190565b60405180910390a4620012398487600001518860200151856200251c565b6200124f8487604001518860600151856200209e565b5050509392505050565b6200126362001b7c565b60005474010000000000000000000000000000000000000000900460ff1615620012b9576040517f05bfeb5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000620012cd87876200260a565b93985091965094509250905080600080620012ea83888862002893565b915091506040518060a00160405280866fffffffffffffffffffffffffffffffff1681526020018860020b81526020018760020b815260200183815260200182815250600260008b815260200190815260200160002060008a815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160000160136101000a81548162ffffff021916908360020b62ffffff160217905550606082015181600101556080820151816002015590505087897f19bc21617a8d86ff19202ac9541480a99b9ae5fbd573a23f14f479af784392c4876040516200144191906fffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a350505050505050505050565b620014807fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000806200148e8562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff8585171615801590620014d85750620014d88262002940565b1562001510576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200151e818686866200209e565b505050505050565b620015517f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b801515600060149054906101000a900460ff161515036200157157600080fd5b6000805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517fee20b3d336390a4b077dbc7d702bf6e35a954bc96106f37b9e5ef08a1d0ce05990620015eb90831515815260200190565b60405180910390a150565b600080600080620016078662001ba3565b91509150600062001619868462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff1662001643818362001dd1565b50919a909950975050505050505050565b60008181526001602052604081206200166d9062002940565b92915050565b6200169e7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b60005473ffffffffffffffffffffffffffffffffffffffff90811690821603620016c757600080fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f29f9e1ebeee07596f3165f3e42cb9d4d8d22b0481e968d6c74be3dd037c15d9b91a250565b600080620017428562001ba3565b91509150620017518162002940565b1562001789576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff16620017b2868686856200234a565b90955093506fffffffffffffffffffffffffffffffff85851716156200151e576200151e818686866200251c565b6200180b7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b600080620018198562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff16620018448162001d6c565b6000808273ffffffffffffffffffffffffffffffffffffffff1663f0de82286040518163ffffffff1660e01b81526004016040805180830381865afa15801562001892573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018b8919062003791565b91509150816fffffffffffffffffffffffffffffffff16876fffffffffffffffffffffffffffffffff161115620018ed578196505b83546fffffffffffffffffffffffffffffffff90811690881610620019315783546200192e906001906fffffffffffffffffffffffffffffffff166200389d565b96505b8354620019529088906fffffffffffffffffffffffffffffffff166200389d565b84547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91821617855581811690871611156200199e578095505b8354620019d390879070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166200389d565b84546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161784556040517fca16ca7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063ca16ca7e9062001a74908a908a906004016fffffffffffffffffffffffffffffffff92831681529116602082015260400190565b600060405180830381600087803b15801562001a8f57600080fd5b505af115801562001aa4573d6000803e3d6000fd5b505050506fffffffffffffffffffffffffffffffff87161562001ae257875162001ae290336fffffffffffffffffffffffffffffffff8a16620029f6565b6fffffffffffffffffffffffffffffffff86161562001b1e5762001b1e886020015133886fffffffffffffffffffffffffffffffff16620029f6565b604080516fffffffffffffffffffffffffffffffff808a168252881660208201529081018690527f808ecc37f6d601dde1e43c133bee66af0ff9409b53aca0eb0d4f6c65fb8956e89060600160405180910390a15050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462001ba157600080fd5b565b60008062001c168360408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b6000818152600160205260408120805492945092506fffffffffffffffffffffffffffffffff909116900362001c78576040517fe4c8229200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b915091565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525060008281526002602081815260408084208585528252808420815160a08101835281546fffffffffffffffffffffffffffffffff81168083527001000000000000000000000000000000008204870b958301959095527301000000000000000000000000000000000000009004850b92810192909252600181015460608301529092015460808301529091036200166d576040517f7aa92c6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16636f4a2cd06040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001db557600080fd5b505af115801562001dca573d6000803e3d6000fd5b5050505050565b60008060008062001dec868660200151876040015162002893565b6060870151875192945090925062001e2c91908403906fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b62001e668660800151830387600001516fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b909790965091945092509050565b600073ffffffffffffffffffffffffffffffffffffffff831662001ec4576040517fabd1763600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff80841660009081526004602090815260408083209388168352908390529020549082158062001f0857508183115b1562001f12578192505b821562001fd05773ffffffffffffffffffffffffffffffffffffffff86166000908152602082905260409020838303905562001f50868585620029f6565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe6ac6a784fb43c9f6329d2f5c82f88a26a93bad4281f7780725af5f071f0aafa8660405162001fc791815260200190565b60405180910390a45b50949350505050565b6040517fe8ae2b69000000000000000000000000000000000000000000000000000000008152600481018290523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa1580156200206b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020919190620038d0565b6200209b57600080fd5b50565b6040517f7f463bb80000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff851690637f463bb890604401600060405180830381600087803b1580156200212057600080fd5b505af115801562002135573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f1864e4cc903d98e44820faebd48409c410a2ad20adb3173984ba41ae2828805e925060600190505b60405180910390a150505050565b80600f81900b8114620021a757600080fd5b919050565b600083815260016020819052604082209081015482919073ffffffffffffffffffffffffffffffffffffffff1682620021e58362002940565b620021ff57620021f9896040015162002c27565b62002271565b8173ffffffffffffffffffffffffffffffffffffffff16638e76c3326040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200224b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002271919062003903565b90506200227e8262001d6c565b6200228a828b62001dd1565b9050508095508196505050620022ac828b602001518c60400151898562002ce6565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260046020526040902085156200230557895173ffffffffffffffffffffffffffffffffffffffff1660009081526020829052604090208054870190555b84156200233c576020808b015173ffffffffffffffffffffffffffffffffffffffff16600090815290829052604090208054860190555b505050509550959350505050565b6000805481907501000000000000000000000000000000000000000000900460ff16620023a3576040517f2446d79f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690556fffffffffffffffffffffffffffffffff851615620023f5578551620023f2908662002d8c565b91505b6fffffffffffffffffffffffffffffffff84161562002421576200241e86602001518562002d8c565b90505b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017905582546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041662002499848362003921565b85547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91909116178555620024e1838262003921565b85546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161790945550909590945092505050565b6040517ffddf08e50000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff85169063fddf08e590604401600060405180830381600087803b1580156200259e57600080fd5b505af1158015620025b3573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f8b0312d8047895ce795779b66b705ccd39b1ece7c162f642c72d76a785d1b68a9250606001905062002187565b6000806000806000806200261e8862001ba3565b600089815260026020908152604080832085845290915290205491975091506fffffffffffffffffffffffffffffffff161562002687576040517ff352b37500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff8116925074010000000000000000000000000000000000000000900462ffffff16620026cd8262002940565b1562002705576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620027547f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b62002e26565b60408e0151929a50909850965090915073ffffffffffffffffffffffffffffffffffffffff808316911614620027b6576040517fdce2809300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846fffffffffffffffffffffffffffffffff1660000362002803576040517f4eed436000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8162ffffff168760020b8760020b0312156200284b576040517feab0585000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620028588262002c27565b9050620028858589896200287e8a6fffffffffffffffffffffffffffffffff1662002195565b8562002ce6565b505050509295509295909350565b6040517f0bd6f200000000000000000000000000000000000000000000000000000000008152600283810b600483015282900b6024820152600090819073ffffffffffffffffffffffffffffffffffffffff861690630bd6f200906044016040805180830381865afa1580156200290e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200293491906200394d565b91509150935093915050565b600181015460009073ffffffffffffffffffffffffffffffffffffffff81169077010000000000000000000000000000000000000000000000900460ff168062000ae5578173ffffffffffffffffffffffffffffffffffffffff1663556ed30e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620029d0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ae29190620038d0565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169162002a8f919062003972565b6000604051808303816000865af19150503d806000811462002ace576040519150601f19603f3d011682016040523d82523d6000602084013e62002ad3565b606091505b509150915081801562002b0157508051158062002b0157508080602001905181019062002b019190620038d0565b62001dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8587098281108382030391505080841162002bae57600080fd5b8060000362002bc35750829004905062000ae5565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff1663e76c01e46040518163ffffffff1660e01b815260040160c060405180830381865afa15801562002c76573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002c9c9190620039b6565b93965092945084935062002ce092505050576040517f9ded0f5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b6040517fd6b83ede000000000000000000000000000000000000000000000000000000008152600285810b600483015284810b6024830152600f84900b604483015282900b606482015273ffffffffffffffffffffffffffffffffffffffff86169063d6b83ede90608401600060405180830381600087803b15801562002d6c57600080fd5b505af115801562002d81573d6000803e3d6000fd5b505050505050505050565b60008062002d9a8462002f0c565b905062002dbc843330866fffffffffffffffffffffffffffffffff1662002fa0565b600062002dc98562002f0c565b905081811162002dd857600080fd5b8181036fffffffffffffffffffffffffffffffff811115620007f6576040517f3ba11f1e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000808773ffffffffffffffffffffffffffffffffffffffff166399fbab88886040518263ffffffff1660e01b815260040162002e6b91815260200190565b61016060405180830381865afa15801562002e8a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002eb0919062003a44565b50506040805180820190915273ffffffffffffffffffffffffffffffffffffffff808916825287166020820152949d50929b5090995093975091955062002eff94508d935091506200311b9050565b9550505093509350935093565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801562002f7a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200166d919062003b2c565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169162003041919062003972565b6000604051808303816000865af19150503d806000811462003080576040519150601f19603f3d011682016040523d82523d6000602084013e62003085565b606091505b5091509150818015620030b3575080511580620030b3575080806020019051810190620030b39190620038d0565b6200151e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015260640162002b64565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610620031bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964206f72646572206f6620746f6b656e73000000000000000000604482015260640162002b64565b8282600001518360200151604051602001620031fb92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290528051602091820120620032c0939290917ff96d2474815c32e070cd63233f06af5413efc5dcb430aee4ff18cc29007c562d91017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6123288062003b4783390190565b60405160a0810167ffffffffffffffff8111828210171562003356577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b73ffffffffffffffffffffffffffffffffffffffff811681146200209b57600080fd5b6000608082840312156200339257600080fd5b6040516080810181811067ffffffffffffffff82111715620033dd577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235620033f0816200335c565b8152602083013562003402816200335c565b6020820152604083013562003417816200335c565b6040820152606092830135920191909152919050565b8035620021a7816200335c565b600080600060c084860312156200345057600080fd5b6200345c85856200337f565b92506080840135915060a084013562003475816200335c565b809150509250925092565b600080600080608085870312156200349757600080fd5b8435620034a4816200335c565b93506020850135620034b6816200335c565b92506040850135620034c8816200335c565b9396929550929360600135925050565b60008060408385031215620034ec57600080fd5b50508035926020909101359150565b6000608082840312156200350e57600080fd5b62000ae583836200337f565b6000806000606084860312156200353057600080fd5b83356200353d816200335c565b925060208401356200354f816200335c565b929592945050506040919091013590565b6fffffffffffffffffffffffffffffffff811681146200209b57600080fd5b60008060008385036101408112156200359757600080fd5b620035a386866200337f565b935060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082011215620035d657600080fd5b50620035e16200330b565b6080850135620035f18162003560565b815260a0850135620036038162003560565b602082015260c0850135620036188162003560565b604082015260e08501356200362d8162003560565b606082015261010085013562ffffff811681146200364a57600080fd5b608082015291506200366061012085016200342d565b90509250925092565b60008060a083850312156200367d57600080fd5b6200368984846200337f565b946080939093013593505050565b600060208284031215620036aa57600080fd5b5035919050565b600080600060c08486031215620036c757600080fd5b620036d385856200337f565b92506080840135620036e58162003560565b915060a0840135620034758162003560565b80151581146200209b57600080fd5b6000602082840312156200371957600080fd5b813562000ae581620036f7565b6000602082840312156200373957600080fd5b813562000ae5816200335c565b600080604083850312156200375a57600080fd5b823562003767816200335c565b9150602083013562003779816200335c565b809150509250929050565b8051620021a78162003560565b60008060408385031215620037a557600080fd5b8251620037b28162003560565b6020840151909250620037798162003560565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600081600f0b7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081036200382c576200382c620037c5565b60000392915050565b8051620021a7816200335c565b6000602082840312156200385557600080fd5b815162000ae5816200335c565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620038965762003896620037c5565b5060010190565b6fffffffffffffffffffffffffffffffff828116828216039080821115620038c957620038c9620037c5565b5092915050565b600060208284031215620038e357600080fd5b815162000ae581620036f7565b8051600281900b8114620021a757600080fd5b6000602082840312156200391657600080fd5b62000ae582620038f0565b6fffffffffffffffffffffffffffffffff818116838216019080821115620038c957620038c9620037c5565b600080604083850312156200396157600080fd5b505080516020909101519092909150565b6000825160005b8181101562003995576020818601810151858301520162003979565b506000920191825250919050565b805161ffff81168114620021a757600080fd5b60008060008060008060c08789031215620039d057600080fd5b8651620039dd816200335c565b9550620039ed60208801620038f0565b9450620039fd60408801620039a3565b9350606087015160ff8116811462003a1457600080fd5b925062003a2460808801620039a3565b915060a087015162003a3681620036f7565b809150509295509295509295565b60008060008060008060008060008060006101608c8e03121562003a6757600080fd5b8b516affffffffffffffffffffff8116811462003a8357600080fd5b60208d0151909b5062003a96816200335c565b60408d0151909a5062003aa9816200335c565b985062003ab960608d0162003835565b975062003ac960808d01620038f0565b965062003ad960a08d01620038f0565b955062003ae960c08d0162003784565b945060e08c015193506101008c0151925062003b096101208d0162003784565b915062003b1a6101408d0162003784565b90509295989b509295989b9093969950565b60006020828403121562003b3f57600080fd5b505191905056fe60c0604052600160075560016008553480156200001b57600080fd5b506040516200232838038062002328833981810160405260408110156200004157600080fd5b508051602090910151620000566000620000d2565b6001600160a01b03828116608052811660a0526004805462ffffff63ffffffff60c81b011916600160c81b4263ffffffff160262ffffff19161762f27618179055620000a6620d89e719620001c8565b6004805462ffffff9290921663010000000265ffffff0000001990921691909117905550620001f99050565b620d89e719620000e281620001c8565b620d89e7196000818152602085905260409020600101805465ffffffffffff60801b1916600160981b62ffffff9485160262ffffff60801b191617600160801b9490931693909302919091179091556200013c81620001c8565b8260006200014e620d89e719620001c8565b60020b60020b81526020019081526020016000206001016010846000620d89e7196200017a90620001c8565b60020b81526020810191909152604001600020600101805462ffffff948516600160981b0262ffffff60981b1990911617905581549383166101009190910a90810292021990921617905550565b60008160020b627fffff198103620001f057634e487b7160e01b600052601160045260246000fd5b60000392915050565b60805160a0516120fb6200022d6000396000818161044101526107e801526000818161028c015261132401526120fb6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e76c332116100b2578063d6b83ede11610081578063f0de822811610066578063f0de822814610463578063f30dba9314610495578063fddf08e51461054c57600080fd5b8063d6b83ede14610401578063ef01df4f1461043c57600080fd5b80638e76c332146102d7578063a88a5c1614610315578063ca16ca7e14610384578063d576dfc0146103bb57600080fd5b8063556ed30e116101095780636f4a2cd0116100ee5780636f4a2cd0146102485780637f463bb8146102505780638a2ade581461028757600080fd5b8063556ed30e1461020f5780635e075b531461023d57600080fd5b80630bd6f2001461013b57806334d335901461017e57806346caf2ae146101ba57806351b42b0014610205575b600080fd5b6101656004803603604081101561015157600080fd5b508035600290810b9160200135900b610583565b6040805192835260208301919091528051918290030190f35b6101a66004803603604081101561019457600080fd5b50803560020b906020013515156107ce565b604080519115158252519081900360200190f35b6004546101e090660100000000000090046fffffffffffffffffffffffffffffffff1681565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61020d610c17565b005b6004546101a6907d010000000000000000000000000000000000000000000000000000000000900460ff1681565b600754600854610165565b61020d610c69565b61020d6004803603604081101561026657600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610c7b565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6004546102fe90760100000000000000000000000000000000000000000000900460020b81565b6040805160029290920b8252519081900360200190f35b6005546fffffffffffffffffffffffffffffffff808216917001000000000000000000000000000000009004165b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b61020d6004803603604081101561039a57600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610cdc565b6004546103e890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b6040805163ffffffff9092168252519081900360200190f35b61020d6004803603608081101561041757600080fd5b508035600290810b916020810135820b916040820135600f0b9160600135900b610cf4565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416610343565b610510600480360360208110156104ab57600080fd5b50600060208190529035600290810b8252604090912080546001820154828401546003909301549193600f82900b937001000000000000000000000000000000008304820b9373010000000000000000000000000000000000000090930490910b9186565b60408051968752600f9590950b6020870152600293840b868601529190920b6060850152608084019190915260a0830152519081900360c00190f35b61020d6004803603604081101561056257600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610f0c565b600282810b600090815260208190526040812060010154909182917001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b14806106205750600283810b6000908152602081905260409020600101547001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b145b15610657576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045460075460085463ffffffff79010000000000000000000000000000000000000000000000000084048116420393760100000000000000000000000000000000000000000000900460020b9291908416156107af57600454660100000000000090046fffffffffffffffffffffffffffffffff1680156107ad5760055460065463ffffffff87166fffffffffffffffffffffffffffffffff8084168202811693700100000000000000000000000000000000908190048216909202811692818116929004168184111561072a578193505b80831115610736578092505b831561076f5761076a84700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b870196505b82156107a8576107a383700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b860195505b505050505b505b6107be60008989868686610fd8565b95509550505050505b9250929050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461083f576040517f545acb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546fffffffffffffffffffffffffffffffff6601000000000000820416907601000000000000000000000000000000000000000000008104600290810b9163ffffffff7901000000000000000000000000000000000000000000000000008204169160ff7d0100000000000000000000000000000000000000000000000000000000008304169180820b916301000000909104900b82156108eb5760009650505050505050610c11565b600285810b908a900b1380159061091e578260020b8a60020b12610919576001975050505050505050610c11565b61093c565b8160020b8a60020b121561093c576001975050505050505050610c11565b881515811515146109a0575050600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000001790555060009450610c119350505050565b6109bc85886fffffffffffffffffffffffffffffffff16611076565b6007546008548a15610a8d575b600288900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761814610a88578460020b8c60020b1215610b3a57600285810b600090815260208190526040812060038101805482850180548803905585039055600101547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88019a50700100000000000000000000000000000000810490920b969550600f9190910b90610a80908b90839003611245565b9950506109c9565b610b3a565b6001610ab87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b610ac2919061200c565b60020b8860020b14610b3a578360020b8c60020b12610b3a57600284810b600090815260208190526040902060038101805482840180548703905584039055600101549498508895507301000000000000000000000000000000000000008504900b93600f0b610b328a82611245565b995050610a8d565b50506004805462ffffff9384166301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000858e16760100000000000000000000000000000000000000000000027fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff909c166601000000000000029b909b167fffffffffffffff00000000000000000000000000000000000000ffffffffffff90931692909217999099171693909216929092179590951790945550600193505050505b92915050565b610c1f61130c565b600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055565b610c7161130c565b610c7961137b565b565b610c8361130c565b610c8b61137b565b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000001617600555565b610ce461130c565b610cf0600083836113c7565b5050565b610cfc61130c565b6004546fffffffffffffffffffffffffffffffff66010000000000008204169063ffffffff7901000000000000000000000000000000000000000000000000008204169060ff7d0100000000000000000000000000000000000000000000000000000000008204169063010000008104600290810b91900b82610dd557610d848682846114a7565b610dd557600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055600192505b50508015610de557505050610f06565b600480547fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000062ffffff87160217905563ffffffff82164263ffffffff161115610e5d57610e5d82846fffffffffffffffffffffffffffffffff16611076565b84600f0b600014610f02576000610e7788868860006114cc565b90506000610e8888878960016114cc565b9050610e95868a8a6114a7565b15610edd57610ea48588611245565b600460066101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b8180610ee65750805b15610eff57610eff898984848a60008d600f0b126114f0565b50505b5050505b50505050565b610f1461130c565b610cf0600183836113c7565b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870982811083820303915050808411610f6057600080fd5b80600003610f7357508290049050610fd1565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290505b9392505050565b600285810b60009081526020889052604080822087840b8084529183209293849391929088900b121561104e578860020b8760020b1261102957816002015486039350816003015485039250611038565b81600201549350816003015492505b6002810154600382015494039390920391611069565b81600201548160020154039350816003015481600301540392505b5050965096945050505050565b63ffffffff4283900316600081900361108e57505050565b81156111f4576005546006546fffffffffffffffffffffffffffffffff8083168402927001000000000000000000000000000000009081900482168502928083169291900416818411156110f257816fffffffffffffffffffffffffffffffff1693505b806fffffffffffffffffffffffffffffffff1683111561112257806fffffffffffffffffffffffffffffffff1692505b838317156111ef576fffffffffffffffffffffffffffffffff91821684900391168290038315611172576111688470010000000000000000000000000000000088610f20565b6007805490910190555b821561119e576111948370010000000000000000000000000000000088610f20565b6008805490910190555b6fffffffffffffffffffffffffffffffff808316908216700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050505b5050600480547fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff167901000000000000000000000000000000000000000000000000004263ffffffff160217905550565b60008082600f0b12156112a957508082016fffffffffffffffffffffffffffffffff808416908216106112a4576040517f1301f74800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c11565b826fffffffffffffffffffffffffffffffff168284019150816fffffffffffffffffffffffffffffffff161015610c11576040517f997402f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c79576040517fae74b17800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454610c7990790100000000000000000000000000000000000000000000000000810463ffffffff1690660100000000000090046fffffffffffffffffffffffffffffffff16611076565b6113cf61137b565b6fffffffffffffffffffffffffffffffff82821716156114a2576006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416841561143957611426848361204d565b9150611432838261204d565b9050611452565b611443848361207d565b915061144f838261207d565b90505b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050565b60008260020b8460020b121580156114c457508160020b8460020b125b949350505050565b6007546008546000916114e79183918891889188918861161f565b95945050505050565b600454600154600282810b9263010000009004900b9063ffffffff16828282891561152b576115238c898386868c611753565b919450925090505b88156115475761153f8b898386868c611753565b919450925090505b8260020b8660020b14158061156257508160020b8560020b14155b8061157957508363ffffffff168163ffffffff1614155b1561161157600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8316179055600480547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016630100000062ffffff858116919091027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000016919091179085161790555b505050505050505050505050565b600286900b600090815260208890526040812080548261163f8289611245565b6fffffffffffffffffffffffffffffffff1690506d09745258e83de0d0f4e400fce79981111561169b576040517f25b8364a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830154600f0b856116bf5788600f0b81600f0b6116ba91906120a6565b6116d1565b88600f0b81600f0b6116d191906120ce565b6001850180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691909117905581845581159450600083900361174457841594508960020b8b60020b136117445760038401879055600284018890555b50505050979650505050505050565b6000806000831561179c5760008061176b818c611854565b915091508a60020b8860020b0361178457819750611795565b8a60020b8760020b03611795578096505b5050611832565b6000808a60020b8860020b1280156117b957508a60020b8760020b135b156117e257508690508560028a810b908c900b13156117da578a9650611822565b8a9750611822565b6117f0600360028b8e611aca565b600281810b6000908152602081905260409020600101547001000000000000000000000000000000009004900b925090505b61182f60008c8484611ba7565b50505b6000611842600360028a8d611d53565b969a9599509597509395505050505050565b600281810b60008181526020859052604081206001810180548383557fffffffffffffffffffff0000000000000000000000000000000000000000000081169091558185018390556003909101919091557001000000000000000000000000000000008104830b92730100000000000000000000000000000000000000909104900b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618148061193157506119287ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b156119d657600283900b6000908152602085905260409020600101805462ffffff808516700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff91851673010000000000000000000000000000000000000002919091167fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff909216919091171790556107c7565b8060020b8260020b03611a15576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282810b6000908152602086905260408082206001908101805462ffffff808816730100000000000000000000000000000000000000027fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff909216919091179091559385900b83529120018054918416700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff9092169190911790559250929050565b600190810190600090600883811d610d8a01901c90829061ffff83161b851663ffffffff1615611b2d57611afe8785611deb565b90945090925090508015611b135750506114c4565b611b2486610d8b840160010b611deb565b90945090925090505b80611b7057611b4b8563ffffffff168360010193508360010b611e1c565b909350905080611b635750620d89e891506114c49050565b611b6d8684611f73565b92505b611b9c877ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2768501611f73565b979650505050505050565b600283900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276181480611c065750611bfd7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b610f06578260020b8260020b128015611c2457508260020b8160020b135b611c5a576040517fe45ac17d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810b60009081526020959095526040808620600190810180547fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff1673010000000000000000000000000000000000000062ffffff87811682027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff908116939093177001000000000000000000000000000000008a831681029190911790945597860b8a52848a20840180547fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff1698909916908102979097179097559390920b865290942090930180549092169202919091179055565b81600080611d908785600881901d600181810b60009081526020949094526040909320805460ff9093169390931b80831890935591811490151891565b915091508115611de157610d8a01600181810b60081d80820b6000908152602089905260409020805460ff9094169290921b808418909255821591909214818118935014611de1576001811b831892505b5050949350505050565b600881901d600181900b6000908152602084905260408120548190611e109085611e1c565b93969095509293505050565b60008060ff831684811c808303611e38578460ff179350611f6a565b7f555555555555555555555555555555555555555555555555555555555555555560008290038216908116156fffffffffffffffffffffffffffffffff82161560071b1777ffffffffffffffff0000000000000000ffffffffffffffff82161560061b177bffffffff00000000ffffffff00000000ffffffff00000000ffffffff82161560051b177dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff82161560041b177eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff82161560031b177f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f82161560021b177f33333333333333333333333333333333333333333333333333333333333333339091161560011b1760ff1685019350600192505b50509250929050565b600181900b600090815260208390526040902054600882901b90611f979082611e1c565b509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361200357612003611f9f565b60000392915050565b600282810b9082900b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008112627fffff82131715610c1157610c11611f9f565b6fffffffffffffffffffffffffffffffff81811683821601908082111561207657612076611f9f565b5092915050565b6fffffffffffffffffffffffffffffffff82811682821603908082111561207657612076611f9f565b80820182811260008312801582168215821617156120c6576120c6611f9f565b505092915050565b818103600083128015838313168383128216171561207657612076611f9f56fea164736f6c6343000814000aa164736f6c6343000814000a', + deployedBytecode: + '0x60806040523480156200001157600080fd5b5060043610620001ad5760003560e01c80638433524111620000f5578063dd56e5d81162000097578063f2256319116200006e578063f225631914620005d1578063f26ebf7a14620005f7578063f6de3cae146200060e57600080fd5b8063dd56e5d8146200056b578063df42efda146200058c578063e70b9e2714620005a357600080fd5b8063b44a272211620000cc578063b44a272214620004f3578063b5bae00a146200051b578063b8883c50146200054357600080fd5b80638433524114620004ae578063890cdcb314620004c557806396da9bd514620004dc57600080fd5b806336808b19116200015f5780635739f0b911620001365780635739f0b9146200037657806360777795146200038d57806382bd79ea14620004a457600080fd5b806336808b1914620002fa5780633c6d07151462000311578063547b6da9146200033957600080fd5b806327e6a99a116200019457806327e6a99a14620002095780632912bf1014620002ca5780632f2d783d14620002e357600080fd5b8063046ec16614620001b25780630a53075414620001e3575b600080fd5b620001c9620001c33660046200343a565b62000625565b604080519283526020830191909152015b60405180910390f35b620001fa620001f436600462003480565b620007dc565b604051908152602001620001da565b620002886200021a366004620034d8565b6002602081815260009384526040808520909152918352912080546001820154918301546fffffffffffffffffffffffffffffffff8216937001000000000000000000000000000000008304810b93730100000000000000000000000000000000000000909304900b919085565b604080516fffffffffffffffffffffffffffffffff9096168652600294850b60208701529290930b918401919091526060830152608082015260a001620001da565b620002e1620002db366004620034fb565b620007ff565b005b620001fa620002f43660046200351a565b62000ad2565b620002e16200030b3660046200343a565b62000aec565b620001fa7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39581565b620003506200034a3660046200357f565b62000c94565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001da565b620002e16200038736600462003669565b62001259565b620004406200039e36600462003697565b60016020819052600091825260409091208054918101546002909101546fffffffffffffffffffffffffffffffff808416937001000000000000000000000000000000009004169173ffffffffffffffffffffffffffffffffffffffff8082169274010000000000000000000000000000000000000000830462ffffff169277010000000000000000000000000000000000000000000000900460ff16911686565b604080516fffffffffffffffffffffffffffffffff978816815296909516602087015273ffffffffffffffffffffffffffffffffffffffff9384169486019490945262ffffff9091166060850152151560808401521660a082015260c001620001da565b620001fa60035481565b620002e1620004bf366004620036b1565b62001455565b620002e1620004d636600462003706565b62001526565b620001c9620004ed36600462003669565b620015f6565b620003507f000000000000000000000000000000000000000000000000000000000000000081565b620005326200052c36600462003697565b62001654565b6040519015158152602001620001da565b620001fa7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221981565b600054620003509073ffffffffffffffffffffffffffffffffffffffff1681565b620002e16200059d36600462003726565b62001673565b620001fa620005b436600462003746565b600460209081526000928352604080842090915290825290205481565b600054620005329074010000000000000000000000000000000000000000900460ff1681565b620002e162000608366004620036b1565b62001734565b620002e16200061f366004620036b1565b620017e0565b6000806200063262001b7c565b600080620006408762001ba3565b91509150600062000652878462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff166200067b8162001d6c565b6000806200068a838562001dd1565b809450819550829a50839b50505050506000600260008c8152602001908152602001600020600088815260200190815260200160002090508281600101819055508181600201819055506000600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050896000146200074d578c5173ffffffffffffffffffffffffffffffffffffffff16600090815260208290526040902080548b0190555b881562000784576020808e015173ffffffffffffffffffffffffffffffffffffffff166000908152908290526040902080548a0190555b604080518d8152602081018a90529081018b9052606081018a90527f15b2e0f32b50efdbbdee9ec7884ed3c61e6209b1b395e5762011a6734b86f7b59060800160405180910390a15050505050505050935093915050565b6000620007e862001b7c565b620007f68585858562001e74565b95945050505050565b6200082a7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b600080620008388362001ba3565b6001810154919350915077010000000000000000000000000000000000000000000000900460ff161562000898576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101805460028301547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff82167701000000000000000000000000000000000000000000000017909255604080517f51b42b00000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff928316939092169183916351b42b0091600480830192600092919082900301818387803b1580156200095257600080fd5b505af115801562000967573d6000803e3d6000fd5b505050506000808373ffffffffffffffffffffffffffffffffffffffff1663a88a5c166040518163ffffffff1660e01b81526004016040805180830381865afa158015620009b9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009df919062003791565b915091508082176fffffffffffffffffffffffffffffffff1660001462000a0f5762000a0f84600080896200209e565b6000546040517f2bd34c4800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015290911690632bd34c4890604401600060405180830381600087803b15801562000a8557600080fd5b505af115801562000a9a573d6000803e3d6000fd5b50506040518892507f907b91fb061b1c46367da11a5a0e8b2c0bd5fecd22eb92967e626cffa5ef63869150600090a250505050505050565b600062000ae28433858562001e74565b90505b9392505050565b62000af662001b7c565b600062000b688460408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b9050600062000b78848362001c7d565b9050600080600060149054906101000a900460ff1662000bd25762000bcc8388868862000bbb88600001516fffffffffffffffffffffffffffffffff1662002195565b62000bc690620037f4565b620021ac565b90925090505b6000868152600260208181526040808420888552825280842080547fffffffffffffffffffff000000000000000000000000000000000000000000001681556001810185905590920192909255885189830151825173ffffffffffffffffffffffffffffffffffffffff918216815289821694810194909452918301859052606083018490521690859088907f7f2557bb15dcf63e3d029ef1dcb4333563fcd78edf263b8fe42ed3adb925ff849060800160405180910390a450505050505050565b600062000cc17fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000846040015173ffffffffffffffffffffffffffffffffffffffff1663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d13573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d39919062003842565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158062000d8b575073ffffffffffffffffffffffffffffffffffffffff8116155b1562000dc3576040517f093d6f1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16631d4632ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000e27573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e4d919062003842565b73ffffffffffffffffffffffffffffffffffffffff161462000e9b576040517f47146bcc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b308160405162000eab90620032fd565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f08015801562000eec573d6000803e3d6000fd5b506000546040517fd68516bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8084166004830152848116602483015292945091169063d68516bc90604401600060405180830381600087803b15801562000f6557600080fd5b505af115801562000f7a573d6000803e3d6000fd5b50506003805492509050600062000f918362003862565b90915550606086015260006200100c8660408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b60008181526001602090815260409091208751918801519293509162001035918991846200234a565b6fffffffffffffffffffffffffffffffff9081166020890152168087526000036200108c576040517f36ab0f6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080860151621b13d062ffffff9091161315620010d5576040517f1db9891100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181018054608088015162ffffff811674010000000000000000000000000000000000000000027fffffffffffffffffff000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff80891691909117929092179092556002830180548683167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790556040808a01516020808c01518c5160608e01518d51938e01519551948716979287169691909116947fcef9468c62cd8a6eca3a887fc30674c037943e423de07ab3a122bdf2f73c77e1946200121b948d9490929173ffffffffffffffffffffffffffffffffffffffff95909516855260208501939093526fffffffffffffffffffffffffffffffff918216604085015216606083015262ffffff16608082015260a00190565b60405180910390a4620012398487600001518860200151856200251c565b6200124f8487604001518860600151856200209e565b5050509392505050565b6200126362001b7c565b60005474010000000000000000000000000000000000000000900460ff1615620012b9576040517f05bfeb5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000620012cd87876200260a565b93985091965094509250905080600080620012ea83888862002893565b915091506040518060a00160405280866fffffffffffffffffffffffffffffffff1681526020018860020b81526020018760020b815260200183815260200182815250600260008b815260200190815260200160002060008a815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160000160136101000a81548162ffffff021916908360020b62ffffff160217905550606082015181600101556080820151816002015590505087897f19bc21617a8d86ff19202ac9541480a99b9ae5fbd573a23f14f479af784392c4876040516200144191906fffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a350505050505050505050565b620014807fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000806200148e8562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff8585171615801590620014d85750620014d88262002940565b1562001510576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200151e818686866200209e565b505050505050565b620015517f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b801515600060149054906101000a900460ff161515036200157157600080fd5b6000805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517fee20b3d336390a4b077dbc7d702bf6e35a954bc96106f37b9e5ef08a1d0ce05990620015eb90831515815260200190565b60405180910390a150565b600080600080620016078662001ba3565b91509150600062001619868462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff1662001643818362001dd1565b50919a909950975050505050505050565b60008181526001602052604081206200166d9062002940565b92915050565b6200169e7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b60005473ffffffffffffffffffffffffffffffffffffffff90811690821603620016c757600080fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f29f9e1ebeee07596f3165f3e42cb9d4d8d22b0481e968d6c74be3dd037c15d9b91a250565b600080620017428562001ba3565b91509150620017518162002940565b1562001789576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff16620017b2868686856200234a565b90955093506fffffffffffffffffffffffffffffffff85851716156200151e576200151e818686866200251c565b6200180b7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b600080620018198562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff16620018448162001d6c565b6000808273ffffffffffffffffffffffffffffffffffffffff1663f0de82286040518163ffffffff1660e01b81526004016040805180830381865afa15801562001892573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018b8919062003791565b91509150816fffffffffffffffffffffffffffffffff16876fffffffffffffffffffffffffffffffff161115620018ed578196505b83546fffffffffffffffffffffffffffffffff90811690881610620019315783546200192e906001906fffffffffffffffffffffffffffffffff166200389d565b96505b8354620019529088906fffffffffffffffffffffffffffffffff166200389d565b84547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91821617855581811690871611156200199e578095505b8354620019d390879070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166200389d565b84546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161784556040517fca16ca7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063ca16ca7e9062001a74908a908a906004016fffffffffffffffffffffffffffffffff92831681529116602082015260400190565b600060405180830381600087803b15801562001a8f57600080fd5b505af115801562001aa4573d6000803e3d6000fd5b505050506fffffffffffffffffffffffffffffffff87161562001ae257875162001ae290336fffffffffffffffffffffffffffffffff8a16620029f6565b6fffffffffffffffffffffffffffffffff86161562001b1e5762001b1e886020015133886fffffffffffffffffffffffffffffffff16620029f6565b604080516fffffffffffffffffffffffffffffffff808a168252881660208201529081018690527f808ecc37f6d601dde1e43c133bee66af0ff9409b53aca0eb0d4f6c65fb8956e89060600160405180910390a15050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462001ba157600080fd5b565b60008062001c168360408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b6000818152600160205260408120805492945092506fffffffffffffffffffffffffffffffff909116900362001c78576040517fe4c8229200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b915091565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525060008281526002602081815260408084208585528252808420815160a08101835281546fffffffffffffffffffffffffffffffff81168083527001000000000000000000000000000000008204870b958301959095527301000000000000000000000000000000000000009004850b92810192909252600181015460608301529092015460808301529091036200166d576040517f7aa92c6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16636f4a2cd06040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001db557600080fd5b505af115801562001dca573d6000803e3d6000fd5b5050505050565b60008060008062001dec868660200151876040015162002893565b6060870151875192945090925062001e2c91908403906fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b62001e668660800151830387600001516fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b909790965091945092509050565b600073ffffffffffffffffffffffffffffffffffffffff831662001ec4576040517fabd1763600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff80841660009081526004602090815260408083209388168352908390529020549082158062001f0857508183115b1562001f12578192505b821562001fd05773ffffffffffffffffffffffffffffffffffffffff86166000908152602082905260409020838303905562001f50868585620029f6565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe6ac6a784fb43c9f6329d2f5c82f88a26a93bad4281f7780725af5f071f0aafa8660405162001fc791815260200190565b60405180910390a45b50949350505050565b6040517fe8ae2b69000000000000000000000000000000000000000000000000000000008152600481018290523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa1580156200206b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020919190620038d0565b6200209b57600080fd5b50565b6040517f7f463bb80000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff851690637f463bb890604401600060405180830381600087803b1580156200212057600080fd5b505af115801562002135573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f1864e4cc903d98e44820faebd48409c410a2ad20adb3173984ba41ae2828805e925060600190505b60405180910390a150505050565b80600f81900b8114620021a757600080fd5b919050565b600083815260016020819052604082209081015482919073ffffffffffffffffffffffffffffffffffffffff1682620021e58362002940565b620021ff57620021f9896040015162002c27565b62002271565b8173ffffffffffffffffffffffffffffffffffffffff16638e76c3326040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200224b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002271919062003903565b90506200227e8262001d6c565b6200228a828b62001dd1565b9050508095508196505050620022ac828b602001518c60400151898562002ce6565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260046020526040902085156200230557895173ffffffffffffffffffffffffffffffffffffffff1660009081526020829052604090208054870190555b84156200233c576020808b015173ffffffffffffffffffffffffffffffffffffffff16600090815290829052604090208054860190555b505050509550959350505050565b6000805481907501000000000000000000000000000000000000000000900460ff16620023a3576040517f2446d79f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690556fffffffffffffffffffffffffffffffff851615620023f5578551620023f2908662002d8c565b91505b6fffffffffffffffffffffffffffffffff84161562002421576200241e86602001518562002d8c565b90505b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017905582546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041662002499848362003921565b85547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91909116178555620024e1838262003921565b85546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161790945550909590945092505050565b6040517ffddf08e50000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff85169063fddf08e590604401600060405180830381600087803b1580156200259e57600080fd5b505af1158015620025b3573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f8b0312d8047895ce795779b66b705ccd39b1ece7c162f642c72d76a785d1b68a9250606001905062002187565b6000806000806000806200261e8862001ba3565b600089815260026020908152604080832085845290915290205491975091506fffffffffffffffffffffffffffffffff161562002687576040517ff352b37500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff8116925074010000000000000000000000000000000000000000900462ffffff16620026cd8262002940565b1562002705576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620027547f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b62002e26565b60408e0151929a50909850965090915073ffffffffffffffffffffffffffffffffffffffff808316911614620027b6576040517fdce2809300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846fffffffffffffffffffffffffffffffff1660000362002803576040517f4eed436000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8162ffffff168760020b8760020b0312156200284b576040517feab0585000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620028588262002c27565b9050620028858589896200287e8a6fffffffffffffffffffffffffffffffff1662002195565b8562002ce6565b505050509295509295909350565b6040517f0bd6f200000000000000000000000000000000000000000000000000000000008152600283810b600483015282900b6024820152600090819073ffffffffffffffffffffffffffffffffffffffff861690630bd6f200906044016040805180830381865afa1580156200290e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200293491906200394d565b91509150935093915050565b600181015460009073ffffffffffffffffffffffffffffffffffffffff81169077010000000000000000000000000000000000000000000000900460ff168062000ae5578173ffffffffffffffffffffffffffffffffffffffff1663556ed30e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620029d0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ae29190620038d0565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169162002a8f919062003972565b6000604051808303816000865af19150503d806000811462002ace576040519150601f19603f3d011682016040523d82523d6000602084013e62002ad3565b606091505b509150915081801562002b0157508051158062002b0157508080602001905181019062002b019190620038d0565b62001dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8587098281108382030391505080841162002bae57600080fd5b8060000362002bc35750829004905062000ae5565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff1663e76c01e46040518163ffffffff1660e01b815260040160c060405180830381865afa15801562002c76573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002c9c9190620039b6565b93965092945084935062002ce092505050576040517f9ded0f5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b6040517fd6b83ede000000000000000000000000000000000000000000000000000000008152600285810b600483015284810b6024830152600f84900b604483015282900b606482015273ffffffffffffffffffffffffffffffffffffffff86169063d6b83ede90608401600060405180830381600087803b15801562002d6c57600080fd5b505af115801562002d81573d6000803e3d6000fd5b505050505050505050565b60008062002d9a8462002f0c565b905062002dbc843330866fffffffffffffffffffffffffffffffff1662002fa0565b600062002dc98562002f0c565b905081811162002dd857600080fd5b8181036fffffffffffffffffffffffffffffffff811115620007f6576040517f3ba11f1e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000808773ffffffffffffffffffffffffffffffffffffffff166399fbab88886040518263ffffffff1660e01b815260040162002e6b91815260200190565b61016060405180830381865afa15801562002e8a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002eb0919062003a44565b50506040805180820190915273ffffffffffffffffffffffffffffffffffffffff808916825287166020820152949d50929b5090995093975091955062002eff94508d935091506200311b9050565b9550505093509350935093565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801562002f7a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200166d919062003b2c565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169162003041919062003972565b6000604051808303816000865af19150503d806000811462003080576040519150601f19603f3d011682016040523d82523d6000602084013e62003085565b606091505b5091509150818015620030b3575080511580620030b3575080806020019051810190620030b39190620038d0565b6200151e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015260640162002b64565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610620031bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964206f72646572206f6620746f6b656e73000000000000000000604482015260640162002b64565b8282600001518360200151604051602001620031fb92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290528051602091820120620032c0939290917ff96d2474815c32e070cd63233f06af5413efc5dcb430aee4ff18cc29007c562d91017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6123288062003b4783390190565b60405160a0810167ffffffffffffffff8111828210171562003356577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b73ffffffffffffffffffffffffffffffffffffffff811681146200209b57600080fd5b6000608082840312156200339257600080fd5b6040516080810181811067ffffffffffffffff82111715620033dd577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235620033f0816200335c565b8152602083013562003402816200335c565b6020820152604083013562003417816200335c565b6040820152606092830135920191909152919050565b8035620021a7816200335c565b600080600060c084860312156200345057600080fd5b6200345c85856200337f565b92506080840135915060a084013562003475816200335c565b809150509250925092565b600080600080608085870312156200349757600080fd5b8435620034a4816200335c565b93506020850135620034b6816200335c565b92506040850135620034c8816200335c565b9396929550929360600135925050565b60008060408385031215620034ec57600080fd5b50508035926020909101359150565b6000608082840312156200350e57600080fd5b62000ae583836200337f565b6000806000606084860312156200353057600080fd5b83356200353d816200335c565b925060208401356200354f816200335c565b929592945050506040919091013590565b6fffffffffffffffffffffffffffffffff811681146200209b57600080fd5b60008060008385036101408112156200359757600080fd5b620035a386866200337f565b935060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082011215620035d657600080fd5b50620035e16200330b565b6080850135620035f18162003560565b815260a0850135620036038162003560565b602082015260c0850135620036188162003560565b604082015260e08501356200362d8162003560565b606082015261010085013562ffffff811681146200364a57600080fd5b608082015291506200366061012085016200342d565b90509250925092565b60008060a083850312156200367d57600080fd5b6200368984846200337f565b946080939093013593505050565b600060208284031215620036aa57600080fd5b5035919050565b600080600060c08486031215620036c757600080fd5b620036d385856200337f565b92506080840135620036e58162003560565b915060a0840135620034758162003560565b80151581146200209b57600080fd5b6000602082840312156200371957600080fd5b813562000ae581620036f7565b6000602082840312156200373957600080fd5b813562000ae5816200335c565b600080604083850312156200375a57600080fd5b823562003767816200335c565b9150602083013562003779816200335c565b809150509250929050565b8051620021a78162003560565b60008060408385031215620037a557600080fd5b8251620037b28162003560565b6020840151909250620037798162003560565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600081600f0b7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081036200382c576200382c620037c5565b60000392915050565b8051620021a7816200335c565b6000602082840312156200385557600080fd5b815162000ae5816200335c565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620038965762003896620037c5565b5060010190565b6fffffffffffffffffffffffffffffffff828116828216039080821115620038c957620038c9620037c5565b5092915050565b600060208284031215620038e357600080fd5b815162000ae581620036f7565b8051600281900b8114620021a757600080fd5b6000602082840312156200391657600080fd5b62000ae582620038f0565b6fffffffffffffffffffffffffffffffff818116838216019080821115620038c957620038c9620037c5565b600080604083850312156200396157600080fd5b505080516020909101519092909150565b6000825160005b8181101562003995576020818601810151858301520162003979565b506000920191825250919050565b805161ffff81168114620021a757600080fd5b60008060008060008060c08789031215620039d057600080fd5b8651620039dd816200335c565b9550620039ed60208801620038f0565b9450620039fd60408801620039a3565b9350606087015160ff8116811462003a1457600080fd5b925062003a2460808801620039a3565b915060a087015162003a3681620036f7565b809150509295509295509295565b60008060008060008060008060008060006101608c8e03121562003a6757600080fd5b8b516affffffffffffffffffffff8116811462003a8357600080fd5b60208d0151909b5062003a96816200335c565b60408d0151909a5062003aa9816200335c565b985062003ab960608d0162003835565b975062003ac960808d01620038f0565b965062003ad960a08d01620038f0565b955062003ae960c08d0162003784565b945060e08c015193506101008c0151925062003b096101208d0162003784565b915062003b1a6101408d0162003784565b90509295989b509295989b9093969950565b60006020828403121562003b3f57600080fd5b505191905056fe60c0604052600160075560016008553480156200001b57600080fd5b506040516200232838038062002328833981810160405260408110156200004157600080fd5b508051602090910151620000566000620000d2565b6001600160a01b03828116608052811660a0526004805462ffffff63ffffffff60c81b011916600160c81b4263ffffffff160262ffffff19161762f27618179055620000a6620d89e719620001c8565b6004805462ffffff9290921663010000000265ffffff0000001990921691909117905550620001f99050565b620d89e719620000e281620001c8565b620d89e7196000818152602085905260409020600101805465ffffffffffff60801b1916600160981b62ffffff9485160262ffffff60801b191617600160801b9490931693909302919091179091556200013c81620001c8565b8260006200014e620d89e719620001c8565b60020b60020b81526020019081526020016000206001016010846000620d89e7196200017a90620001c8565b60020b81526020810191909152604001600020600101805462ffffff948516600160981b0262ffffff60981b1990911617905581549383166101009190910a90810292021990921617905550565b60008160020b627fffff198103620001f057634e487b7160e01b600052601160045260246000fd5b60000392915050565b60805160a0516120fb6200022d6000396000818161044101526107e801526000818161028c015261132401526120fb6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e76c332116100b2578063d6b83ede11610081578063f0de822811610066578063f0de822814610463578063f30dba9314610495578063fddf08e51461054c57600080fd5b8063d6b83ede14610401578063ef01df4f1461043c57600080fd5b80638e76c332146102d7578063a88a5c1614610315578063ca16ca7e14610384578063d576dfc0146103bb57600080fd5b8063556ed30e116101095780636f4a2cd0116100ee5780636f4a2cd0146102485780637f463bb8146102505780638a2ade581461028757600080fd5b8063556ed30e1461020f5780635e075b531461023d57600080fd5b80630bd6f2001461013b57806334d335901461017e57806346caf2ae146101ba57806351b42b0014610205575b600080fd5b6101656004803603604081101561015157600080fd5b508035600290810b9160200135900b610583565b6040805192835260208301919091528051918290030190f35b6101a66004803603604081101561019457600080fd5b50803560020b906020013515156107ce565b604080519115158252519081900360200190f35b6004546101e090660100000000000090046fffffffffffffffffffffffffffffffff1681565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61020d610c17565b005b6004546101a6907d010000000000000000000000000000000000000000000000000000000000900460ff1681565b600754600854610165565b61020d610c69565b61020d6004803603604081101561026657600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610c7b565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6004546102fe90760100000000000000000000000000000000000000000000900460020b81565b6040805160029290920b8252519081900360200190f35b6005546fffffffffffffffffffffffffffffffff808216917001000000000000000000000000000000009004165b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b61020d6004803603604081101561039a57600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610cdc565b6004546103e890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b6040805163ffffffff9092168252519081900360200190f35b61020d6004803603608081101561041757600080fd5b508035600290810b916020810135820b916040820135600f0b9160600135900b610cf4565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416610343565b610510600480360360208110156104ab57600080fd5b50600060208190529035600290810b8252604090912080546001820154828401546003909301549193600f82900b937001000000000000000000000000000000008304820b9373010000000000000000000000000000000000000090930490910b9186565b60408051968752600f9590950b6020870152600293840b868601529190920b6060850152608084019190915260a0830152519081900360c00190f35b61020d6004803603604081101561056257600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610f0c565b600282810b600090815260208190526040812060010154909182917001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b14806106205750600283810b6000908152602081905260409020600101547001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b145b15610657576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045460075460085463ffffffff79010000000000000000000000000000000000000000000000000084048116420393760100000000000000000000000000000000000000000000900460020b9291908416156107af57600454660100000000000090046fffffffffffffffffffffffffffffffff1680156107ad5760055460065463ffffffff87166fffffffffffffffffffffffffffffffff8084168202811693700100000000000000000000000000000000908190048216909202811692818116929004168184111561072a578193505b80831115610736578092505b831561076f5761076a84700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b870196505b82156107a8576107a383700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b860195505b505050505b505b6107be60008989868686610fd8565b95509550505050505b9250929050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461083f576040517f545acb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546fffffffffffffffffffffffffffffffff6601000000000000820416907601000000000000000000000000000000000000000000008104600290810b9163ffffffff7901000000000000000000000000000000000000000000000000008204169160ff7d0100000000000000000000000000000000000000000000000000000000008304169180820b916301000000909104900b82156108eb5760009650505050505050610c11565b600285810b908a900b1380159061091e578260020b8a60020b12610919576001975050505050505050610c11565b61093c565b8160020b8a60020b121561093c576001975050505050505050610c11565b881515811515146109a0575050600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000001790555060009450610c119350505050565b6109bc85886fffffffffffffffffffffffffffffffff16611076565b6007546008548a15610a8d575b600288900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761814610a88578460020b8c60020b1215610b3a57600285810b600090815260208190526040812060038101805482850180548803905585039055600101547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88019a50700100000000000000000000000000000000810490920b969550600f9190910b90610a80908b90839003611245565b9950506109c9565b610b3a565b6001610ab87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b610ac2919061200c565b60020b8860020b14610b3a578360020b8c60020b12610b3a57600284810b600090815260208190526040902060038101805482840180548703905584039055600101549498508895507301000000000000000000000000000000000000008504900b93600f0b610b328a82611245565b995050610a8d565b50506004805462ffffff9384166301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000858e16760100000000000000000000000000000000000000000000027fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff909c166601000000000000029b909b167fffffffffffffff00000000000000000000000000000000000000ffffffffffff90931692909217999099171693909216929092179590951790945550600193505050505b92915050565b610c1f61130c565b600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055565b610c7161130c565b610c7961137b565b565b610c8361130c565b610c8b61137b565b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000001617600555565b610ce461130c565b610cf0600083836113c7565b5050565b610cfc61130c565b6004546fffffffffffffffffffffffffffffffff66010000000000008204169063ffffffff7901000000000000000000000000000000000000000000000000008204169060ff7d0100000000000000000000000000000000000000000000000000000000008204169063010000008104600290810b91900b82610dd557610d848682846114a7565b610dd557600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055600192505b50508015610de557505050610f06565b600480547fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000062ffffff87160217905563ffffffff82164263ffffffff161115610e5d57610e5d82846fffffffffffffffffffffffffffffffff16611076565b84600f0b600014610f02576000610e7788868860006114cc565b90506000610e8888878960016114cc565b9050610e95868a8a6114a7565b15610edd57610ea48588611245565b600460066101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b8180610ee65750805b15610eff57610eff898984848a60008d600f0b126114f0565b50505b5050505b50505050565b610f1461130c565b610cf0600183836113c7565b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870982811083820303915050808411610f6057600080fd5b80600003610f7357508290049050610fd1565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290505b9392505050565b600285810b60009081526020889052604080822087840b8084529183209293849391929088900b121561104e578860020b8760020b1261102957816002015486039350816003015485039250611038565b81600201549350816003015492505b6002810154600382015494039390920391611069565b81600201548160020154039350816003015481600301540392505b5050965096945050505050565b63ffffffff4283900316600081900361108e57505050565b81156111f4576005546006546fffffffffffffffffffffffffffffffff8083168402927001000000000000000000000000000000009081900482168502928083169291900416818411156110f257816fffffffffffffffffffffffffffffffff1693505b806fffffffffffffffffffffffffffffffff1683111561112257806fffffffffffffffffffffffffffffffff1692505b838317156111ef576fffffffffffffffffffffffffffffffff91821684900391168290038315611172576111688470010000000000000000000000000000000088610f20565b6007805490910190555b821561119e576111948370010000000000000000000000000000000088610f20565b6008805490910190555b6fffffffffffffffffffffffffffffffff808316908216700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050505b5050600480547fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff167901000000000000000000000000000000000000000000000000004263ffffffff160217905550565b60008082600f0b12156112a957508082016fffffffffffffffffffffffffffffffff808416908216106112a4576040517f1301f74800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c11565b826fffffffffffffffffffffffffffffffff168284019150816fffffffffffffffffffffffffffffffff161015610c11576040517f997402f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c79576040517fae74b17800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454610c7990790100000000000000000000000000000000000000000000000000810463ffffffff1690660100000000000090046fffffffffffffffffffffffffffffffff16611076565b6113cf61137b565b6fffffffffffffffffffffffffffffffff82821716156114a2576006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416841561143957611426848361204d565b9150611432838261204d565b9050611452565b611443848361207d565b915061144f838261207d565b90505b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050565b60008260020b8460020b121580156114c457508160020b8460020b125b949350505050565b6007546008546000916114e79183918891889188918861161f565b95945050505050565b600454600154600282810b9263010000009004900b9063ffffffff16828282891561152b576115238c898386868c611753565b919450925090505b88156115475761153f8b898386868c611753565b919450925090505b8260020b8660020b14158061156257508160020b8560020b14155b8061157957508363ffffffff168163ffffffff1614155b1561161157600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8316179055600480547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016630100000062ffffff858116919091027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000016919091179085161790555b505050505050505050505050565b600286900b600090815260208890526040812080548261163f8289611245565b6fffffffffffffffffffffffffffffffff1690506d09745258e83de0d0f4e400fce79981111561169b576040517f25b8364a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830154600f0b856116bf5788600f0b81600f0b6116ba91906120a6565b6116d1565b88600f0b81600f0b6116d191906120ce565b6001850180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691909117905581845581159450600083900361174457841594508960020b8b60020b136117445760038401879055600284018890555b50505050979650505050505050565b6000806000831561179c5760008061176b818c611854565b915091508a60020b8860020b0361178457819750611795565b8a60020b8760020b03611795578096505b5050611832565b6000808a60020b8860020b1280156117b957508a60020b8760020b135b156117e257508690508560028a810b908c900b13156117da578a9650611822565b8a9750611822565b6117f0600360028b8e611aca565b600281810b6000908152602081905260409020600101547001000000000000000000000000000000009004900b925090505b61182f60008c8484611ba7565b50505b6000611842600360028a8d611d53565b969a9599509597509395505050505050565b600281810b60008181526020859052604081206001810180548383557fffffffffffffffffffff0000000000000000000000000000000000000000000081169091558185018390556003909101919091557001000000000000000000000000000000008104830b92730100000000000000000000000000000000000000909104900b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618148061193157506119287ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b156119d657600283900b6000908152602085905260409020600101805462ffffff808516700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff91851673010000000000000000000000000000000000000002919091167fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff909216919091171790556107c7565b8060020b8260020b03611a15576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282810b6000908152602086905260408082206001908101805462ffffff808816730100000000000000000000000000000000000000027fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff909216919091179091559385900b83529120018054918416700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff9092169190911790559250929050565b600190810190600090600883811d610d8a01901c90829061ffff83161b851663ffffffff1615611b2d57611afe8785611deb565b90945090925090508015611b135750506114c4565b611b2486610d8b840160010b611deb565b90945090925090505b80611b7057611b4b8563ffffffff168360010193508360010b611e1c565b909350905080611b635750620d89e891506114c49050565b611b6d8684611f73565b92505b611b9c877ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2768501611f73565b979650505050505050565b600283900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276181480611c065750611bfd7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b610f06578260020b8260020b128015611c2457508260020b8160020b135b611c5a576040517fe45ac17d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810b60009081526020959095526040808620600190810180547fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff1673010000000000000000000000000000000000000062ffffff87811682027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff908116939093177001000000000000000000000000000000008a831681029190911790945597860b8a52848a20840180547fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff1698909916908102979097179097559390920b865290942090930180549092169202919091179055565b81600080611d908785600881901d600181810b60009081526020949094526040909320805460ff9093169390931b80831890935591811490151891565b915091508115611de157610d8a01600181810b60081d80820b6000908152602089905260409020805460ff9094169290921b808418909255821591909214818118935014611de1576001811b831892505b5050949350505050565b600881901d600181900b6000908152602084905260408120548190611e109085611e1c565b93969095509293505050565b60008060ff831684811c808303611e38578460ff179350611f6a565b7f555555555555555555555555555555555555555555555555555555555555555560008290038216908116156fffffffffffffffffffffffffffffffff82161560071b1777ffffffffffffffff0000000000000000ffffffffffffffff82161560061b177bffffffff00000000ffffffff00000000ffffffff00000000ffffffff82161560051b177dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff82161560041b177eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff82161560031b177f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f82161560021b177f33333333333333333333333333333333333333333333333333333333333333339091161560011b1760ff1685019350600192505b50509250929050565b600181900b600090815260208390526040902054600882901b90611f979082611e1c565b509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361200357612003611f9f565b60000392915050565b600282810b9082900b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008112627fffff82131715610c1157610c11611f9f565b6fffffffffffffffffffffffffffffffff81811683821601908082111561207657612076611f9f565b5092915050565b6fffffffffffffffffffffffffffffffff82811682821603908082111561207657612076611f9f565b80820182811260008312801582168215821617156120c6576120c6611f9f565b505092915050565b818103600083128015838313168383128216171561207657612076611f9f56fea164736f6c6343000814000aa164736f6c6343000814000a', + linkReferences: {}, + deployedLinkReferences: {}, +}; diff --git a/src/abis/farming/farmingCenter.ts b/src/abis/farming/farmingCenter.ts new file mode 100644 index 0000000..a72bffd --- /dev/null +++ b/src/abis/farming/farmingCenter.ts @@ -0,0 +1,392 @@ +export const farmingCenter = [ + { + inputs: [ + { + internalType: 'contract IAlgebraEternalFarming', + name: '_eternalFarming', + type: 'address', + }, + { + internalType: 'contract INonfungiblePositionManager', + name: '_nonfungiblePositionManager', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'liquidityDelta', + type: 'int256', + }, + ], + name: 'applyLiquidityDelta', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'burnPosition', + outputs: [ + { + internalType: 'bool', + name: 'success', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountRequested', + type: 'uint256', + }, + ], + name: 'claimReward', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'collectRewards', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'address', + name: 'newVirtualPool', + type: 'address', + }, + ], + name: 'connectVirtualPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityDelta', + type: 'uint256', + }, + ], + name: 'decreaseLiquidity', + outputs: [ + { + internalType: 'bool', + name: 'success', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'deposits', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'enterFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'eternalFarming', + outputs: [ + { + internalType: 'contract IAlgebraEternalFarming', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'exitFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'incentiveKeys', + outputs: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityDelta', + type: 'uint256', + }, + ], + name: 'increaseLiquidity', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes[]', + name: 'data', + type: 'bytes[]', + }, + ], + name: 'multicall', + outputs: [ + { + internalType: 'bytes[]', + name: 'results', + type: 'bytes[]', + }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'nonfungiblePositionManager', + outputs: [ + { + internalType: 'contract INonfungiblePositionManager', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'virtualPoolAddresses', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/abis/farming/index.ts b/src/abis/farming/index.ts new file mode 100644 index 0000000..e520655 --- /dev/null +++ b/src/abis/farming/index.ts @@ -0,0 +1,2 @@ +export * from './algebraEternalFarming'; +export * from './farmingCenter'; diff --git a/src/abis/index.ts b/src/abis/index.ts index 7cab5c8..c95f0b2 100644 --- a/src/abis/index.ts +++ b/src/abis/index.ts @@ -1,7 +1,8 @@ -export * from './algebraFactory' -export * from './algebraPool' -export * from './algebraPositionManager' -export * from './algebraQuoter' -export * from './algebraQuoterV2' -export * from './algebraRouter' -export * from './plugins' \ No newline at end of file +export * from './algebraFactory'; +export * from './algebraPool'; +export * from './algebraPositionManager'; +export * from './algebraQuoter'; +export * from './algebraQuoterV2'; +export * from './algebraRouter'; +export * from './plugins'; +export * from './farming'; diff --git a/src/constants/addresses.ts b/src/constants/addresses.ts index 4d5bc5a..85d4b34 100644 --- a/src/constants/addresses.ts +++ b/src/constants/addresses.ts @@ -1,15 +1,28 @@ -import { Address } from "viem"; +import { Address } from 'viem'; -export const POOL_INIT_CODE_HASH: Address = '0xf96d2474815c32e070cd63233f06af5413efc5dcb430aee4ff18cc29007c562d' +export const POOL_INIT_CODE_HASH: Address = + '0xf96d2474815c32e070cd63233f06af5413efc5dcb430aee4ff18cc29007c562d'; -export const ALGEBRA_FACTORY: Address = '0x6AD6A4f233F1E33613e996CCc17409B93fF8bf5f' +export const ALGEBRA_FACTORY: Address = + '0x6AD6A4f233F1E33613e996CCc17409B93fF8bf5f'; -export const ALGEBRA_POOL_DEPLOYER: Address = '0x69D57B9D705eaD73a5d2f2476C30c55bD755cc2F' +export const ALGEBRA_POOL_DEPLOYER: Address = + '0x69D57B9D705eaD73a5d2f2476C30c55bD755cc2F'; -export const ALGEBRA_POSITION_MANAGER: Address = '0x5AeFBA317BAba46EAF98Fd6f381d07673bcA6467' +export const ALGEBRA_POSITION_MANAGER: Address = + '0x5AeFBA317BAba46EAF98Fd6f381d07673bcA6467'; -export const ALGEBRA_QUOTER: Address = '0x38A5C36FA8c8c9E4649b51FCD61810B14e7ce047' +export const ALGEBRA_QUOTER: Address = + '0x38A5C36FA8c8c9E4649b51FCD61810B14e7ce047'; -export const ALGEBRA_QUOTER_V2: Address = '0x83D4a9Ea77a4dbA073cD90b30410Ac9F95F93E7C' +export const ALGEBRA_QUOTER_V2: Address = + '0x83D4a9Ea77a4dbA073cD90b30410Ac9F95F93E7C'; -export const ALGEBRA_ROUTER: Address = '0xEC250E6856e14A494cb1f0abC61d72348c79F418' \ No newline at end of file +export const ALGEBRA_ROUTER: Address = + '0xEC250E6856e14A494cb1f0abC61d72348c79F418'; + +export const ALGEBRA_ETERNAL_FARMING: Address = + '0x49a390a3dFd2d01389f799965F3af5961f87d228'; + +export const FARMING_CENTER: Address = + '0x37A4950b4ea0C46596404895c5027B088B0e70e7'; From 9d4dc009ed2482860117cf8ed659d4f340c2cf68 Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 4 Mar 2024 19:41:58 +0300 Subject: [PATCH 02/47] add: farming client to graphql --- .env | 1 + codegen.ts | 36 ++++++++++++++++++--------------- src/graphql/clients/index.tsx | 11 +++++++--- src/hooks/graphql/useClients.ts | 11 +++++----- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/.env b/.env index e081d02..0afcd55 100644 --- a/.env +++ b/.env @@ -1,5 +1,6 @@ VITE_INFO_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/integral-core VITE_LIMIT_ORDERS_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/integral-limit-order VITE_BLOCKS_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/goerli-blocks +VITE_FARMING_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/farming-test VITE_INFURA_RPC=https://1rpc.io/holesky VITE_WALLETCONNECT_PROJECT_ID=79c313a96c99edbc26d06cd97bff1126 \ No newline at end of file diff --git a/codegen.ts b/codegen.ts index 77dbfa1..a6ff6e8 100644 --- a/codegen.ts +++ b/codegen.ts @@ -1,22 +1,26 @@ - import type { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { - overwrite: true, - schema: [ - "https://api.thegraph.com/subgraphs/name/iliaazhel/integral-core", - "https://api.thegraph.com/subgraphs/name/iliaazhel/goerli-blocks" - ], - documents: "src/graphql/queries/!(*.d).{ts,tsx}", - generates: { - "src/graphql/generated/graphql.tsx": { - plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'], - config: { - withHooks: true, - withResultType: true - } - } - } + overwrite: true, + schema: [ + 'https://api.thegraph.com/subgraphs/name/iliaazhel/integral-core', + 'https://api.thegraph.com/subgraphs/name/iliaazhel/goerli-blocks', + 'https://api.thegraph.com/subgraphs/name/iliaazhel/farming-test', + ], + documents: 'src/graphql/queries/!(*.d).{ts,tsx}', + generates: { + 'src/graphql/generated/graphql.tsx': { + plugins: [ + 'typescript', + 'typescript-operations', + 'typescript-react-apollo', + ], + config: { + withHooks: true, + withResultType: true, + }, + }, + }, }; export default config; diff --git a/src/graphql/clients/index.tsx b/src/graphql/clients/index.tsx index 9d7d20f..b556446 100644 --- a/src/graphql/clients/index.tsx +++ b/src/graphql/clients/index.tsx @@ -1,4 +1,4 @@ -import { ApolloClient, InMemoryCache } from "@apollo/client"; +import { ApolloClient, InMemoryCache } from '@apollo/client'; export const infoClient = new ApolloClient({ uri: import.meta.env.VITE_INFO_GRAPH, @@ -7,5 +7,10 @@ export const infoClient = new ApolloClient({ export const blocksClient = new ApolloClient({ uri: import.meta.env.VITE_BLOCKS_GRAPH, - cache: new InMemoryCache() -}) + cache: new InMemoryCache(), +}); + +export const farmingClient = new ApolloClient({ + uri: import.meta.env.VITE_FARMING_GRAPH, + cache: new InMemoryCache(), +}); diff --git a/src/hooks/graphql/useClients.ts b/src/hooks/graphql/useClients.ts index 2b27fb6..39a447a 100644 --- a/src/hooks/graphql/useClients.ts +++ b/src/hooks/graphql/useClients.ts @@ -1,10 +1,9 @@ -import { infoClient, blocksClient } from "@/graphql/clients"; +import { infoClient, blocksClient, farmingClient } from '@/graphql/clients'; export function useClients() { - return { infoClient, - blocksClient - } - -} \ No newline at end of file + blocksClient, + farmingClient, + }; +} From e023117728e804935ad9718e3e474ce14a2922e4 Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 4 Mar 2024 19:43:23 +0300 Subject: [PATCH 03/47] add: farming queries in pool page --- src/graphql/queries/farmings.ts | 20 ++ src/main.tsx | 106 +++++---- src/pages/Pool/index.tsx | 382 +++++++++++++++++++++----------- src/pages/Pools/index.tsx | 39 ++-- 4 files changed, 348 insertions(+), 199 deletions(-) create mode 100644 src/graphql/queries/farmings.ts diff --git a/src/graphql/queries/farmings.ts b/src/graphql/queries/farmings.ts new file mode 100644 index 0000000..f24495e --- /dev/null +++ b/src/graphql/queries/farmings.ts @@ -0,0 +1,20 @@ +import { gql } from '@apollo/client'; + +export const ETERNAL_FARMINGS = gql` + query EternalFarmings($pool: Bytes) { + eternalFarmings(where: { pool: $pool }) { + id + reward + bonusReward + rewardRate + bonusRewardRate + rewardToken + bonusRewardToken + isDeactivated + nonce + minRangeLength + virtualPool + pool + } + } +`; diff --git a/src/main.tsx b/src/main.tsx index bae56fe..29866e1 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,56 +1,76 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' +import React from 'react'; +import ReactDOM from 'react-dom/client'; import { - createBrowserRouter, - Navigate, - RouterProvider, -} from "react-router-dom"; + createBrowserRouter, + Navigate, + RouterProvider, +} from 'react-router-dom'; -import App from './App.tsx' +import App from './App.tsx'; -import './index.css' +import './index.css'; -import SwapPage from "@/pages/Swap"; -import Page404 from "@/pages/Page404"; -import PoolsPage from "@/pages/Pools"; -import PoolPage from "@/pages/Pool"; -import NewPositionPage from "@/pages/NewPosition"; +import SwapPage from '@/pages/Swap'; +import Page404 from '@/pages/Page404'; +import PoolsPage from '@/pages/Pools'; +import PoolPage from '@/pages/Pool'; +import NewPositionPage from '@/pages/NewPosition'; -import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client"; +import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; const router = createBrowserRouter([ - { - path: "/", - element: , - errorElement: - }, - { - path: '/swap', - element: , - }, - { - path: '/pools', - element: - }, - { - path: '/pool/:pool', - element: - }, - { - path: '/pool/:pool/new-position', - element: - } + { + path: '/', + element: , + errorElement: , + }, + { + path: '/swap', + element: ( + + {' '} + {' '} + + ), + }, + { + path: '/pools', + element: ( + + {' '} + {' '} + + ), + }, + { + path: '/pool/:pool', + element: ( + + {' '} + {' '} + + ), + }, + { + path: '/pool/:pool/new-position', + element: ( + + {' '} + {' '} + + ), + }, ]); const client = new ApolloClient({ - uri: import.meta.env.VITE_INFO_GRAPH, - cache: new InMemoryCache(), + uri: import.meta.env.VITE_INFO_GRAPH, + cache: new InMemoryCache(), }); ReactDOM.createRoot(document.getElementById('root')!).render( - - - - - , -) + + + + + +); diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index de247dd..51f17ff 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -1,189 +1,301 @@ -import PageContainer from "@/components/common/PageContainer" -import MyPositions from "@/components/pool/MyPositions" -import MyPositionsToolbar from "@/components/pool/MyPositionsToolbar" -import PoolHeader from "@/components/pool/PoolHeader" -import PositionCard from "@/components/position/PositionCard" -import { Button } from "@/components/ui/button" -import { Skeleton } from "@/components/ui/skeleton" -import { useNativePriceQuery, usePoolFeeDataQuery, useSinglePoolQuery } from "@/graphql/generated/graphql" -import { usePool } from "@/hooks/pools/usePool" -import { usePositions } from "@/hooks/positions/usePositions" -import { FormattedPosition } from "@/types/formatted-position" -import { getPositionAPR } from "@/utils/positions/getPositionAPR" -import { getPositionFees } from "@/utils/positions/getPositionFees" -import { Position } from "@cryptoalgebra/integral-sdk" -import { useWeb3Modal } from "@web3modal/wagmi/react" -import { MoveRightIcon } from "lucide-react" -import { useEffect, useMemo, useState } from "react" -import { Link, useParams } from "react-router-dom" -import { Address, useAccount } from "wagmi" - +import PageContainer from '@/components/common/PageContainer'; +import MyPositions from '@/components/pool/MyPositions'; +import MyPositionsToolbar from '@/components/pool/MyPositionsToolbar'; +import PoolHeader from '@/components/pool/PoolHeader'; +import PositionCard from '@/components/position/PositionCard'; +import { Button } from '@/components/ui/button'; +import { Skeleton } from '@/components/ui/skeleton'; +import { FARMING_CENTER } from '@/constants/addresses'; +import { + useEternalFarmingQuery, + useEternalFarmingsQuery, + useNativePriceQuery, + usePoolFeeDataQuery, + useSinglePoolQuery, + useSingleTokenQuery, +} from '@/graphql/generated/graphql'; +import { ETERNAL_FARMINGS } from '@/graphql/queries/farmings'; +import { useClients } from '@/hooks/graphql/useClients'; +import { usePool } from '@/hooks/pools/usePool'; +import { usePositions } from '@/hooks/positions/usePositions'; +import { FormattedPosition } from '@/types/formatted-position'; +import { getPositionAPR } from '@/utils/positions/getPositionAPR'; +import { getPositionFees } from '@/utils/positions/getPositionFees'; +import { Position } from '@cryptoalgebra/integral-sdk'; +import { useWeb3Modal } from '@web3modal/wagmi/react'; +import { MoveRightIcon } from 'lucide-react'; +import { useEffect, useMemo, useState } from 'react'; +import { Link, useParams } from 'react-router-dom'; +import { Address, useAccount, useQuery } from 'wagmi'; const PoolPage = () => { + const { address: account } = useAccount(); - const { address: account } = useAccount() - - const { pool: poolId } = useParams() as { pool: Address } + const { pool: poolId } = useParams() as { pool: Address }; - const [selectedPositionId, selectPosition] = useState() + const [selectedPositionId, selectPosition] = useState(); - const [, poolEntity] = usePool(poolId) + const [, poolEntity] = usePool(poolId); const { data: poolInfo } = useSinglePoolQuery({ variables: { - poolId - } - }) + poolId, + }, + }); const { data: poolFeeData } = usePoolFeeDataQuery({ variables: { - poolId - } - }) + poolId, + }, + }); - const { data: bundles } = useNativePriceQuery() + const { data: bundles } = useNativePriceQuery(); - const [positionsFees, setPositionsFees] = useState() - const [positionsAPRs, setPositionsAPRs] = useState() + const [positionsFees, setPositionsFees] = useState(); + const [positionsAPRs, setPositionsAPRs] = useState(); - const { positions, loading: positionsLoading } = usePositions() + const { positions, loading: positionsLoading } = usePositions(); const filteredPositions = useMemo(() => { - - if (!positions || !poolEntity) return [] - - return positions.filter(({ pool }) => pool.toLowerCase() === poolId.toLowerCase()).map(position => ({ - positionId: position.tokenId, - position: new Position({ - pool: poolEntity, - liquidity: position.liquidity.toString(), - tickLower: Number(position.tickLower), - tickUpper: Number(position.tickUpper) - }) - })) - - }, [positions, poolEntity]) + if (!positions || !poolEntity) return []; + + return positions + .filter(({ pool }) => pool.toLowerCase() === poolId.toLowerCase()) + .map((position) => ({ + positionId: position.tokenId, + position: new Position({ + pool: poolEntity, + liquidity: position.liquidity.toString(), + tickLower: Number(position.tickLower), + tickUpper: Number(position.tickUpper), + }), + })); + }, [positions, poolEntity]); useEffect(() => { - async function getPositionsFees() { - const fees = await Promise.all(filteredPositions.map(({ positionId, position }) => getPositionFees(position.pool, positionId))) - setPositionsFees(fees) + const fees = await Promise.all( + filteredPositions.map(({ positionId, position }) => + getPositionFees(position.pool, positionId) + ) + ); + setPositionsFees(fees); } - if (filteredPositions) getPositionsFees() - - }, [filteredPositions]) + if (filteredPositions) getPositionsFees(); + }, [filteredPositions]); useEffect(() => { - async function getPositionsAPRs() { - const nativePrice = bundles?.bundles[0].maticPriceUSD - const aprs = await Promise.all(filteredPositions.map(({ position }) => getPositionAPR(poolId, position, poolInfo?.pool, poolFeeData?.poolDayDatas, nativePrice))) - setPositionsAPRs(aprs) + const nativePrice = bundles?.bundles[0].maticPriceUSD; + const aprs = await Promise.all( + filteredPositions.map(({ position }) => + getPositionAPR( + poolId, + position, + poolInfo?.pool, + poolFeeData?.poolDayDatas, + nativePrice + ) + ) + ); + setPositionsAPRs(aprs); } - if (filteredPositions && poolInfo?.pool && poolFeeData?.poolDayDatas && bundles?.bundles && poolId) getPositionsAPRs() - - }, [filteredPositions, poolInfo, poolId, poolFeeData, bundles]) + if ( + filteredPositions && + poolInfo?.pool && + poolFeeData?.poolDayDatas && + bundles?.bundles && + poolId + ) + getPositionsAPRs(); + }, [filteredPositions, poolInfo, poolId, poolFeeData, bundles]); const formatLiquidityUSD = (position: Position) => { - if (!poolInfo?.pool) return 0 + if (!poolInfo?.pool) return 0; - const amount0USD = Number(position.amount0.toSignificant()) * Number(poolInfo.pool.token1Price) - const amount1USD = Number(position.amount1.toSignificant()) * Number(poolInfo.pool.token0Price) + const amount0USD = + Number(position.amount0.toSignificant()) * + Number(poolInfo.pool.token1Price); + const amount1USD = + Number(position.amount1.toSignificant()) * + Number(poolInfo.pool.token0Price); - return amount0USD + amount1USD - } + return amount0USD + amount1USD; + }; const formatFeesUSD = (idx: number) => { - if (!positionsFees || !positionsFees[idx] || !poolInfo?.pool) return 0 + if (!positionsFees || !positionsFees[idx] || !poolInfo?.pool) return 0; - const fees0USD = positionsFees[idx][0] ? Number(positionsFees[idx][0].toSignificant()) * Number(poolInfo.pool.token0Price) : 0 - const fees1USD = positionsFees[idx][1] ? Number(positionsFees[idx][1].toSignificant()) * Number(poolInfo.pool.token1Price) : 0 + const fees0USD = positionsFees[idx][0] + ? Number(positionsFees[idx][0].toSignificant()) * + Number(poolInfo.pool.token0Price) + : 0; + const fees1USD = positionsFees[idx][1] + ? Number(positionsFees[idx][1].toSignificant()) * + Number(poolInfo.pool.token1Price) + : 0; - return fees0USD + fees1USD - } + return fees0USD + fees1USD; + }; const formatAPR = (idx: number) => { - if (!positionsAPRs || !positionsAPRs[idx]) return 0 - return positionsAPRs[idx] - } + if (!positionsAPRs || !positionsAPRs[idx]) return 0; + return positionsAPRs[idx]; + }; const positionsData = useMemo(() => { - - if (!filteredPositions || !poolEntity) return [] - - return filteredPositions.map(({ positionId, position }, idx) => ({ - id: positionId, - outOfRange: poolEntity.tickCurrent < position.tickLower || poolEntity.tickCurrent > position.tickUpper, - range: `${position.token0PriceLower.toFixed()} — ${position.token0PriceUpper.toFixed()}`, - liquidityUSD: formatLiquidityUSD(position), - feesUSD: formatFeesUSD(idx), - apr: formatAPR(idx) - }) as FormattedPosition) - - }, [filteredPositions, poolEntity, poolInfo, positionsFees, positionsAPRs]) + if (!filteredPositions || !poolEntity) return []; + + return filteredPositions.map( + ({ positionId, position }, idx) => + ({ + id: positionId, + outOfRange: + poolEntity.tickCurrent < position.tickLower || + poolEntity.tickCurrent > position.tickUpper, + range: `${position.token0PriceLower.toFixed()} — ${position.token0PriceUpper.toFixed()}`, + liquidityUSD: formatLiquidityUSD(position), + feesUSD: formatFeesUSD(idx), + apr: formatAPR(idx), + } as FormattedPosition) + ); + }, [filteredPositions, poolEntity, poolInfo, positionsFees, positionsAPRs]); const selectedPosition = useMemo(() => { + if (!positionsData || !selectedPositionId) return; - if (!positionsData || !selectedPositionId) return + return positionsData.find( + ({ id }) => Number(id) === Number(selectedPositionId) + ); + }, [selectedPositionId, positionsData]); - return positionsData.find(({ id }) => Number(id) === Number(selectedPositionId)) + const noPositions = + !positionsLoading && positionsData.length === 0 && poolEntity; - }, [selectedPositionId, positionsData]) + /* FARMING FEATURE */ + const [farmingData, setFarmingData] = useState(null); - const noPositions = !positionsLoading && positionsData.length === 0 && poolEntity + const { farmingClient } = useClients(); - return + const { data: farmings } = useEternalFarmingsQuery({ + variables: { + pool: poolId, + }, + client: farmingClient, + }); - + const { data: rewardToken } = useSingleTokenQuery({ + variables: { + tokenId: farmings?.eternalFarmings?.[0]?.rewardToken, + }, + }); -
+ const { data: bonusRewardToken } = useSingleTokenQuery({ + variables: { + tokenId: farmings?.eternalFarmings?.[0]?.bonusRewardToken, + }, + }); -
- { - !account ? : positionsLoading ? : noPositions ? : <> - - selectPosition(prev => prev === positionId ? null : positionId)} /> - - } -
+ useEffect(() => { + if (!farmings) return; + if (farmings.eternalFarmings.length === 0) return; + if (!rewardToken || !bonusRewardToken) return; + if (!poolInfo) return; + const farming = farmings.eternalFarmings[0]; + setFarmingData({ + farming, + rewardToken: rewardToken, + bonusRewardToken: bonusRewardToken, + pool: poolInfo, + }); + }, [farmings, rewardToken, bonusRewardToken, poolInfo]); -
- + useEffect(() => { + console.log(farmingData); + }, [farmingData]); + + /* FARMING FEATURE */ + + return ( + + + +
+
+ {!account ? ( + + ) : positionsLoading ? ( + + ) : noPositions ? ( + + ) : ( + <> + + + selectPosition((prev) => + prev === positionId ? null : positionId + ) + } + /> + + )} +
+ +
+ +
- -
- - -} - -const NoPositions = ({ poolId }: { poolId: Address }) =>
-

You don't have positions for this pool

-

Let's create one!

- -
+ + ); +}; + +const NoPositions = ({ poolId }: { poolId: Address }) => ( +
+

+ You don't have positions for this pool +

+

Let's create one!

+ +
+); const NoAccount = () => { - - const { open } = useWeb3Modal() - - return
-

Connect Wallet

-

Connect your account to view or create positions

- + const { open } = useWeb3Modal(); + + return ( +
+

Connect Wallet

+

+ Connect your account to view or create positions +

+ +
+ ); +}; + +const LoadingState = () => ( +
+ {[1, 2, 3, 4].map((v) => ( + + ))}
-} - -const LoadingState = () =>
- {[1, 2, 3, 4].map(v => )} -
- +); -export default PoolPage \ No newline at end of file +export default PoolPage; diff --git a/src/pages/Pools/index.tsx b/src/pages/Pools/index.tsx index b318fb6..7d8270b 100644 --- a/src/pages/Pools/index.tsx +++ b/src/pages/Pools/index.tsx @@ -1,26 +1,23 @@ -import PageContainer from "@/components/common/PageContainer" -import PageTitle from "@/components/common/PageTitle" -import PoolsList from "@/components/pools/PoolsList" -import { CreatePoolModal } from "@/components/modals/CreatePoolModal" +import PageContainer from '@/components/common/PageContainer'; +import PageTitle from '@/components/common/PageTitle'; +import PoolsList from '@/components/pools/PoolsList'; +import { CreatePoolModal } from '@/components/modals/CreatePoolModal'; const PoolsPage = () => { - - - return - -
- - -
- -
-
- + return ( + +
+ +
-
- - -} +
+
+ +
+
+ + ); +}; -export default PoolsPage \ No newline at end of file +export default PoolsPage; From 3a8687d052a2cc273688c6323387f3152b8a2805 Mon Sep 17 00:00:00 2001 From: damnnou Date: Tue, 5 Mar 2024 18:12:57 +0300 Subject: [PATCH 04/47] add: farming deposits query --- src/graphql/queries/farmings.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/graphql/queries/farmings.ts b/src/graphql/queries/farmings.ts index f24495e..16c0987 100644 --- a/src/graphql/queries/farmings.ts +++ b/src/graphql/queries/farmings.ts @@ -18,3 +18,29 @@ export const ETERNAL_FARMINGS = gql` } } `; + +export const DEPOSITS = gql` + query Deposits($owner: Bytes, $pool: Bytes) { + deposits(where: { owner: $owner, pool: $pool }) { + eternalFarming + id + liquidity + owner + pool + rangeLength + } + } +`; + +export const DEPOSIT = gql` + query Deposit($id: ID!) { + deposit(id: $id) { + id + liquidity + owner + pool + rangeLength + eternalFarming + } + } +`; From 05ca4763fb535c88bf78d475b8cce674911f74eb Mon Sep 17 00:00:00 2001 From: damnnou Date: Tue, 5 Mar 2024 18:13:48 +0300 Subject: [PATCH 05/47] add: create select position modal farming --- .../modals/SelectPositionFarmModal/index.tsx | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/components/modals/SelectPositionFarmModal/index.tsx diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx new file mode 100644 index 0000000..391f521 --- /dev/null +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -0,0 +1,51 @@ +import Loader from '@/components/common/Loader'; +import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/ui/dialog'; +import { Deposit } from '@/graphql/generated/graphql'; + +interface SelectPositionFarmModalProps { + positions: Deposit[]; +} + +export function SelectPositionFarmModal({ + positions, +}: SelectPositionFarmModalProps) { + return ( + + + + + + + + Select Position + + + +
    + {positions && + positions.map((position) => ( +
  • +

    {position.id}.

    +

    {position.liquidity / 10 ** 18}

    +
  • + ))} +
+
+
+ ); +} From 0d5e3af1dc4aaed52984ad27c6366df108787b28 Mon Sep 17 00:00:00 2001 From: damnnou Date: Tue, 5 Mar 2024 18:15:11 +0300 Subject: [PATCH 06/47] add: create farming util isSameReward --- src/utils/farming/isSameRewards.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/utils/farming/isSameRewards.ts diff --git a/src/utils/farming/isSameRewards.ts b/src/utils/farming/isSameRewards.ts new file mode 100644 index 0000000..d96a5f0 --- /dev/null +++ b/src/utils/farming/isSameRewards.ts @@ -0,0 +1,5 @@ +import { EternalFarming } from '@/graphql/generated/graphql'; + +export const isSameRewards = (farming: EternalFarming) => { + return farming.rewardToken === farming.bonusRewardToken ? true : false; +}; From 34824a0a6ddcf4f23a95a36ced527795c8d1c7e4 Mon Sep 17 00:00:00 2001 From: damnnou Date: Tue, 5 Mar 2024 18:16:47 +0300 Subject: [PATCH 07/47] refactor: create farming components, refactor queries --- src/components/pool/ActiveFarming/index.tsx | 52 +++ src/components/pool/ClosedFarmings/index.tsx | 25 ++ src/components/pool/FarmRewards/index.tsx | 11 + src/components/pool/Farmings/index.tsx | 120 +++++++ src/hooks/farming/useFarmIntegralActions.ts | 320 +++++++++++++++++++ src/pages/Pool/index.tsx | 58 +--- 6 files changed, 538 insertions(+), 48 deletions(-) create mode 100644 src/components/pool/ActiveFarming/index.tsx create mode 100644 src/components/pool/ClosedFarmings/index.tsx create mode 100644 src/components/pool/FarmRewards/index.tsx create mode 100644 src/components/pool/Farmings/index.tsx create mode 100644 src/hooks/farming/useFarmIntegralActions.ts diff --git a/src/components/pool/ActiveFarming/index.tsx b/src/components/pool/ActiveFarming/index.tsx new file mode 100644 index 0000000..2259aab --- /dev/null +++ b/src/components/pool/ActiveFarming/index.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; +import { Farming } from '../Farmings'; +import { isSameRewards } from '@/utils/farming/isSameRewards'; +import { Deposit } from '@/graphql/generated/graphql'; + +interface ActiveFarmingProps { + farming: Farming; + deposits: Deposit[]; +} + +const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => { + const isSameReward = farming ? isSameRewards(farming?.farming) : false; + + return ( +
+ Active Farm +
+

APR -

+ {isSameReward ? ( + <> +

+ Token - {farming?.rewardToken?.name} +

+

+ Reward Pool - {farming?.farming?.reward / 10 ** 18} +

+ + ) : ( + <> +

+ Token - {farming?.rewardToken?.name} +

+

+ Reward - {farming?.farming?.reward / 10 ** 18} +

+

+ Bonus Token - {farming?.bonusRewardToken?.name} +

+

+ Bonus Reward -{' '} + {farming?.farming?.bonusReward / 10 ** 18} +

+ + )} +
+ +
+ ); +}; + +export default ActiveFarming; diff --git a/src/components/pool/ClosedFarmings/index.tsx b/src/components/pool/ClosedFarmings/index.tsx new file mode 100644 index 0000000..fc89860 --- /dev/null +++ b/src/components/pool/ClosedFarmings/index.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Farming } from '../Farmings'; +import { EternalFarming } from '@/graphql/generated/graphql'; + +interface ActiveFarmingProps { + farmings: EternalFarming[]; +} + +const ClosedFarmings = ({ farmings }: ActiveFarmingProps) => { + console.log(farmings); + return ( +
+ Closed Farmings +
    + {farmings && + farmings.length > 0 && + farmings.map((farm) => ( +
  • {farm.id.slice(0, 12)}
  • + ))} +
+
+ ); +}; + +export default ClosedFarmings; diff --git a/src/components/pool/FarmRewards/index.tsx b/src/components/pool/FarmRewards/index.tsx new file mode 100644 index 0000000..d65e849 --- /dev/null +++ b/src/components/pool/FarmRewards/index.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +const FarmRewards = () => { + return ( +
+ Farm Rewards +
+ ); +}; + +export default FarmRewards; diff --git a/src/components/pool/Farmings/index.tsx b/src/components/pool/Farmings/index.tsx new file mode 100644 index 0000000..503429c --- /dev/null +++ b/src/components/pool/Farmings/index.tsx @@ -0,0 +1,120 @@ +import React, { useEffect, useState } from 'react'; +import MyPositions from '../MyPositions'; +import { + useEternalFarmingsQuery, + useSingleTokenQuery, + useDepositsQuery, + SinglePoolQuery, + Deposit, + EternalFarming, + SingleTokenQuery, +} from '@/graphql/generated/graphql'; +import { useClients } from '@/hooks/graphql/useClients'; +import { Address, useAccount } from 'wagmi'; +import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; +import { isSameRewards } from '@/utils/farming/isSameRewards'; +import { Token } from 'graphql'; +import ActiveFarming from '../ActiveFarming'; +import FarmRewards from '../FarmRewards'; +import ClosedFarmings from '../ClosedFarmings'; + +interface FarmingsProps { + poolId: Address; + poolInfo: SinglePoolQuery; +} + +export interface Farming { + farming: EternalFarming; + rewardToken: SingleTokenQuery['token']; + bonusRewardToken: SingleTokenQuery['token']; + pool: SinglePoolQuery; +} + +const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { + const { address: account } = useAccount(); + + const [farmingInfo, setFarmingInfo] = useState(); + + const { farmingClient } = useClients(); + + const { data: farmings, loading: isLoading } = useEternalFarmingsQuery({ + variables: { + pool: poolId, + }, + client: farmingClient, + }); + + const activeFarming = farmings?.eternalFarmings.filter( + (farming) => !farming.isDeactivated + )[0]; + + const closedFarmings = farmings?.eternalFarmings.filter( + (farming) => farming.isDeactivated + ); + + const { data: rewardToken } = useSingleTokenQuery({ + variables: { + tokenId: activeFarming?.rewardToken, + }, + }); + + const { data: bonusRewardToken } = useSingleTokenQuery({ + variables: { + tokenId: activeFarming?.bonusRewardToken, + }, + }); + + useEffect(() => { + if (!farmings?.eternalFarmings || farmings.eternalFarmings.length === 0) + return; + if (!rewardToken || !bonusRewardToken || !poolInfo) return; + + if (!activeFarming) { + console.error('Active farming not found'); + } + + setFarmingInfo({ + farming: { ...activeFarming }, + rewardToken: { ...rewardToken.token }, + bonusRewardToken: { ...bonusRewardToken.token }, + ...poolInfo, + }); + }, [farmings, rewardToken, bonusRewardToken, poolInfo]); + + useEffect(() => { + console.log(farmingInfo); + }, [farmingInfo]); + + // All positions for current pool + const { data: deposits } = useDepositsQuery({ + variables: { + owner: account, + pool: poolId, + }, + client: farmingClient, + }); + + // useEffect(() => { + // if (!deposits) return; + // console.log(deposits); + // }, [deposits]); + + return ( +
+ {isLoading ? ( +
Loading...
+ ) : ( + <> + + + + + )} +
+ ); +}; + +export default Farmings; diff --git a/src/hooks/farming/useFarmIntegralActions.ts b/src/hooks/farming/useFarmIntegralActions.ts new file mode 100644 index 0000000..2bb7213 --- /dev/null +++ b/src/hooks/farming/useFarmIntegralActions.ts @@ -0,0 +1,320 @@ +interface FarmIntegralActionContainerChildrenProps { + onApprove: () => void; + onStake: () => void; + onUnstake: () => void; + onHarvest: () => void; + onHarvestAll: (calldatas: string[]) => void; +} + +const useFarmIntegralActions = ({ + tokenId, + rewardToken, + bonusRewardToken, + pool, + nonce, +}: { + tokenId: string; + rewardToken: string; + bonusRewardToken: string; + pool: string; + nonce: string; +}): FarmIntegralActionContainerChildrenProps => { + const { t } = useTranslation(); + const { toastSuccess } = useToast(); + const { address: account } = useAccount(); + const signer = useEthersSigner(); + + const gasPrice = useGasPrice(); + const { loading, fetchWithCatchTxError } = useCatchTxError(); + + const algebraFarmingCenter = useAlgebraFarmingCenterContract(); + const algebraPositionManager = useAlgebraPositionManagerContract(); + + const onApprove = useCallback(async () => { + const calldata = algebraPositionManager.interface.encodeFunctionData( + 'approveForFarming', + [tokenId, true, algebraFarmingCenter.address] + ); + + const txn = { + to: algebraPositionManager.address, + data: calldata, + }; + + const resp = await fetchWithCatchTxError(() => + signer.estimateGas(txn).then((estimate) => { + const newTxn = { + ...txn, + gasPrice, + gasLimit: calculateGasMargin(estimate), + }; + + return signer.sendTransaction(newTxn); + }) + ); + if (resp?.status) { + toastSuccess( + `${t('Approved')}!`, + + {t('Position was approved for farming')} + + ); + } + }, [ + account, + fetchWithCatchTxError, + signer, + t, + algebraPositionManager, + algebraFarmingCenter, + toastSuccess, + tokenId, + ]); + + const onUnstake = useCallback(async () => { + const callDatas = [ + algebraFarmingCenter.interface.encodeFunctionData('exitFarming', [ + { rewardToken, bonusRewardToken, pool, nonce }, + tokenId, + ]), + algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ + rewardToken, + account, + MaxUint128, + ]), + algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ + bonusRewardToken, + account, + MaxUint128, + ]), + ]; + + const calldata = algebraFarmingCenter.interface.encodeFunctionData( + 'multicall', + [callDatas] + ); + + const txn = { + to: algebraFarmingCenter.address, + data: calldata, + }; + + const resp = await fetchWithCatchTxError(() => + signer.estimateGas(txn).then((estimate) => { + const newTxn = { + ...txn, + gasPrice, + gasLimit: calculateGasMargin(estimate), + }; + + return signer.sendTransaction(newTxn); + }) + ); + if (resp?.status) { + toastSuccess( + `${t('Unstaked')}!`, + + {t('Your earnings have also been harvested to your wallet')} + + ); + } + }, [ + account, + fetchWithCatchTxError, + algebraFarmingCenter, + signer, + t, + toastSuccess, + rewardToken, + tokenId, + ]); + + const onStake = useCallback(async () => { + const calldata = algebraFarmingCenter.interface.encodeFunctionData( + 'enterFarming', + [ + { + rewardToken, + bonusRewardToken, + pool, + nonce, + }, + tokenId, + ] + ); + + const txn = { + to: algebraFarmingCenter.address, + data: calldata, + }; + + const resp = await fetchWithCatchTxError(() => + signer.estimateGas(txn).then((estimate) => { + const newTxn = { + ...txn, + gasPrice, + gasLimit: calculateGasMargin(estimate), + }; + + return signer.sendTransaction(newTxn); + }) + ); + + if (resp?.status) { + toastSuccess( + `${t('Staked')}!`, + + {t('Your funds have been staked in the farm')} + + ); + } + }, [ + account, + fetchWithCatchTxError, + algebraFarmingCenter, + signer, + t, + toastSuccess, + rewardToken, + tokenId, + ]); + + const onHarvest = useCallback(async () => { + const collectRewards = + algebraFarmingCenter.interface.encodeFunctionData( + 'collectRewards', + [{ rewardToken, bonusRewardToken, pool, nonce }, tokenId] + ); + const claimReward1 = algebraFarmingCenter.interface.encodeFunctionData( + 'claimReward', + [rewardToken, account, MaxUint128] + ); + const claimReward2 = algebraFarmingCenter.interface.encodeFunctionData( + 'claimReward', + [bonusRewardToken, account, MaxUint128] + ); + + let calldata; + + if (rewardToken.toLowerCase() !== bonusRewardToken.toLowerCase()) { + calldata = [collectRewards, claimReward1, claimReward2]; + } else { + calldata = [collectRewards, claimReward1]; + } + + const mcall = algebraFarmingCenter.interface.encodeFunctionData( + 'multicall', + [calldata] + ); + + const txn = { + to: algebraFarmingCenter.address, + data: mcall, + }; + + const resp = await fetchWithCatchTxError(() => + signer.estimateGas(txn).then((estimate) => { + const newTxn = { + ...txn, + gasPrice, + gasLimit: calculateGasMargin(estimate), + }; + + return signer.sendTransaction(newTxn); + }) + ); + + if (resp?.status) { + toastSuccess( + `${t('Harvested')}!`, + + {t('Earnings have been sent to your wallet!')} + + ); + // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) + } + }, [ + account, + fetchWithCatchTxError, + algebraFarmingCenter, + signer, + t, + toastSuccess, + rewardToken, + tokenId, + ]); + + const onHarvestAll = useCallback( + async (calldatas: string[]) => { + const calldata = algebraFarmingCenter.interface.encodeFunctionData( + 'multicall', + [calldatas] + ); + + const txn = { + to: algebraFarmingCenter.address, + data: calldata, + }; + + const resp = await fetchWithCatchTxError(() => + signer.estimateGas(txn).then((estimate) => { + const newTxn = { + ...txn, + gasPrice, + gasLimit: calculateGasMargin(estimate), + }; + + return signer.sendTransaction(newTxn); + }) + ); + + if (resp?.status) { + toastSuccess( + `${t('Harvested')}!`, + + {t('Earnings have been sent to your wallet!')} + + ); + // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) + } + }, + [ + account, + fetchWithCatchTxError, + algebraFarmingCenter, + signer, + t, + toastSuccess, + rewardToken, + tokenId, + ] + ); + + return { + attemptingTxn: loading, + onApprove, + onStake, + onUnstake, + onHarvest, + onHarvestAll, + }; +}; + +export function useFarmIntegralApprove(tokenId: string) { + const [approve, setApprove] = useState(); + + const algebraPositionManager = useAlgebraPositionManagerContract(); + + useEffect(() => { + algebraPositionManager.callStatic + .farmingApprovals(tokenId) + .then((approval) => setApprove(approval !== ADDRESS_ZERO)); + }); + + return { + approve, + isLoading: approve === undefined, + }; +} + +export default useFarmIntegralActions; diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 51f17ff..b23fd4c 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -1,20 +1,19 @@ import PageContainer from '@/components/common/PageContainer'; +import Farmings from '@/components/pool/Farmings'; import MyPositions from '@/components/pool/MyPositions'; import MyPositionsToolbar from '@/components/pool/MyPositionsToolbar'; import PoolHeader from '@/components/pool/PoolHeader'; import PositionCard from '@/components/position/PositionCard'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; -import { FARMING_CENTER } from '@/constants/addresses'; import { - useEternalFarmingQuery, + useDepositsQuery, useEternalFarmingsQuery, useNativePriceQuery, usePoolFeeDataQuery, useSinglePoolQuery, useSingleTokenQuery, } from '@/graphql/generated/graphql'; -import { ETERNAL_FARMINGS } from '@/graphql/queries/farmings'; import { useClients } from '@/hooks/graphql/useClients'; import { usePool } from '@/hooks/pools/usePool'; import { usePositions } from '@/hooks/positions/usePositions'; @@ -26,7 +25,7 @@ import { useWeb3Modal } from '@web3modal/wagmi/react'; import { MoveRightIcon } from 'lucide-react'; import { useEffect, useMemo, useState } from 'react'; import { Link, useParams } from 'react-router-dom'; -import { Address, useAccount, useQuery } from 'wagmi'; +import { Address, useAccount } from 'wagmi'; const PoolPage = () => { const { address: account } = useAccount(); @@ -174,50 +173,6 @@ const PoolPage = () => { const noPositions = !positionsLoading && positionsData.length === 0 && poolEntity; - /* FARMING FEATURE */ - const [farmingData, setFarmingData] = useState(null); - - const { farmingClient } = useClients(); - - const { data: farmings } = useEternalFarmingsQuery({ - variables: { - pool: poolId, - }, - client: farmingClient, - }); - - const { data: rewardToken } = useSingleTokenQuery({ - variables: { - tokenId: farmings?.eternalFarmings?.[0]?.rewardToken, - }, - }); - - const { data: bonusRewardToken } = useSingleTokenQuery({ - variables: { - tokenId: farmings?.eternalFarmings?.[0]?.bonusRewardToken, - }, - }); - - useEffect(() => { - if (!farmings) return; - if (farmings.eternalFarmings.length === 0) return; - if (!rewardToken || !bonusRewardToken) return; - if (!poolInfo) return; - const farming = farmings.eternalFarmings[0]; - setFarmingData({ - farming, - rewardToken: rewardToken, - bonusRewardToken: bonusRewardToken, - pool: poolInfo, - }); - }, [farmings, rewardToken, bonusRewardToken, poolInfo]); - - useEffect(() => { - console.log(farmingData); - }, [farmingData]); - - /* FARMING FEATURE */ - return ( @@ -246,6 +201,13 @@ const PoolPage = () => { ) } /> +

+ Farmings +

+ )}
From 7bbe7bdfbb251a0a690b9083b02f42235c71675c Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 6 Mar 2024 02:13:06 +0300 Subject: [PATCH 08/47] config: fix abis, add farming contracts to wagmi config --- src/abis/algebraFactory.ts | 1036 +++++----- src/abis/farming/algebraEternalFarming.ts | 2294 ++++++++++----------- src/abis/farming/farmingCenter.ts | 4 +- wagmi.config.ts | 128 +- 4 files changed, 1739 insertions(+), 1723 deletions(-) diff --git a/src/abis/algebraFactory.ts b/src/abis/algebraFactory.ts index 1350873..338ad41 100644 --- a/src/abis/algebraFactory.ts +++ b/src/abis/algebraFactory.ts @@ -1,766 +1,766 @@ export const algebraFactoryABI = [ { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "_poolDeployer", - "type": "address" - } + internalType: 'address', + name: '_poolDeployer', + type: 'address', + }, ], - "stateMutability": "nonpayable", - "type": "constructor" + stateMutability: 'nonpayable', + type: 'constructor', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": false, - "internalType": "uint8", - "name": "newDefaultCommunityFee", - "type": "uint8" - } + indexed: false, + internalType: 'uint8', + name: 'newDefaultCommunityFee', + type: 'uint8', + }, ], - "name": "DefaultCommunityFee", - "type": "event" + name: 'DefaultCommunityFee', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": true, - "internalType": "address", - "name": "newFarmingAddress", - "type": "address" - } + indexed: true, + internalType: 'address', + name: 'newFarmingAddress', + type: 'address', + }, ], - "name": "FarmingAddress", - "type": "event" + name: 'FarmingAddress', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": false, - "internalType": "uint16", - "name": "alpha1", - "type": "uint16" + indexed: false, + internalType: 'uint16', + name: 'alpha1', + type: 'uint16', }, { - "indexed": false, - "internalType": "uint16", - "name": "alpha2", - "type": "uint16" + indexed: false, + internalType: 'uint16', + name: 'alpha2', + type: 'uint16', }, { - "indexed": false, - "internalType": "uint32", - "name": "beta1", - "type": "uint32" + indexed: false, + internalType: 'uint32', + name: 'beta1', + type: 'uint32', }, { - "indexed": false, - "internalType": "uint32", - "name": "beta2", - "type": "uint32" + indexed: false, + internalType: 'uint32', + name: 'beta2', + type: 'uint32', }, { - "indexed": false, - "internalType": "uint16", - "name": "gamma1", - "type": "uint16" + indexed: false, + internalType: 'uint16', + name: 'gamma1', + type: 'uint16', }, { - "indexed": false, - "internalType": "uint16", - "name": "gamma2", - "type": "uint16" + indexed: false, + internalType: 'uint16', + name: 'gamma2', + type: 'uint16', }, { - "indexed": false, - "internalType": "uint16", - "name": "baseFee", - "type": "uint16" - } + indexed: false, + internalType: 'uint16', + name: 'baseFee', + type: 'uint16', + }, ], - "name": "FeeConfiguration", - "type": "event" + name: 'FeeConfiguration', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, ], - "name": "OwnershipTransferStarted", - "type": "event" + name: 'OwnershipTransferStarted', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, ], - "name": "OwnershipTransferred", - "type": "event" + name: 'OwnershipTransferred', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": true, - "internalType": "address", - "name": "token0", - "type": "address" + indexed: true, + internalType: 'address', + name: 'token0', + type: 'address', }, { - "indexed": true, - "internalType": "address", - "name": "token1", - "type": "address" + indexed: true, + internalType: 'address', + name: 'token1', + type: 'address', }, { - "indexed": false, - "internalType": "address", - "name": "pool", - "type": "address" - } + indexed: false, + internalType: 'address', + name: 'pool', + type: 'address', + }, ], - "name": "Pool", - "type": "event" + name: 'Pool', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" + indexed: true, + internalType: 'bytes32', + name: 'previousAdminRole', + type: 'bytes32', }, { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } + indexed: true, + internalType: 'bytes32', + name: 'newAdminRole', + type: 'bytes32', + }, ], - "name": "RoleAdminChanged", - "type": "event" + name: 'RoleAdminChanged', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', }, { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, ], - "name": "RoleGranted", - "type": "event" + name: 'RoleGranted', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', }, { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, ], - "name": "RoleRevoked", - "type": "event" + name: 'RoleRevoked', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": false, - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - } + indexed: false, + internalType: 'uint256', + name: 'timestamp', + type: 'uint256', + }, ], - "name": "renounceOwnershipFinished", - "type": "event" + name: 'renounceOwnershipFinished', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": false, - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" + indexed: false, + internalType: 'uint256', + name: 'timestamp', + type: 'uint256', }, { - "indexed": false, - "internalType": "uint256", - "name": "finishTimestamp", - "type": "uint256" - } + indexed: false, + internalType: 'uint256', + name: 'finishTimestamp', + type: 'uint256', + }, ], - "name": "renounceOwnershipStarted", - "type": "event" + name: 'renounceOwnershipStarted', + type: 'event', }, { - "anonymous": false, - "inputs": [ + anonymous: false, + inputs: [ { - "indexed": false, - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - } + indexed: false, + internalType: 'uint256', + name: 'timestamp', + type: 'uint256', + }, ], - "name": "renounceOwnershipStopped", - "type": "event" + name: 'renounceOwnershipStopped', + type: 'event', }, { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [ { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "baseFeeConfiguration", - "outputs": [ + inputs: [], + name: 'baseFeeConfiguration', + outputs: [ { - "internalType": "uint16", - "name": "alpha1", - "type": "uint16" + internalType: 'uint16', + name: 'alpha1', + type: 'uint16', }, { - "internalType": "uint16", - "name": "alpha2", - "type": "uint16" + internalType: 'uint16', + name: 'alpha2', + type: 'uint16', }, { - "internalType": "uint32", - "name": "beta1", - "type": "uint32" + internalType: 'uint32', + name: 'beta1', + type: 'uint32', }, { - "internalType": "uint32", - "name": "beta2", - "type": "uint32" + internalType: 'uint32', + name: 'beta2', + type: 'uint32', }, { - "internalType": "uint16", - "name": "gamma1", - "type": "uint16" + internalType: 'uint16', + name: 'gamma1', + type: 'uint16', }, { - "internalType": "uint16", - "name": "gamma2", - "type": "uint16" + internalType: 'uint16', + name: 'gamma2', + type: 'uint16', }, { - "internalType": "uint16", - "name": "baseFee", - "type": "uint16" - } + internalType: 'uint16', + name: 'baseFee', + type: 'uint16', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "communityVault", - "outputs": [ + inputs: [], + name: 'communityVault', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "tokenA", - "type": "address" + internalType: 'address', + name: 'tokenA', + type: 'address', }, { - "internalType": "address", - "name": "tokenB", - "type": "address" - } + internalType: 'address', + name: 'tokenB', + type: 'address', + }, ], - "name": "createPool", - "outputs": [ + name: 'createPool', + outputs: [ { - "internalType": "address", - "name": "pool", - "type": "address" - } + internalType: 'address', + name: 'pool', + type: 'address', + }, ], - "stateMutability": "nonpayable", - "type": "function" + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "defaultCommunityFee", - "outputs": [ + inputs: [], + name: 'defaultCommunityFee', + outputs: [ { - "internalType": "uint8", - "name": "", - "type": "uint8" - } + internalType: 'uint8', + name: '', + type: 'uint8', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "farmingAddress", - "outputs": [ + inputs: [], + name: 'farmingAddress', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, ], - "name": "getRoleAdmin", - "outputs": [ + name: 'getRoleAdmin', + outputs: [ { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, ], - "name": "getRoleMember", - "outputs": [ + name: 'getRoleMember', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, ], - "name": "getRoleMemberCount", - "outputs": [ + name: 'getRoleMemberCount', + outputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: 'uint256', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "internalType": "address", - "name": "account", - "type": "address" - } + internalType: 'address', + name: 'account', + type: 'address', + }, ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "internalType": "address", - "name": "account", - "type": "address" - } + internalType: 'address', + name: 'account', + type: 'address', + }, ], - "name": "hasRole", - "outputs": [ + name: 'hasRole', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "internalType": "address", - "name": "account", - "type": "address" - } + internalType: 'address', + name: 'account', + type: 'address', + }, ], - "name": "hasRoleOrOwner", - "outputs": [ + name: 'hasRoleOrOwner', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "owner", - "outputs": [ + inputs: [], + name: 'owner', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + inputs: [], + name: 'pendingOwner', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "", - "type": "address" + internalType: 'address', + name: '', + type: 'address', }, { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "name": "poolByPair", - "outputs": [ + name: 'poolByPair', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "poolDeployer", - "outputs": [ + inputs: [], + name: 'poolDeployer', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "renounceOwnershipStartTimestamp", - "outputs": [ + inputs: [], + name: 'renounceOwnershipStartTimestamp', + outputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: 'uint256', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "internalType": "address", - "name": "account", - "type": "address" - } + internalType: 'address', + name: 'account', + type: 'address', + }, ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + internalType: 'bytes32', + name: 'role', + type: 'bytes32', }, { - "internalType": "address", - "name": "account", - "type": "address" - } + internalType: 'address', + name: 'account', + type: 'address', + }, ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "components": [ + components: [ { - "internalType": "uint16", - "name": "alpha1", - "type": "uint16" + internalType: 'uint16', + name: 'alpha1', + type: 'uint16', }, { - "internalType": "uint16", - "name": "alpha2", - "type": "uint16" + internalType: 'uint16', + name: 'alpha2', + type: 'uint16', }, { - "internalType": "uint32", - "name": "beta1", - "type": "uint32" + internalType: 'uint32', + name: 'beta1', + type: 'uint32', }, { - "internalType": "uint32", - "name": "beta2", - "type": "uint32" + internalType: 'uint32', + name: 'beta2', + type: 'uint32', }, { - "internalType": "uint16", - "name": "gamma1", - "type": "uint16" + internalType: 'uint16', + name: 'gamma1', + type: 'uint16', }, { - "internalType": "uint16", - "name": "gamma2", - "type": "uint16" + internalType: 'uint16', + name: 'gamma2', + type: 'uint16', }, { - "internalType": "uint16", - "name": "baseFee", - "type": "uint16" - } + internalType: 'uint16', + name: 'baseFee', + type: 'uint16', + }, ], - "internalType": "struct IAlgebraFeeConfiguration.Configuration", - "name": "_config", - "type": "tuple" - } + internalType: 'struct IAlgebraFeeConfiguration.Configuration', + name: '_config', + type: 'tuple', + }, ], - "name": "setBaseFeeConfiguration", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'setBaseFeeConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint8", - "name": "newDefaultCommunityFee", - "type": "uint8" - } + internalType: 'uint8', + name: 'newDefaultCommunityFee', + type: 'uint8', + }, ], - "name": "setDefaultCommunityFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'setDefaultCommunityFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "newFarmingAddress", - "type": "address" - } + internalType: 'address', + name: 'newFarmingAddress', + type: 'address', + }, ], - "name": "setFarmingAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'setFarmingAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "startRenounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'startRenounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "stopRenounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'stopRenounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } + internalType: 'bytes4', + name: 'interfaceId', + type: 'bytes4', + }, ], - "name": "supportsInterface", - "outputs": [ + name: 'supportsInterface', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "newOwner", - "type": "address" - } + internalType: 'address', + name: 'newOwner', + type: 'address', + }, ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] as const + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const; diff --git a/src/abis/farming/algebraEternalFarming.ts b/src/abis/farming/algebraEternalFarming.ts index e77ca37..254a855 100644 --- a/src/abis/farming/algebraEternalFarming.ts +++ b/src/abis/farming/algebraEternalFarming.ts @@ -1,1153 +1,1141 @@ -export const algebraEternalFarming = { - _format: 'hh-sol-artifact-1', - contractName: 'AlgebraEternalFarming', - sourceName: 'contracts/farmings/AlgebraEternalFarming.sol', - abi: [ - { - inputs: [ - { - internalType: 'contract IAlgebraPoolDeployer', - name: '_deployer', - type: 'address', - }, - { - internalType: 'contract INonfungiblePositionManager', - name: '_nonfungiblePositionManager', - type: 'address', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'anotherFarmingIsActive', - type: 'error', - }, - { - inputs: [], - name: 'claimToZeroAddress', - type: 'error', - }, - { - inputs: [], - name: 'emergencyActivated', - type: 'error', - }, - { - inputs: [], - name: 'farmDoesNotExist', - type: 'error', - }, - { - inputs: [], - name: 'incentiveNotExist', - type: 'error', - }, - { - inputs: [], - name: 'incentiveStopped', - type: 'error', - }, - { - inputs: [], - name: 'invalidPool', - type: 'error', - }, - { - inputs: [], - name: 'invalidTokenAmount', - type: 'error', - }, - { - inputs: [], - name: 'minimalPositionWidthTooWide', - type: 'error', - }, - { - inputs: [], - name: 'pluginNotConnected', - type: 'error', - }, - { - inputs: [], - name: 'poolReentrancyLock', - type: 'error', - }, - { - inputs: [], - name: 'positionIsTooNarrow', - type: 'error', - }, - { - inputs: [], - name: 'reentrancyLock', - type: 'error', - }, - { - inputs: [], - name: 'tokenAlreadyFarmed', - type: 'error', - }, - { - inputs: [], - name: 'zeroLiquidity', - type: 'error', - }, - { - inputs: [], - name: 'zeroRewardAmount', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'bool', - name: 'newStatus', - type: 'bool', - }, - ], - name: 'EmergencyWithdraw', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - indexed: true, - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - indexed: true, - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'virtualPool', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'reward', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'bonusReward', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint24', - name: 'minimalAllowedPositionWidth', - type: 'uint24', - }, - ], - name: 'EternalFarmingCreated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'rewardAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'bonusRewardToken', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'owner', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'reward', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'bonusReward', - type: 'uint256', - }, - ], - name: 'FarmEnded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - { - indexed: false, - internalType: 'uint128', - name: 'liquidity', - type: 'uint128', - }, - ], - name: 'FarmEntered', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'farmingCenter', - type: 'address', - }, - ], - name: 'FarmingCenter', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - ], - name: 'IncentiveDeactivated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint256', - name: 'rewardAmount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'bonusRewardAmount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - ], - name: 'RewardAmountsDecreased', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'to', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'reward', - type: 'uint256', - }, - { - indexed: true, - internalType: 'address', - name: 'rewardAddress', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'RewardClaimed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint256', - name: 'rewardAmount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'bonusRewardAmount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - ], - name: 'RewardsAdded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - { - indexed: false, - internalType: 'uint256', - name: 'rewardAmount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'bonusRewardAmount', - type: 'uint256', - }, - ], - name: 'RewardsCollected', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint128', - name: 'rewardRate', - type: 'uint128', - }, - { - indexed: false, - internalType: 'uint128', - name: 'bonusRewardRate', - type: 'uint128', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - ], - name: 'RewardsRatesChanged', - type: 'event', - }, - { - inputs: [], - name: 'FARMINGS_ADMINISTRATOR_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'INCENTIVE_MAKER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - internalType: 'uint128', - name: 'rewardAmount', - type: 'uint128', - }, - { - internalType: 'uint128', - name: 'bonusRewardAmount', - type: 'uint128', - }, - ], - name: 'addRewards', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amountRequested', - type: 'uint256', - }, - ], - name: 'claimReward', - outputs: [ - { - internalType: 'uint256', - name: 'reward', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'address', - name: 'from', - type: 'address', - }, - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amountRequested', - type: 'uint256', - }, - ], - name: 'claimRewardFrom', - outputs: [ - { - internalType: 'uint256', - name: 'reward', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - { - internalType: 'address', - name: '_owner', - type: 'address', - }, - ], - name: 'collectRewards', - outputs: [ - { - internalType: 'uint256', - name: 'reward', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'bonusReward', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - components: [ - { - internalType: 'uint128', - name: 'reward', - type: 'uint128', - }, - { - internalType: 'uint128', - name: 'bonusReward', - type: 'uint128', - }, - { - internalType: 'uint128', - name: 'rewardRate', - type: 'uint128', - }, - { - internalType: 'uint128', - name: 'bonusRewardRate', - type: 'uint128', - }, - { - internalType: 'uint24', - name: 'minimalPositionWidth', - type: 'uint24', - }, - ], - internalType: - 'struct IAlgebraEternalFarming.IncentiveParams', - name: 'params', - type: 'tuple', - }, - { - internalType: 'address', - name: 'plugin', - type: 'address', - }, - ], - name: 'createEternalFarming', - outputs: [ - { - internalType: 'address', - name: 'virtualPool', - type: 'address', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - ], - name: 'deactivateIncentive', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - internalType: 'uint128', - name: 'rewardAmount', - type: 'uint128', - }, - { - internalType: 'uint128', - name: 'bonusRewardAmount', - type: 'uint128', - }, - ], - name: 'decreaseRewardsAmount', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - ], - name: 'enterFarming', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - { - internalType: 'address', - name: '_owner', - type: 'address', - }, - ], - name: 'exitFarming', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'farmingCenter', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - { - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - ], - name: 'farms', - outputs: [ - { - internalType: 'uint128', - name: 'liquidity', - type: 'uint128', - }, - { - internalType: 'int24', - name: 'tickLower', - type: 'int24', - }, - { - internalType: 'int24', - name: 'tickUpper', - type: 'int24', - }, - { - internalType: 'uint256', - name: 'innerRewardGrowth0', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'innerRewardGrowth1', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - ], - name: 'getRewardInfo', - outputs: [ - { - internalType: 'uint256', - name: 'reward', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'bonusReward', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - ], - name: 'incentives', - outputs: [ - { - internalType: 'uint128', - name: 'totalReward', - type: 'uint128', - }, - { - internalType: 'uint128', - name: 'bonusReward', - type: 'uint128', - }, - { - internalType: 'address', - name: 'virtualPoolAddress', - type: 'address', - }, - { - internalType: 'uint24', - name: 'minimalPositionWidth', - type: 'uint24', - }, - { - internalType: 'bool', - name: 'deactivated', - type: 'bool', - }, - { - internalType: 'address', - name: 'pluginAddress', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'isEmergencyWithdrawActivated', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'incentiveId', - type: 'bytes32', - }, - ], - name: 'isIncentiveDeactivated', - outputs: [ - { - internalType: 'bool', - name: 'res', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'nonfungiblePositionManager', - outputs: [ - { - internalType: 'contract INonfungiblePositionManager', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'numOfIncentives', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - ], - name: 'rewards', - outputs: [ - { - internalType: 'uint256', - name: 'rewardAmount', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bool', - name: 'newStatus', - type: 'bool', - }, - ], - name: 'setEmergencyWithdrawStatus', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_farmingCenter', - type: 'address', - }, - ], - name: 'setFarmingCenterAddress', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'contract IERC20Minimal', - name: 'rewardToken', - type: 'address', - }, - { - internalType: 'contract IERC20Minimal', - name: 'bonusRewardToken', - type: 'address', - }, - { - internalType: 'contract IAlgebraPool', - name: 'pool', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - ], - internalType: 'struct IncentiveKey', - name: 'key', - type: 'tuple', - }, - { - internalType: 'uint128', - name: 'rewardRate', - type: 'uint128', - }, - { - internalType: 'uint128', - name: 'bonusRewardRate', - type: 'uint128', - }, - ], - name: 'setRates', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - ], - bytecode: - '0x60e06040526000805460ff60a81b1916600160a81b1790553480156200002457600080fd5b5060405162006005380380620060058339810160408190526200004791620000ed565b6001600160a01b03808216608081905290831660a0526040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa15801562000099573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000bf91906200012c565b6001600160a01b031660c05250620001539050565b6001600160a01b0381168114620000ea57600080fd5b50565b600080604083850312156200010157600080fd5b82516200010e81620000d4565b60208401519092506200012181620000d4565b809150509250929050565b6000602082840312156200013f57600080fd5b81516200014c81620000d4565b9392505050565b60805160a05160c051615e7b6200018a600039600061200e0152600061270d0152600081816104f9015261272e0152615e7b6000f3fe60806040523480156200001157600080fd5b5060043610620001ad5760003560e01c80638433524111620000f5578063dd56e5d81162000097578063f2256319116200006e578063f225631914620005d1578063f26ebf7a14620005f7578063f6de3cae146200060e57600080fd5b8063dd56e5d8146200056b578063df42efda146200058c578063e70b9e2714620005a357600080fd5b8063b44a272211620000cc578063b44a272214620004f3578063b5bae00a146200051b578063b8883c50146200054357600080fd5b80638433524114620004ae578063890cdcb314620004c557806396da9bd514620004dc57600080fd5b806336808b19116200015f5780635739f0b911620001365780635739f0b9146200037657806360777795146200038d57806382bd79ea14620004a457600080fd5b806336808b1914620002fa5780633c6d07151462000311578063547b6da9146200033957600080fd5b806327e6a99a116200019457806327e6a99a14620002095780632912bf1014620002ca5780632f2d783d14620002e357600080fd5b8063046ec16614620001b25780630a53075414620001e3575b600080fd5b620001c9620001c33660046200343a565b62000625565b604080519283526020830191909152015b60405180910390f35b620001fa620001f436600462003480565b620007dc565b604051908152602001620001da565b620002886200021a366004620034d8565b6002602081815260009384526040808520909152918352912080546001820154918301546fffffffffffffffffffffffffffffffff8216937001000000000000000000000000000000008304810b93730100000000000000000000000000000000000000909304900b919085565b604080516fffffffffffffffffffffffffffffffff9096168652600294850b60208701529290930b918401919091526060830152608082015260a001620001da565b620002e1620002db366004620034fb565b620007ff565b005b620001fa620002f43660046200351a565b62000ad2565b620002e16200030b3660046200343a565b62000aec565b620001fa7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39581565b620003506200034a3660046200357f565b62000c94565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001da565b620002e16200038736600462003669565b62001259565b620004406200039e36600462003697565b60016020819052600091825260409091208054918101546002909101546fffffffffffffffffffffffffffffffff808416937001000000000000000000000000000000009004169173ffffffffffffffffffffffffffffffffffffffff8082169274010000000000000000000000000000000000000000830462ffffff169277010000000000000000000000000000000000000000000000900460ff16911686565b604080516fffffffffffffffffffffffffffffffff978816815296909516602087015273ffffffffffffffffffffffffffffffffffffffff9384169486019490945262ffffff9091166060850152151560808401521660a082015260c001620001da565b620001fa60035481565b620002e1620004bf366004620036b1565b62001455565b620002e1620004d636600462003706565b62001526565b620001c9620004ed36600462003669565b620015f6565b620003507f000000000000000000000000000000000000000000000000000000000000000081565b620005326200052c36600462003697565b62001654565b6040519015158152602001620001da565b620001fa7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221981565b600054620003509073ffffffffffffffffffffffffffffffffffffffff1681565b620002e16200059d36600462003726565b62001673565b620001fa620005b436600462003746565b600460209081526000928352604080842090915290825290205481565b600054620005329074010000000000000000000000000000000000000000900460ff1681565b620002e162000608366004620036b1565b62001734565b620002e16200061f366004620036b1565b620017e0565b6000806200063262001b7c565b600080620006408762001ba3565b91509150600062000652878462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff166200067b8162001d6c565b6000806200068a838562001dd1565b809450819550829a50839b50505050506000600260008c8152602001908152602001600020600088815260200190815260200160002090508281600101819055508181600201819055506000600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050896000146200074d578c5173ffffffffffffffffffffffffffffffffffffffff16600090815260208290526040902080548b0190555b881562000784576020808e015173ffffffffffffffffffffffffffffffffffffffff166000908152908290526040902080548a0190555b604080518d8152602081018a90529081018b9052606081018a90527f15b2e0f32b50efdbbdee9ec7884ed3c61e6209b1b395e5762011a6734b86f7b59060800160405180910390a15050505050505050935093915050565b6000620007e862001b7c565b620007f68585858562001e74565b95945050505050565b6200082a7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b600080620008388362001ba3565b6001810154919350915077010000000000000000000000000000000000000000000000900460ff161562000898576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101805460028301547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff82167701000000000000000000000000000000000000000000000017909255604080517f51b42b00000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff928316939092169183916351b42b0091600480830192600092919082900301818387803b1580156200095257600080fd5b505af115801562000967573d6000803e3d6000fd5b505050506000808373ffffffffffffffffffffffffffffffffffffffff1663a88a5c166040518163ffffffff1660e01b81526004016040805180830381865afa158015620009b9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009df919062003791565b915091508082176fffffffffffffffffffffffffffffffff1660001462000a0f5762000a0f84600080896200209e565b6000546040517f2bd34c4800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015290911690632bd34c4890604401600060405180830381600087803b15801562000a8557600080fd5b505af115801562000a9a573d6000803e3d6000fd5b50506040518892507f907b91fb061b1c46367da11a5a0e8b2c0bd5fecd22eb92967e626cffa5ef63869150600090a250505050505050565b600062000ae28433858562001e74565b90505b9392505050565b62000af662001b7c565b600062000b688460408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b9050600062000b78848362001c7d565b9050600080600060149054906101000a900460ff1662000bd25762000bcc8388868862000bbb88600001516fffffffffffffffffffffffffffffffff1662002195565b62000bc690620037f4565b620021ac565b90925090505b6000868152600260208181526040808420888552825280842080547fffffffffffffffffffff000000000000000000000000000000000000000000001681556001810185905590920192909255885189830151825173ffffffffffffffffffffffffffffffffffffffff918216815289821694810194909452918301859052606083018490521690859088907f7f2557bb15dcf63e3d029ef1dcb4333563fcd78edf263b8fe42ed3adb925ff849060800160405180910390a450505050505050565b600062000cc17fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000846040015173ffffffffffffffffffffffffffffffffffffffff1663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d13573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d39919062003842565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158062000d8b575073ffffffffffffffffffffffffffffffffffffffff8116155b1562000dc3576040517f093d6f1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16631d4632ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000e27573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e4d919062003842565b73ffffffffffffffffffffffffffffffffffffffff161462000e9b576040517f47146bcc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b308160405162000eab90620032fd565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f08015801562000eec573d6000803e3d6000fd5b506000546040517fd68516bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8084166004830152848116602483015292945091169063d68516bc90604401600060405180830381600087803b15801562000f6557600080fd5b505af115801562000f7a573d6000803e3d6000fd5b50506003805492509050600062000f918362003862565b90915550606086015260006200100c8660408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b60008181526001602090815260409091208751918801519293509162001035918991846200234a565b6fffffffffffffffffffffffffffffffff9081166020890152168087526000036200108c576040517f36ab0f6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080860151621b13d062ffffff9091161315620010d5576040517f1db9891100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181018054608088015162ffffff811674010000000000000000000000000000000000000000027fffffffffffffffffff000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff80891691909117929092179092556002830180548683167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790556040808a01516020808c01518c5160608e01518d51938e01519551948716979287169691909116947fcef9468c62cd8a6eca3a887fc30674c037943e423de07ab3a122bdf2f73c77e1946200121b948d9490929173ffffffffffffffffffffffffffffffffffffffff95909516855260208501939093526fffffffffffffffffffffffffffffffff918216604085015216606083015262ffffff16608082015260a00190565b60405180910390a4620012398487600001518860200151856200251c565b6200124f8487604001518860600151856200209e565b5050509392505050565b6200126362001b7c565b60005474010000000000000000000000000000000000000000900460ff1615620012b9576040517f05bfeb5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000620012cd87876200260a565b93985091965094509250905080600080620012ea83888862002893565b915091506040518060a00160405280866fffffffffffffffffffffffffffffffff1681526020018860020b81526020018760020b815260200183815260200182815250600260008b815260200190815260200160002060008a815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160000160136101000a81548162ffffff021916908360020b62ffffff160217905550606082015181600101556080820151816002015590505087897f19bc21617a8d86ff19202ac9541480a99b9ae5fbd573a23f14f479af784392c4876040516200144191906fffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a350505050505050505050565b620014807fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000806200148e8562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff8585171615801590620014d85750620014d88262002940565b1562001510576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200151e818686866200209e565b505050505050565b620015517f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b801515600060149054906101000a900460ff161515036200157157600080fd5b6000805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517fee20b3d336390a4b077dbc7d702bf6e35a954bc96106f37b9e5ef08a1d0ce05990620015eb90831515815260200190565b60405180910390a150565b600080600080620016078662001ba3565b91509150600062001619868462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff1662001643818362001dd1565b50919a909950975050505050505050565b60008181526001602052604081206200166d9062002940565b92915050565b6200169e7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b60005473ffffffffffffffffffffffffffffffffffffffff90811690821603620016c757600080fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f29f9e1ebeee07596f3165f3e42cb9d4d8d22b0481e968d6c74be3dd037c15d9b91a250565b600080620017428562001ba3565b91509150620017518162002940565b1562001789576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff16620017b2868686856200234a565b90955093506fffffffffffffffffffffffffffffffff85851716156200151e576200151e818686866200251c565b6200180b7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b600080620018198562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff16620018448162001d6c565b6000808273ffffffffffffffffffffffffffffffffffffffff1663f0de82286040518163ffffffff1660e01b81526004016040805180830381865afa15801562001892573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018b8919062003791565b91509150816fffffffffffffffffffffffffffffffff16876fffffffffffffffffffffffffffffffff161115620018ed578196505b83546fffffffffffffffffffffffffffffffff90811690881610620019315783546200192e906001906fffffffffffffffffffffffffffffffff166200389d565b96505b8354620019529088906fffffffffffffffffffffffffffffffff166200389d565b84547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91821617855581811690871611156200199e578095505b8354620019d390879070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166200389d565b84546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161784556040517fca16ca7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063ca16ca7e9062001a74908a908a906004016fffffffffffffffffffffffffffffffff92831681529116602082015260400190565b600060405180830381600087803b15801562001a8f57600080fd5b505af115801562001aa4573d6000803e3d6000fd5b505050506fffffffffffffffffffffffffffffffff87161562001ae257875162001ae290336fffffffffffffffffffffffffffffffff8a16620029f6565b6fffffffffffffffffffffffffffffffff86161562001b1e5762001b1e886020015133886fffffffffffffffffffffffffffffffff16620029f6565b604080516fffffffffffffffffffffffffffffffff808a168252881660208201529081018690527f808ecc37f6d601dde1e43c133bee66af0ff9409b53aca0eb0d4f6c65fb8956e89060600160405180910390a15050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462001ba157600080fd5b565b60008062001c168360408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b6000818152600160205260408120805492945092506fffffffffffffffffffffffffffffffff909116900362001c78576040517fe4c8229200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b915091565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525060008281526002602081815260408084208585528252808420815160a08101835281546fffffffffffffffffffffffffffffffff81168083527001000000000000000000000000000000008204870b958301959095527301000000000000000000000000000000000000009004850b92810192909252600181015460608301529092015460808301529091036200166d576040517f7aa92c6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16636f4a2cd06040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001db557600080fd5b505af115801562001dca573d6000803e3d6000fd5b5050505050565b60008060008062001dec868660200151876040015162002893565b6060870151875192945090925062001e2c91908403906fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b62001e668660800151830387600001516fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b909790965091945092509050565b600073ffffffffffffffffffffffffffffffffffffffff831662001ec4576040517fabd1763600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff80841660009081526004602090815260408083209388168352908390529020549082158062001f0857508183115b1562001f12578192505b821562001fd05773ffffffffffffffffffffffffffffffffffffffff86166000908152602082905260409020838303905562001f50868585620029f6565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe6ac6a784fb43c9f6329d2f5c82f88a26a93bad4281f7780725af5f071f0aafa8660405162001fc791815260200190565b60405180910390a45b50949350505050565b6040517fe8ae2b69000000000000000000000000000000000000000000000000000000008152600481018290523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa1580156200206b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020919190620038d0565b6200209b57600080fd5b50565b6040517f7f463bb80000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff851690637f463bb890604401600060405180830381600087803b1580156200212057600080fd5b505af115801562002135573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f1864e4cc903d98e44820faebd48409c410a2ad20adb3173984ba41ae2828805e925060600190505b60405180910390a150505050565b80600f81900b8114620021a757600080fd5b919050565b600083815260016020819052604082209081015482919073ffffffffffffffffffffffffffffffffffffffff1682620021e58362002940565b620021ff57620021f9896040015162002c27565b62002271565b8173ffffffffffffffffffffffffffffffffffffffff16638e76c3326040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200224b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002271919062003903565b90506200227e8262001d6c565b6200228a828b62001dd1565b9050508095508196505050620022ac828b602001518c60400151898562002ce6565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260046020526040902085156200230557895173ffffffffffffffffffffffffffffffffffffffff1660009081526020829052604090208054870190555b84156200233c576020808b015173ffffffffffffffffffffffffffffffffffffffff16600090815290829052604090208054860190555b505050509550959350505050565b6000805481907501000000000000000000000000000000000000000000900460ff16620023a3576040517f2446d79f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690556fffffffffffffffffffffffffffffffff851615620023f5578551620023f2908662002d8c565b91505b6fffffffffffffffffffffffffffffffff84161562002421576200241e86602001518562002d8c565b90505b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017905582546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041662002499848362003921565b85547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91909116178555620024e1838262003921565b85546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161790945550909590945092505050565b6040517ffddf08e50000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff85169063fddf08e590604401600060405180830381600087803b1580156200259e57600080fd5b505af1158015620025b3573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f8b0312d8047895ce795779b66b705ccd39b1ece7c162f642c72d76a785d1b68a9250606001905062002187565b6000806000806000806200261e8862001ba3565b600089815260026020908152604080832085845290915290205491975091506fffffffffffffffffffffffffffffffff161562002687576040517ff352b37500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff8116925074010000000000000000000000000000000000000000900462ffffff16620026cd8262002940565b1562002705576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620027547f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b62002e26565b60408e0151929a50909850965090915073ffffffffffffffffffffffffffffffffffffffff808316911614620027b6576040517fdce2809300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846fffffffffffffffffffffffffffffffff1660000362002803576040517f4eed436000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8162ffffff168760020b8760020b0312156200284b576040517feab0585000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620028588262002c27565b9050620028858589896200287e8a6fffffffffffffffffffffffffffffffff1662002195565b8562002ce6565b505050509295509295909350565b6040517f0bd6f200000000000000000000000000000000000000000000000000000000008152600283810b600483015282900b6024820152600090819073ffffffffffffffffffffffffffffffffffffffff861690630bd6f200906044016040805180830381865afa1580156200290e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200293491906200394d565b91509150935093915050565b600181015460009073ffffffffffffffffffffffffffffffffffffffff81169077010000000000000000000000000000000000000000000000900460ff168062000ae5578173ffffffffffffffffffffffffffffffffffffffff1663556ed30e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620029d0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ae29190620038d0565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169162002a8f919062003972565b6000604051808303816000865af19150503d806000811462002ace576040519150601f19603f3d011682016040523d82523d6000602084013e62002ad3565b606091505b509150915081801562002b0157508051158062002b0157508080602001905181019062002b019190620038d0565b62001dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8587098281108382030391505080841162002bae57600080fd5b8060000362002bc35750829004905062000ae5565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff1663e76c01e46040518163ffffffff1660e01b815260040160c060405180830381865afa15801562002c76573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002c9c9190620039b6565b93965092945084935062002ce092505050576040517f9ded0f5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b6040517fd6b83ede000000000000000000000000000000000000000000000000000000008152600285810b600483015284810b6024830152600f84900b604483015282900b606482015273ffffffffffffffffffffffffffffffffffffffff86169063d6b83ede90608401600060405180830381600087803b15801562002d6c57600080fd5b505af115801562002d81573d6000803e3d6000fd5b505050505050505050565b60008062002d9a8462002f0c565b905062002dbc843330866fffffffffffffffffffffffffffffffff1662002fa0565b600062002dc98562002f0c565b905081811162002dd857600080fd5b8181036fffffffffffffffffffffffffffffffff811115620007f6576040517f3ba11f1e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000808773ffffffffffffffffffffffffffffffffffffffff166399fbab88886040518263ffffffff1660e01b815260040162002e6b91815260200190565b61016060405180830381865afa15801562002e8a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002eb0919062003a44565b50506040805180820190915273ffffffffffffffffffffffffffffffffffffffff808916825287166020820152949d50929b5090995093975091955062002eff94508d935091506200311b9050565b9550505093509350935093565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801562002f7a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200166d919062003b2c565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169162003041919062003972565b6000604051808303816000865af19150503d806000811462003080576040519150601f19603f3d011682016040523d82523d6000602084013e62003085565b606091505b5091509150818015620030b3575080511580620030b3575080806020019051810190620030b39190620038d0565b6200151e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015260640162002b64565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610620031bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964206f72646572206f6620746f6b656e73000000000000000000604482015260640162002b64565b8282600001518360200151604051602001620031fb92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290528051602091820120620032c0939290917ff96d2474815c32e070cd63233f06af5413efc5dcb430aee4ff18cc29007c562d91017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6123288062003b4783390190565b60405160a0810167ffffffffffffffff8111828210171562003356577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b73ffffffffffffffffffffffffffffffffffffffff811681146200209b57600080fd5b6000608082840312156200339257600080fd5b6040516080810181811067ffffffffffffffff82111715620033dd577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235620033f0816200335c565b8152602083013562003402816200335c565b6020820152604083013562003417816200335c565b6040820152606092830135920191909152919050565b8035620021a7816200335c565b600080600060c084860312156200345057600080fd5b6200345c85856200337f565b92506080840135915060a084013562003475816200335c565b809150509250925092565b600080600080608085870312156200349757600080fd5b8435620034a4816200335c565b93506020850135620034b6816200335c565b92506040850135620034c8816200335c565b9396929550929360600135925050565b60008060408385031215620034ec57600080fd5b50508035926020909101359150565b6000608082840312156200350e57600080fd5b62000ae583836200337f565b6000806000606084860312156200353057600080fd5b83356200353d816200335c565b925060208401356200354f816200335c565b929592945050506040919091013590565b6fffffffffffffffffffffffffffffffff811681146200209b57600080fd5b60008060008385036101408112156200359757600080fd5b620035a386866200337f565b935060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082011215620035d657600080fd5b50620035e16200330b565b6080850135620035f18162003560565b815260a0850135620036038162003560565b602082015260c0850135620036188162003560565b604082015260e08501356200362d8162003560565b606082015261010085013562ffffff811681146200364a57600080fd5b608082015291506200366061012085016200342d565b90509250925092565b60008060a083850312156200367d57600080fd5b6200368984846200337f565b946080939093013593505050565b600060208284031215620036aa57600080fd5b5035919050565b600080600060c08486031215620036c757600080fd5b620036d385856200337f565b92506080840135620036e58162003560565b915060a0840135620034758162003560565b80151581146200209b57600080fd5b6000602082840312156200371957600080fd5b813562000ae581620036f7565b6000602082840312156200373957600080fd5b813562000ae5816200335c565b600080604083850312156200375a57600080fd5b823562003767816200335c565b9150602083013562003779816200335c565b809150509250929050565b8051620021a78162003560565b60008060408385031215620037a557600080fd5b8251620037b28162003560565b6020840151909250620037798162003560565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600081600f0b7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081036200382c576200382c620037c5565b60000392915050565b8051620021a7816200335c565b6000602082840312156200385557600080fd5b815162000ae5816200335c565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620038965762003896620037c5565b5060010190565b6fffffffffffffffffffffffffffffffff828116828216039080821115620038c957620038c9620037c5565b5092915050565b600060208284031215620038e357600080fd5b815162000ae581620036f7565b8051600281900b8114620021a757600080fd5b6000602082840312156200391657600080fd5b62000ae582620038f0565b6fffffffffffffffffffffffffffffffff818116838216019080821115620038c957620038c9620037c5565b600080604083850312156200396157600080fd5b505080516020909101519092909150565b6000825160005b8181101562003995576020818601810151858301520162003979565b506000920191825250919050565b805161ffff81168114620021a757600080fd5b60008060008060008060c08789031215620039d057600080fd5b8651620039dd816200335c565b9550620039ed60208801620038f0565b9450620039fd60408801620039a3565b9350606087015160ff8116811462003a1457600080fd5b925062003a2460808801620039a3565b915060a087015162003a3681620036f7565b809150509295509295509295565b60008060008060008060008060008060006101608c8e03121562003a6757600080fd5b8b516affffffffffffffffffffff8116811462003a8357600080fd5b60208d0151909b5062003a96816200335c565b60408d0151909a5062003aa9816200335c565b985062003ab960608d0162003835565b975062003ac960808d01620038f0565b965062003ad960a08d01620038f0565b955062003ae960c08d0162003784565b945060e08c015193506101008c0151925062003b096101208d0162003784565b915062003b1a6101408d0162003784565b90509295989b509295989b9093969950565b60006020828403121562003b3f57600080fd5b505191905056fe60c0604052600160075560016008553480156200001b57600080fd5b506040516200232838038062002328833981810160405260408110156200004157600080fd5b508051602090910151620000566000620000d2565b6001600160a01b03828116608052811660a0526004805462ffffff63ffffffff60c81b011916600160c81b4263ffffffff160262ffffff19161762f27618179055620000a6620d89e719620001c8565b6004805462ffffff9290921663010000000265ffffff0000001990921691909117905550620001f99050565b620d89e719620000e281620001c8565b620d89e7196000818152602085905260409020600101805465ffffffffffff60801b1916600160981b62ffffff9485160262ffffff60801b191617600160801b9490931693909302919091179091556200013c81620001c8565b8260006200014e620d89e719620001c8565b60020b60020b81526020019081526020016000206001016010846000620d89e7196200017a90620001c8565b60020b81526020810191909152604001600020600101805462ffffff948516600160981b0262ffffff60981b1990911617905581549383166101009190910a90810292021990921617905550565b60008160020b627fffff198103620001f057634e487b7160e01b600052601160045260246000fd5b60000392915050565b60805160a0516120fb6200022d6000396000818161044101526107e801526000818161028c015261132401526120fb6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e76c332116100b2578063d6b83ede11610081578063f0de822811610066578063f0de822814610463578063f30dba9314610495578063fddf08e51461054c57600080fd5b8063d6b83ede14610401578063ef01df4f1461043c57600080fd5b80638e76c332146102d7578063a88a5c1614610315578063ca16ca7e14610384578063d576dfc0146103bb57600080fd5b8063556ed30e116101095780636f4a2cd0116100ee5780636f4a2cd0146102485780637f463bb8146102505780638a2ade581461028757600080fd5b8063556ed30e1461020f5780635e075b531461023d57600080fd5b80630bd6f2001461013b57806334d335901461017e57806346caf2ae146101ba57806351b42b0014610205575b600080fd5b6101656004803603604081101561015157600080fd5b508035600290810b9160200135900b610583565b6040805192835260208301919091528051918290030190f35b6101a66004803603604081101561019457600080fd5b50803560020b906020013515156107ce565b604080519115158252519081900360200190f35b6004546101e090660100000000000090046fffffffffffffffffffffffffffffffff1681565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61020d610c17565b005b6004546101a6907d010000000000000000000000000000000000000000000000000000000000900460ff1681565b600754600854610165565b61020d610c69565b61020d6004803603604081101561026657600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610c7b565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6004546102fe90760100000000000000000000000000000000000000000000900460020b81565b6040805160029290920b8252519081900360200190f35b6005546fffffffffffffffffffffffffffffffff808216917001000000000000000000000000000000009004165b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b61020d6004803603604081101561039a57600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610cdc565b6004546103e890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b6040805163ffffffff9092168252519081900360200190f35b61020d6004803603608081101561041757600080fd5b508035600290810b916020810135820b916040820135600f0b9160600135900b610cf4565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416610343565b610510600480360360208110156104ab57600080fd5b50600060208190529035600290810b8252604090912080546001820154828401546003909301549193600f82900b937001000000000000000000000000000000008304820b9373010000000000000000000000000000000000000090930490910b9186565b60408051968752600f9590950b6020870152600293840b868601529190920b6060850152608084019190915260a0830152519081900360c00190f35b61020d6004803603604081101561056257600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610f0c565b600282810b600090815260208190526040812060010154909182917001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b14806106205750600283810b6000908152602081905260409020600101547001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b145b15610657576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045460075460085463ffffffff79010000000000000000000000000000000000000000000000000084048116420393760100000000000000000000000000000000000000000000900460020b9291908416156107af57600454660100000000000090046fffffffffffffffffffffffffffffffff1680156107ad5760055460065463ffffffff87166fffffffffffffffffffffffffffffffff8084168202811693700100000000000000000000000000000000908190048216909202811692818116929004168184111561072a578193505b80831115610736578092505b831561076f5761076a84700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b870196505b82156107a8576107a383700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b860195505b505050505b505b6107be60008989868686610fd8565b95509550505050505b9250929050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461083f576040517f545acb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546fffffffffffffffffffffffffffffffff6601000000000000820416907601000000000000000000000000000000000000000000008104600290810b9163ffffffff7901000000000000000000000000000000000000000000000000008204169160ff7d0100000000000000000000000000000000000000000000000000000000008304169180820b916301000000909104900b82156108eb5760009650505050505050610c11565b600285810b908a900b1380159061091e578260020b8a60020b12610919576001975050505050505050610c11565b61093c565b8160020b8a60020b121561093c576001975050505050505050610c11565b881515811515146109a0575050600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000001790555060009450610c119350505050565b6109bc85886fffffffffffffffffffffffffffffffff16611076565b6007546008548a15610a8d575b600288900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761814610a88578460020b8c60020b1215610b3a57600285810b600090815260208190526040812060038101805482850180548803905585039055600101547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88019a50700100000000000000000000000000000000810490920b969550600f9190910b90610a80908b90839003611245565b9950506109c9565b610b3a565b6001610ab87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b610ac2919061200c565b60020b8860020b14610b3a578360020b8c60020b12610b3a57600284810b600090815260208190526040902060038101805482840180548703905584039055600101549498508895507301000000000000000000000000000000000000008504900b93600f0b610b328a82611245565b995050610a8d565b50506004805462ffffff9384166301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000858e16760100000000000000000000000000000000000000000000027fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff909c166601000000000000029b909b167fffffffffffffff00000000000000000000000000000000000000ffffffffffff90931692909217999099171693909216929092179590951790945550600193505050505b92915050565b610c1f61130c565b600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055565b610c7161130c565b610c7961137b565b565b610c8361130c565b610c8b61137b565b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000001617600555565b610ce461130c565b610cf0600083836113c7565b5050565b610cfc61130c565b6004546fffffffffffffffffffffffffffffffff66010000000000008204169063ffffffff7901000000000000000000000000000000000000000000000000008204169060ff7d0100000000000000000000000000000000000000000000000000000000008204169063010000008104600290810b91900b82610dd557610d848682846114a7565b610dd557600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055600192505b50508015610de557505050610f06565b600480547fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000062ffffff87160217905563ffffffff82164263ffffffff161115610e5d57610e5d82846fffffffffffffffffffffffffffffffff16611076565b84600f0b600014610f02576000610e7788868860006114cc565b90506000610e8888878960016114cc565b9050610e95868a8a6114a7565b15610edd57610ea48588611245565b600460066101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b8180610ee65750805b15610eff57610eff898984848a60008d600f0b126114f0565b50505b5050505b50505050565b610f1461130c565b610cf0600183836113c7565b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870982811083820303915050808411610f6057600080fd5b80600003610f7357508290049050610fd1565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290505b9392505050565b600285810b60009081526020889052604080822087840b8084529183209293849391929088900b121561104e578860020b8760020b1261102957816002015486039350816003015485039250611038565b81600201549350816003015492505b6002810154600382015494039390920391611069565b81600201548160020154039350816003015481600301540392505b5050965096945050505050565b63ffffffff4283900316600081900361108e57505050565b81156111f4576005546006546fffffffffffffffffffffffffffffffff8083168402927001000000000000000000000000000000009081900482168502928083169291900416818411156110f257816fffffffffffffffffffffffffffffffff1693505b806fffffffffffffffffffffffffffffffff1683111561112257806fffffffffffffffffffffffffffffffff1692505b838317156111ef576fffffffffffffffffffffffffffffffff91821684900391168290038315611172576111688470010000000000000000000000000000000088610f20565b6007805490910190555b821561119e576111948370010000000000000000000000000000000088610f20565b6008805490910190555b6fffffffffffffffffffffffffffffffff808316908216700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050505b5050600480547fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff167901000000000000000000000000000000000000000000000000004263ffffffff160217905550565b60008082600f0b12156112a957508082016fffffffffffffffffffffffffffffffff808416908216106112a4576040517f1301f74800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c11565b826fffffffffffffffffffffffffffffffff168284019150816fffffffffffffffffffffffffffffffff161015610c11576040517f997402f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c79576040517fae74b17800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454610c7990790100000000000000000000000000000000000000000000000000810463ffffffff1690660100000000000090046fffffffffffffffffffffffffffffffff16611076565b6113cf61137b565b6fffffffffffffffffffffffffffffffff82821716156114a2576006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416841561143957611426848361204d565b9150611432838261204d565b9050611452565b611443848361207d565b915061144f838261207d565b90505b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050565b60008260020b8460020b121580156114c457508160020b8460020b125b949350505050565b6007546008546000916114e79183918891889188918861161f565b95945050505050565b600454600154600282810b9263010000009004900b9063ffffffff16828282891561152b576115238c898386868c611753565b919450925090505b88156115475761153f8b898386868c611753565b919450925090505b8260020b8660020b14158061156257508160020b8560020b14155b8061157957508363ffffffff168163ffffffff1614155b1561161157600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8316179055600480547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016630100000062ffffff858116919091027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000016919091179085161790555b505050505050505050505050565b600286900b600090815260208890526040812080548261163f8289611245565b6fffffffffffffffffffffffffffffffff1690506d09745258e83de0d0f4e400fce79981111561169b576040517f25b8364a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830154600f0b856116bf5788600f0b81600f0b6116ba91906120a6565b6116d1565b88600f0b81600f0b6116d191906120ce565b6001850180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691909117905581845581159450600083900361174457841594508960020b8b60020b136117445760038401879055600284018890555b50505050979650505050505050565b6000806000831561179c5760008061176b818c611854565b915091508a60020b8860020b0361178457819750611795565b8a60020b8760020b03611795578096505b5050611832565b6000808a60020b8860020b1280156117b957508a60020b8760020b135b156117e257508690508560028a810b908c900b13156117da578a9650611822565b8a9750611822565b6117f0600360028b8e611aca565b600281810b6000908152602081905260409020600101547001000000000000000000000000000000009004900b925090505b61182f60008c8484611ba7565b50505b6000611842600360028a8d611d53565b969a9599509597509395505050505050565b600281810b60008181526020859052604081206001810180548383557fffffffffffffffffffff0000000000000000000000000000000000000000000081169091558185018390556003909101919091557001000000000000000000000000000000008104830b92730100000000000000000000000000000000000000909104900b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618148061193157506119287ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b156119d657600283900b6000908152602085905260409020600101805462ffffff808516700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff91851673010000000000000000000000000000000000000002919091167fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff909216919091171790556107c7565b8060020b8260020b03611a15576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282810b6000908152602086905260408082206001908101805462ffffff808816730100000000000000000000000000000000000000027fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff909216919091179091559385900b83529120018054918416700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff9092169190911790559250929050565b600190810190600090600883811d610d8a01901c90829061ffff83161b851663ffffffff1615611b2d57611afe8785611deb565b90945090925090508015611b135750506114c4565b611b2486610d8b840160010b611deb565b90945090925090505b80611b7057611b4b8563ffffffff168360010193508360010b611e1c565b909350905080611b635750620d89e891506114c49050565b611b6d8684611f73565b92505b611b9c877ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2768501611f73565b979650505050505050565b600283900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276181480611c065750611bfd7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b610f06578260020b8260020b128015611c2457508260020b8160020b135b611c5a576040517fe45ac17d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810b60009081526020959095526040808620600190810180547fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff1673010000000000000000000000000000000000000062ffffff87811682027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff908116939093177001000000000000000000000000000000008a831681029190911790945597860b8a52848a20840180547fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff1698909916908102979097179097559390920b865290942090930180549092169202919091179055565b81600080611d908785600881901d600181810b60009081526020949094526040909320805460ff9093169390931b80831890935591811490151891565b915091508115611de157610d8a01600181810b60081d80820b6000908152602089905260409020805460ff9094169290921b808418909255821591909214818118935014611de1576001811b831892505b5050949350505050565b600881901d600181900b6000908152602084905260408120548190611e109085611e1c565b93969095509293505050565b60008060ff831684811c808303611e38578460ff179350611f6a565b7f555555555555555555555555555555555555555555555555555555555555555560008290038216908116156fffffffffffffffffffffffffffffffff82161560071b1777ffffffffffffffff0000000000000000ffffffffffffffff82161560061b177bffffffff00000000ffffffff00000000ffffffff00000000ffffffff82161560051b177dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff82161560041b177eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff82161560031b177f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f82161560021b177f33333333333333333333333333333333333333333333333333333333333333339091161560011b1760ff1685019350600192505b50509250929050565b600181900b600090815260208390526040902054600882901b90611f979082611e1c565b509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361200357612003611f9f565b60000392915050565b600282810b9082900b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008112627fffff82131715610c1157610c11611f9f565b6fffffffffffffffffffffffffffffffff81811683821601908082111561207657612076611f9f565b5092915050565b6fffffffffffffffffffffffffffffffff82811682821603908082111561207657612076611f9f565b80820182811260008312801582168215821617156120c6576120c6611f9f565b505092915050565b818103600083128015838313168383128216171561207657612076611f9f56fea164736f6c6343000814000aa164736f6c6343000814000a', - deployedBytecode: - '0x60806040523480156200001157600080fd5b5060043610620001ad5760003560e01c80638433524111620000f5578063dd56e5d81162000097578063f2256319116200006e578063f225631914620005d1578063f26ebf7a14620005f7578063f6de3cae146200060e57600080fd5b8063dd56e5d8146200056b578063df42efda146200058c578063e70b9e2714620005a357600080fd5b8063b44a272211620000cc578063b44a272214620004f3578063b5bae00a146200051b578063b8883c50146200054357600080fd5b80638433524114620004ae578063890cdcb314620004c557806396da9bd514620004dc57600080fd5b806336808b19116200015f5780635739f0b911620001365780635739f0b9146200037657806360777795146200038d57806382bd79ea14620004a457600080fd5b806336808b1914620002fa5780633c6d07151462000311578063547b6da9146200033957600080fd5b806327e6a99a116200019457806327e6a99a14620002095780632912bf1014620002ca5780632f2d783d14620002e357600080fd5b8063046ec16614620001b25780630a53075414620001e3575b600080fd5b620001c9620001c33660046200343a565b62000625565b604080519283526020830191909152015b60405180910390f35b620001fa620001f436600462003480565b620007dc565b604051908152602001620001da565b620002886200021a366004620034d8565b6002602081815260009384526040808520909152918352912080546001820154918301546fffffffffffffffffffffffffffffffff8216937001000000000000000000000000000000008304810b93730100000000000000000000000000000000000000909304900b919085565b604080516fffffffffffffffffffffffffffffffff9096168652600294850b60208701529290930b918401919091526060830152608082015260a001620001da565b620002e1620002db366004620034fb565b620007ff565b005b620001fa620002f43660046200351a565b62000ad2565b620002e16200030b3660046200343a565b62000aec565b620001fa7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39581565b620003506200034a3660046200357f565b62000c94565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001da565b620002e16200038736600462003669565b62001259565b620004406200039e36600462003697565b60016020819052600091825260409091208054918101546002909101546fffffffffffffffffffffffffffffffff808416937001000000000000000000000000000000009004169173ffffffffffffffffffffffffffffffffffffffff8082169274010000000000000000000000000000000000000000830462ffffff169277010000000000000000000000000000000000000000000000900460ff16911686565b604080516fffffffffffffffffffffffffffffffff978816815296909516602087015273ffffffffffffffffffffffffffffffffffffffff9384169486019490945262ffffff9091166060850152151560808401521660a082015260c001620001da565b620001fa60035481565b620002e1620004bf366004620036b1565b62001455565b620002e1620004d636600462003706565b62001526565b620001c9620004ed36600462003669565b620015f6565b620003507f000000000000000000000000000000000000000000000000000000000000000081565b620005326200052c36600462003697565b62001654565b6040519015158152602001620001da565b620001fa7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221981565b600054620003509073ffffffffffffffffffffffffffffffffffffffff1681565b620002e16200059d36600462003726565b62001673565b620001fa620005b436600462003746565b600460209081526000928352604080842090915290825290205481565b600054620005329074010000000000000000000000000000000000000000900460ff1681565b620002e162000608366004620036b1565b62001734565b620002e16200061f366004620036b1565b620017e0565b6000806200063262001b7c565b600080620006408762001ba3565b91509150600062000652878462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff166200067b8162001d6c565b6000806200068a838562001dd1565b809450819550829a50839b50505050506000600260008c8152602001908152602001600020600088815260200190815260200160002090508281600101819055508181600201819055506000600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050896000146200074d578c5173ffffffffffffffffffffffffffffffffffffffff16600090815260208290526040902080548b0190555b881562000784576020808e015173ffffffffffffffffffffffffffffffffffffffff166000908152908290526040902080548a0190555b604080518d8152602081018a90529081018b9052606081018a90527f15b2e0f32b50efdbbdee9ec7884ed3c61e6209b1b395e5762011a6734b86f7b59060800160405180910390a15050505050505050935093915050565b6000620007e862001b7c565b620007f68585858562001e74565b95945050505050565b6200082a7fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b600080620008388362001ba3565b6001810154919350915077010000000000000000000000000000000000000000000000900460ff161562000898576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101805460028301547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff82167701000000000000000000000000000000000000000000000017909255604080517f51b42b00000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff928316939092169183916351b42b0091600480830192600092919082900301818387803b1580156200095257600080fd5b505af115801562000967573d6000803e3d6000fd5b505050506000808373ffffffffffffffffffffffffffffffffffffffff1663a88a5c166040518163ffffffff1660e01b81526004016040805180830381865afa158015620009b9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009df919062003791565b915091508082176fffffffffffffffffffffffffffffffff1660001462000a0f5762000a0f84600080896200209e565b6000546040517f2bd34c4800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015290911690632bd34c4890604401600060405180830381600087803b15801562000a8557600080fd5b505af115801562000a9a573d6000803e3d6000fd5b50506040518892507f907b91fb061b1c46367da11a5a0e8b2c0bd5fecd22eb92967e626cffa5ef63869150600090a250505050505050565b600062000ae28433858562001e74565b90505b9392505050565b62000af662001b7c565b600062000b688460408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b9050600062000b78848362001c7d565b9050600080600060149054906101000a900460ff1662000bd25762000bcc8388868862000bbb88600001516fffffffffffffffffffffffffffffffff1662002195565b62000bc690620037f4565b620021ac565b90925090505b6000868152600260208181526040808420888552825280842080547fffffffffffffffffffff000000000000000000000000000000000000000000001681556001810185905590920192909255885189830151825173ffffffffffffffffffffffffffffffffffffffff918216815289821694810194909452918301859052606083018490521690859088907f7f2557bb15dcf63e3d029ef1dcb4333563fcd78edf263b8fe42ed3adb925ff849060800160405180910390a450505050505050565b600062000cc17fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000846040015173ffffffffffffffffffffffffffffffffffffffff1663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d13573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d39919062003842565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158062000d8b575073ffffffffffffffffffffffffffffffffffffffff8116155b1562000dc3576040517f093d6f1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16631d4632ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000e27573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e4d919062003842565b73ffffffffffffffffffffffffffffffffffffffff161462000e9b576040517f47146bcc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b308160405162000eab90620032fd565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f08015801562000eec573d6000803e3d6000fd5b506000546040517fd68516bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8084166004830152848116602483015292945091169063d68516bc90604401600060405180830381600087803b15801562000f6557600080fd5b505af115801562000f7a573d6000803e3d6000fd5b50506003805492509050600062000f918362003862565b90915550606086015260006200100c8660408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b60008181526001602090815260409091208751918801519293509162001035918991846200234a565b6fffffffffffffffffffffffffffffffff9081166020890152168087526000036200108c576040517f36ab0f6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080860151621b13d062ffffff9091161315620010d5576040517f1db9891100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181018054608088015162ffffff811674010000000000000000000000000000000000000000027fffffffffffffffffff000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff80891691909117929092179092556002830180548683167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790556040808a01516020808c01518c5160608e01518d51938e01519551948716979287169691909116947fcef9468c62cd8a6eca3a887fc30674c037943e423de07ab3a122bdf2f73c77e1946200121b948d9490929173ffffffffffffffffffffffffffffffffffffffff95909516855260208501939093526fffffffffffffffffffffffffffffffff918216604085015216606083015262ffffff16608082015260a00190565b60405180910390a4620012398487600001518860200151856200251c565b6200124f8487604001518860600151856200209e565b5050509392505050565b6200126362001b7c565b60005474010000000000000000000000000000000000000000900460ff1615620012b9576040517f05bfeb5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000620012cd87876200260a565b93985091965094509250905080600080620012ea83888862002893565b915091506040518060a00160405280866fffffffffffffffffffffffffffffffff1681526020018860020b81526020018760020b815260200183815260200182815250600260008b815260200190815260200160002060008a815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160000160136101000a81548162ffffff021916908360020b62ffffff160217905550606082015181600101556080820151816002015590505087897f19bc21617a8d86ff19202ac9541480a99b9ae5fbd573a23f14f479af784392c4876040516200144191906fffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a350505050505050505050565b620014807fa777c10270ee0b99d2c737c09ff865ed48064b252418bbd31d39c8b88ea1221962001fd9565b6000806200148e8562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff8585171615801590620014d85750620014d88262002940565b1562001510576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200151e818686866200209e565b505050505050565b620015517f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b801515600060149054906101000a900460ff161515036200157157600080fd5b6000805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517fee20b3d336390a4b077dbc7d702bf6e35a954bc96106f37b9e5ef08a1d0ce05990620015eb90831515815260200190565b60405180910390a150565b600080600080620016078662001ba3565b91509150600062001619868462001c7d565b600183015490915073ffffffffffffffffffffffffffffffffffffffff1662001643818362001dd1565b50919a909950975050505050505050565b60008181526001602052604081206200166d9062002940565b92915050565b6200169e7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b60005473ffffffffffffffffffffffffffffffffffffffff90811690821603620016c757600080fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f29f9e1ebeee07596f3165f3e42cb9d4d8d22b0481e968d6c74be3dd037c15d9b91a250565b600080620017428562001ba3565b91509150620017518162002940565b1562001789576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff16620017b2868686856200234a565b90955093506fffffffffffffffffffffffffffffffff85851716156200151e576200151e818686866200251c565b6200180b7f681ab0361ab5f3ae8c1d864335ef2b9a8c12a6a67e1ed0f4083d00a4b8a9a39562001fd9565b600080620018198562001ba3565b6001810154919350915073ffffffffffffffffffffffffffffffffffffffff16620018448162001d6c565b6000808273ffffffffffffffffffffffffffffffffffffffff1663f0de82286040518163ffffffff1660e01b81526004016040805180830381865afa15801562001892573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018b8919062003791565b91509150816fffffffffffffffffffffffffffffffff16876fffffffffffffffffffffffffffffffff161115620018ed578196505b83546fffffffffffffffffffffffffffffffff90811690881610620019315783546200192e906001906fffffffffffffffffffffffffffffffff166200389d565b96505b8354620019529088906fffffffffffffffffffffffffffffffff166200389d565b84547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91821617855581811690871611156200199e578095505b8354620019d390879070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166200389d565b84546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161784556040517fca16ca7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063ca16ca7e9062001a74908a908a906004016fffffffffffffffffffffffffffffffff92831681529116602082015260400190565b600060405180830381600087803b15801562001a8f57600080fd5b505af115801562001aa4573d6000803e3d6000fd5b505050506fffffffffffffffffffffffffffffffff87161562001ae257875162001ae290336fffffffffffffffffffffffffffffffff8a16620029f6565b6fffffffffffffffffffffffffffffffff86161562001b1e5762001b1e886020015133886fffffffffffffffffffffffffffffffff16620029f6565b604080516fffffffffffffffffffffffffffffffff808a168252881660208201529081018690527f808ecc37f6d601dde1e43c133bee66af0ff9409b53aca0eb0d4f6c65fb8956e89060600160405180910390a15050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462001ba157600080fd5b565b60008062001c168360408051825173ffffffffffffffffffffffffffffffffffffffff90811660208084019190915284015181168284015291830151909116606080830191909152820151608082015260009060a001604051602081830303815290604052805190602001209050919050565b6000818152600160205260408120805492945092506fffffffffffffffffffffffffffffffff909116900362001c78576040517fe4c8229200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b915091565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525060008281526002602081815260408084208585528252808420815160a08101835281546fffffffffffffffffffffffffffffffff81168083527001000000000000000000000000000000008204870b958301959095527301000000000000000000000000000000000000009004850b92810192909252600181015460608301529092015460808301529091036200166d576040517f7aa92c6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16636f4a2cd06040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001db557600080fd5b505af115801562001dca573d6000803e3d6000fd5b5050505050565b60008060008062001dec868660200151876040015162002893565b6060870151875192945090925062001e2c91908403906fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b62001e668660800151830387600001516fffffffffffffffffffffffffffffffff1670010000000000000000000000000000000062002b6d565b909790965091945092509050565b600073ffffffffffffffffffffffffffffffffffffffff831662001ec4576040517fabd1763600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff80841660009081526004602090815260408083209388168352908390529020549082158062001f0857508183115b1562001f12578192505b821562001fd05773ffffffffffffffffffffffffffffffffffffffff86166000908152602082905260409020838303905562001f50868585620029f6565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe6ac6a784fb43c9f6329d2f5c82f88a26a93bad4281f7780725af5f071f0aafa8660405162001fc791815260200190565b60405180910390a45b50949350505050565b6040517fe8ae2b69000000000000000000000000000000000000000000000000000000008152600481018290523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa1580156200206b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020919190620038d0565b6200209b57600080fd5b50565b6040517f7f463bb80000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff851690637f463bb890604401600060405180830381600087803b1580156200212057600080fd5b505af115801562002135573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f1864e4cc903d98e44820faebd48409c410a2ad20adb3173984ba41ae2828805e925060600190505b60405180910390a150505050565b80600f81900b8114620021a757600080fd5b919050565b600083815260016020819052604082209081015482919073ffffffffffffffffffffffffffffffffffffffff1682620021e58362002940565b620021ff57620021f9896040015162002c27565b62002271565b8173ffffffffffffffffffffffffffffffffffffffff16638e76c3326040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200224b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002271919062003903565b90506200227e8262001d6c565b6200228a828b62001dd1565b9050508095508196505050620022ac828b602001518c60400151898562002ce6565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260046020526040902085156200230557895173ffffffffffffffffffffffffffffffffffffffff1660009081526020829052604090208054870190555b84156200233c576020808b015173ffffffffffffffffffffffffffffffffffffffff16600090815290829052604090208054860190555b505050509550959350505050565b6000805481907501000000000000000000000000000000000000000000900460ff16620023a3576040517f2446d79f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690556fffffffffffffffffffffffffffffffff851615620023f5578551620023f2908662002d8c565b91505b6fffffffffffffffffffffffffffffffff84161562002421576200241e86602001518562002d8c565b90505b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017905582546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041662002499848362003921565b85547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91909116178555620024e1838262003921565b85546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161790945550909590945092505050565b6040517ffddf08e50000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff80851660048301528316602482015273ffffffffffffffffffffffffffffffffffffffff85169063fddf08e590604401600060405180830381600087803b1580156200259e57600080fd5b505af1158015620025b3573d6000803e3d6000fd5b5050604080516fffffffffffffffffffffffffffffffff8088168252861660208201529081018490527f8b0312d8047895ce795779b66b705ccd39b1ece7c162f642c72d76a785d1b68a9250606001905062002187565b6000806000806000806200261e8862001ba3565b600089815260026020908152604080832085845290915290205491975091506fffffffffffffffffffffffffffffffff161562002687576040517ff352b37500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015473ffffffffffffffffffffffffffffffffffffffff8116925074010000000000000000000000000000000000000000900462ffffff16620026cd8262002940565b1562002705576040517f260e553a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620027547f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b62002e26565b60408e0151929a50909850965090915073ffffffffffffffffffffffffffffffffffffffff808316911614620027b6576040517fdce2809300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846fffffffffffffffffffffffffffffffff1660000362002803576040517f4eed436000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8162ffffff168760020b8760020b0312156200284b576040517feab0585000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620028588262002c27565b9050620028858589896200287e8a6fffffffffffffffffffffffffffffffff1662002195565b8562002ce6565b505050509295509295909350565b6040517f0bd6f200000000000000000000000000000000000000000000000000000000008152600283810b600483015282900b6024820152600090819073ffffffffffffffffffffffffffffffffffffffff861690630bd6f200906044016040805180830381865afa1580156200290e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200293491906200394d565b91509150935093915050565b600181015460009073ffffffffffffffffffffffffffffffffffffffff81169077010000000000000000000000000000000000000000000000900460ff168062000ae5578173ffffffffffffffffffffffffffffffffffffffff1663556ed30e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620029d0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ae29190620038d0565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169162002a8f919062003972565b6000604051808303816000865af19150503d806000811462002ace576040519150601f19603f3d011682016040523d82523d6000602084013e62002ad3565b606091505b509150915081801562002b0157508051158062002b0157508080602001905181019062002b019190620038d0565b62001dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8587098281108382030391505080841162002bae57600080fd5b8060000362002bc35750829004905062000ae5565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff1663e76c01e46040518163ffffffff1660e01b815260040160c060405180830381865afa15801562002c76573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002c9c9190620039b6565b93965092945084935062002ce092505050576040517f9ded0f5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b6040517fd6b83ede000000000000000000000000000000000000000000000000000000008152600285810b600483015284810b6024830152600f84900b604483015282900b606482015273ffffffffffffffffffffffffffffffffffffffff86169063d6b83ede90608401600060405180830381600087803b15801562002d6c57600080fd5b505af115801562002d81573d6000803e3d6000fd5b505050505050505050565b60008062002d9a8462002f0c565b905062002dbc843330866fffffffffffffffffffffffffffffffff1662002fa0565b600062002dc98562002f0c565b905081811162002dd857600080fd5b8181036fffffffffffffffffffffffffffffffff811115620007f6576040517f3ba11f1e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000806000808773ffffffffffffffffffffffffffffffffffffffff166399fbab88886040518263ffffffff1660e01b815260040162002e6b91815260200190565b61016060405180830381865afa15801562002e8a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002eb0919062003a44565b50506040805180820190915273ffffffffffffffffffffffffffffffffffffffff808916825287166020820152949d50929b5090995093975091955062002eff94508d935091506200311b9050565b9550505093509350935093565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801562002f7a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200166d919062003b2c565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169162003041919062003972565b6000604051808303816000865af19150503d806000811462003080576040519150601f19603f3d011682016040523d82523d6000602084013e62003085565b606091505b5091509150818015620030b3575080511580620030b3575080806020019051810190620030b39190620038d0565b6200151e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015260640162002b64565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610620031bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964206f72646572206f6620746f6b656e73000000000000000000604482015260640162002b64565b8282600001518360200151604051602001620031fb92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290528051602091820120620032c0939290917ff96d2474815c32e070cd63233f06af5413efc5dcb430aee4ff18cc29007c562d91017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6123288062003b4783390190565b60405160a0810167ffffffffffffffff8111828210171562003356577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b73ffffffffffffffffffffffffffffffffffffffff811681146200209b57600080fd5b6000608082840312156200339257600080fd5b6040516080810181811067ffffffffffffffff82111715620033dd577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235620033f0816200335c565b8152602083013562003402816200335c565b6020820152604083013562003417816200335c565b6040820152606092830135920191909152919050565b8035620021a7816200335c565b600080600060c084860312156200345057600080fd5b6200345c85856200337f565b92506080840135915060a084013562003475816200335c565b809150509250925092565b600080600080608085870312156200349757600080fd5b8435620034a4816200335c565b93506020850135620034b6816200335c565b92506040850135620034c8816200335c565b9396929550929360600135925050565b60008060408385031215620034ec57600080fd5b50508035926020909101359150565b6000608082840312156200350e57600080fd5b62000ae583836200337f565b6000806000606084860312156200353057600080fd5b83356200353d816200335c565b925060208401356200354f816200335c565b929592945050506040919091013590565b6fffffffffffffffffffffffffffffffff811681146200209b57600080fd5b60008060008385036101408112156200359757600080fd5b620035a386866200337f565b935060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082011215620035d657600080fd5b50620035e16200330b565b6080850135620035f18162003560565b815260a0850135620036038162003560565b602082015260c0850135620036188162003560565b604082015260e08501356200362d8162003560565b606082015261010085013562ffffff811681146200364a57600080fd5b608082015291506200366061012085016200342d565b90509250925092565b60008060a083850312156200367d57600080fd5b6200368984846200337f565b946080939093013593505050565b600060208284031215620036aa57600080fd5b5035919050565b600080600060c08486031215620036c757600080fd5b620036d385856200337f565b92506080840135620036e58162003560565b915060a0840135620034758162003560565b80151581146200209b57600080fd5b6000602082840312156200371957600080fd5b813562000ae581620036f7565b6000602082840312156200373957600080fd5b813562000ae5816200335c565b600080604083850312156200375a57600080fd5b823562003767816200335c565b9150602083013562003779816200335c565b809150509250929050565b8051620021a78162003560565b60008060408385031215620037a557600080fd5b8251620037b28162003560565b6020840151909250620037798162003560565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600081600f0b7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081036200382c576200382c620037c5565b60000392915050565b8051620021a7816200335c565b6000602082840312156200385557600080fd5b815162000ae5816200335c565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620038965762003896620037c5565b5060010190565b6fffffffffffffffffffffffffffffffff828116828216039080821115620038c957620038c9620037c5565b5092915050565b600060208284031215620038e357600080fd5b815162000ae581620036f7565b8051600281900b8114620021a757600080fd5b6000602082840312156200391657600080fd5b62000ae582620038f0565b6fffffffffffffffffffffffffffffffff818116838216019080821115620038c957620038c9620037c5565b600080604083850312156200396157600080fd5b505080516020909101519092909150565b6000825160005b8181101562003995576020818601810151858301520162003979565b506000920191825250919050565b805161ffff81168114620021a757600080fd5b60008060008060008060c08789031215620039d057600080fd5b8651620039dd816200335c565b9550620039ed60208801620038f0565b9450620039fd60408801620039a3565b9350606087015160ff8116811462003a1457600080fd5b925062003a2460808801620039a3565b915060a087015162003a3681620036f7565b809150509295509295509295565b60008060008060008060008060008060006101608c8e03121562003a6757600080fd5b8b516affffffffffffffffffffff8116811462003a8357600080fd5b60208d0151909b5062003a96816200335c565b60408d0151909a5062003aa9816200335c565b985062003ab960608d0162003835565b975062003ac960808d01620038f0565b965062003ad960a08d01620038f0565b955062003ae960c08d0162003784565b945060e08c015193506101008c0151925062003b096101208d0162003784565b915062003b1a6101408d0162003784565b90509295989b509295989b9093969950565b60006020828403121562003b3f57600080fd5b505191905056fe60c0604052600160075560016008553480156200001b57600080fd5b506040516200232838038062002328833981810160405260408110156200004157600080fd5b508051602090910151620000566000620000d2565b6001600160a01b03828116608052811660a0526004805462ffffff63ffffffff60c81b011916600160c81b4263ffffffff160262ffffff19161762f27618179055620000a6620d89e719620001c8565b6004805462ffffff9290921663010000000265ffffff0000001990921691909117905550620001f99050565b620d89e719620000e281620001c8565b620d89e7196000818152602085905260409020600101805465ffffffffffff60801b1916600160981b62ffffff9485160262ffffff60801b191617600160801b9490931693909302919091179091556200013c81620001c8565b8260006200014e620d89e719620001c8565b60020b60020b81526020019081526020016000206001016010846000620d89e7196200017a90620001c8565b60020b81526020810191909152604001600020600101805462ffffff948516600160981b0262ffffff60981b1990911617905581549383166101009190910a90810292021990921617905550565b60008160020b627fffff198103620001f057634e487b7160e01b600052601160045260246000fd5b60000392915050565b60805160a0516120fb6200022d6000396000818161044101526107e801526000818161028c015261132401526120fb6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e76c332116100b2578063d6b83ede11610081578063f0de822811610066578063f0de822814610463578063f30dba9314610495578063fddf08e51461054c57600080fd5b8063d6b83ede14610401578063ef01df4f1461043c57600080fd5b80638e76c332146102d7578063a88a5c1614610315578063ca16ca7e14610384578063d576dfc0146103bb57600080fd5b8063556ed30e116101095780636f4a2cd0116100ee5780636f4a2cd0146102485780637f463bb8146102505780638a2ade581461028757600080fd5b8063556ed30e1461020f5780635e075b531461023d57600080fd5b80630bd6f2001461013b57806334d335901461017e57806346caf2ae146101ba57806351b42b0014610205575b600080fd5b6101656004803603604081101561015157600080fd5b508035600290810b9160200135900b610583565b6040805192835260208301919091528051918290030190f35b6101a66004803603604081101561019457600080fd5b50803560020b906020013515156107ce565b604080519115158252519081900360200190f35b6004546101e090660100000000000090046fffffffffffffffffffffffffffffffff1681565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61020d610c17565b005b6004546101a6907d010000000000000000000000000000000000000000000000000000000000900460ff1681565b600754600854610165565b61020d610c69565b61020d6004803603604081101561026657600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610c7b565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6004546102fe90760100000000000000000000000000000000000000000000900460020b81565b6040805160029290920b8252519081900360200190f35b6005546fffffffffffffffffffffffffffffffff808216917001000000000000000000000000000000009004165b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b61020d6004803603604081101561039a57600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610cdc565b6004546103e890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b6040805163ffffffff9092168252519081900360200190f35b61020d6004803603608081101561041757600080fd5b508035600290810b916020810135820b916040820135600f0b9160600135900b610cf4565b6102ae7f000000000000000000000000000000000000000000000000000000000000000081565b6006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416610343565b610510600480360360208110156104ab57600080fd5b50600060208190529035600290810b8252604090912080546001820154828401546003909301549193600f82900b937001000000000000000000000000000000008304820b9373010000000000000000000000000000000000000090930490910b9186565b60408051968752600f9590950b6020870152600293840b868601529190920b6060850152608084019190915260a0830152519081900360c00190f35b61020d6004803603604081101561056257600080fd5b506fffffffffffffffffffffffffffffffff81358116916020013516610f0c565b600282810b600090815260208190526040812060010154909182917001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b14806106205750600283810b6000908152602081905260409020600101547001000000000000000000000000000000008104820b73010000000000000000000000000000000000000090910490910b145b15610657576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045460075460085463ffffffff79010000000000000000000000000000000000000000000000000084048116420393760100000000000000000000000000000000000000000000900460020b9291908416156107af57600454660100000000000090046fffffffffffffffffffffffffffffffff1680156107ad5760055460065463ffffffff87166fffffffffffffffffffffffffffffffff8084168202811693700100000000000000000000000000000000908190048216909202811692818116929004168184111561072a578193505b80831115610736578092505b831561076f5761076a84700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b870196505b82156107a8576107a383700100000000000000000000000000000000876fffffffffffffffffffffffffffffffff16610f20565b860195505b505050505b505b6107be60008989868686610fd8565b95509550505050505b9250929050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461083f576040517f545acb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546fffffffffffffffffffffffffffffffff6601000000000000820416907601000000000000000000000000000000000000000000008104600290810b9163ffffffff7901000000000000000000000000000000000000000000000000008204169160ff7d0100000000000000000000000000000000000000000000000000000000008304169180820b916301000000909104900b82156108eb5760009650505050505050610c11565b600285810b908a900b1380159061091e578260020b8a60020b12610919576001975050505050505050610c11565b61093c565b8160020b8a60020b121561093c576001975050505050505050610c11565b881515811515146109a0575050600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000001790555060009450610c119350505050565b6109bc85886fffffffffffffffffffffffffffffffff16611076565b6007546008548a15610a8d575b600288900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761814610a88578460020b8c60020b1215610b3a57600285810b600090815260208190526040812060038101805482850180548803905585039055600101547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88019a50700100000000000000000000000000000000810490920b969550600f9190910b90610a80908b90839003611245565b9950506109c9565b610b3a565b6001610ab87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b610ac2919061200c565b60020b8860020b14610b3a578360020b8c60020b12610b3a57600284810b600090815260208190526040902060038101805482840180548703905584039055600101549498508895507301000000000000000000000000000000000000008504900b93600f0b610b328a82611245565b995050610a8d565b50506004805462ffffff9384166301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000858e16760100000000000000000000000000000000000000000000027fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff909c166601000000000000029b909b167fffffffffffffff00000000000000000000000000000000000000ffffffffffff90931692909217999099171693909216929092179590951790945550600193505050505b92915050565b610c1f61130c565b600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055565b610c7161130c565b610c7961137b565b565b610c8361130c565b610c8b61137b565b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000001617600555565b610ce461130c565b610cf0600083836113c7565b5050565b610cfc61130c565b6004546fffffffffffffffffffffffffffffffff66010000000000008204169063ffffffff7901000000000000000000000000000000000000000000000000008204169060ff7d0100000000000000000000000000000000000000000000000000000000008204169063010000008104600290810b91900b82610dd557610d848682846114a7565b610dd557600480547fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d010000000000000000000000000000000000000000000000000000000000179055600192505b50508015610de557505050610f06565b600480547fffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000062ffffff87160217905563ffffffff82164263ffffffff161115610e5d57610e5d82846fffffffffffffffffffffffffffffffff16611076565b84600f0b600014610f02576000610e7788868860006114cc565b90506000610e8888878960016114cc565b9050610e95868a8a6114a7565b15610edd57610ea48588611245565b600460066101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b8180610ee65750805b15610eff57610eff898984848a60008d600f0b126114f0565b50505b5050505b50505050565b610f1461130c565b610cf0600183836113c7565b6000838302817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870982811083820303915050808411610f6057600080fd5b80600003610f7357508290049050610fd1565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290505b9392505050565b600285810b60009081526020889052604080822087840b8084529183209293849391929088900b121561104e578860020b8760020b1261102957816002015486039350816003015485039250611038565b81600201549350816003015492505b6002810154600382015494039390920391611069565b81600201548160020154039350816003015481600301540392505b5050965096945050505050565b63ffffffff4283900316600081900361108e57505050565b81156111f4576005546006546fffffffffffffffffffffffffffffffff8083168402927001000000000000000000000000000000009081900482168502928083169291900416818411156110f257816fffffffffffffffffffffffffffffffff1693505b806fffffffffffffffffffffffffffffffff1683111561112257806fffffffffffffffffffffffffffffffff1692505b838317156111ef576fffffffffffffffffffffffffffffffff91821684900391168290038315611172576111688470010000000000000000000000000000000088610f20565b6007805490910190555b821561119e576111948370010000000000000000000000000000000088610f20565b6008805490910190555b6fffffffffffffffffffffffffffffffff808316908216700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050505b5050600480547fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff167901000000000000000000000000000000000000000000000000004263ffffffff160217905550565b60008082600f0b12156112a957508082016fffffffffffffffffffffffffffffffff808416908216106112a4576040517f1301f74800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c11565b826fffffffffffffffffffffffffffffffff168284019150816fffffffffffffffffffffffffffffffff161015610c11576040517f997402f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c79576040517fae74b17800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454610c7990790100000000000000000000000000000000000000000000000000810463ffffffff1690660100000000000090046fffffffffffffffffffffffffffffffff16611076565b6113cf61137b565b6fffffffffffffffffffffffffffffffff82821716156114a2576006546fffffffffffffffffffffffffffffffff80821691700100000000000000000000000000000000900416841561143957611426848361204d565b9150611432838261204d565b9050611452565b611443848361207d565b915061144f838261207d565b90505b6fffffffffffffffffffffffffffffffff9182169116700100000000000000000000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000016176006555b505050565b60008260020b8460020b121580156114c457508160020b8460020b125b949350505050565b6007546008546000916114e79183918891889188918861161f565b95945050505050565b600454600154600282810b9263010000009004900b9063ffffffff16828282891561152b576115238c898386868c611753565b919450925090505b88156115475761153f8b898386868c611753565b919450925090505b8260020b8660020b14158061156257508160020b8560020b14155b8061157957508363ffffffff168163ffffffff1614155b1561161157600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8316179055600480547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016630100000062ffffff858116919091027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000016919091179085161790555b505050505050505050505050565b600286900b600090815260208890526040812080548261163f8289611245565b6fffffffffffffffffffffffffffffffff1690506d09745258e83de0d0f4e400fce79981111561169b576040517f25b8364a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830154600f0b856116bf5788600f0b81600f0b6116ba91906120a6565b6116d1565b88600f0b81600f0b6116d191906120ce565b6001850180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691909117905581845581159450600083900361174457841594508960020b8b60020b136117445760038401879055600284018890555b50505050979650505050505050565b6000806000831561179c5760008061176b818c611854565b915091508a60020b8860020b0361178457819750611795565b8a60020b8760020b03611795578096505b5050611832565b6000808a60020b8860020b1280156117b957508a60020b8760020b135b156117e257508690508560028a810b908c900b13156117da578a9650611822565b8a9750611822565b6117f0600360028b8e611aca565b600281810b6000908152602081905260409020600101547001000000000000000000000000000000009004900b925090505b61182f60008c8484611ba7565b50505b6000611842600360028a8d611d53565b969a9599509597509395505050505050565b600281810b60008181526020859052604081206001810180548383557fffffffffffffffffffff0000000000000000000000000000000000000000000081169091558185018390556003909101919091557001000000000000000000000000000000008104830b92730100000000000000000000000000000000000000909104900b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618148061193157506119287ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b156119d657600283900b6000908152602085905260409020600101805462ffffff808516700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff91851673010000000000000000000000000000000000000002919091167fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff909216919091171790556107c7565b8060020b8260020b03611a15576040517f0d6e094900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282810b6000908152602086905260408082206001908101805462ffffff808816730100000000000000000000000000000000000000027fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff909216919091179091559385900b83529120018054918416700100000000000000000000000000000000027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff9092169190911790559250929050565b600190810190600090600883811d610d8a01901c90829061ffff83161b851663ffffffff1615611b2d57611afe8785611deb565b90945090925090508015611b135750506114c4565b611b2486610d8b840160010b611deb565b90945090925090505b80611b7057611b4b8563ffffffff168360010193508360010b611e1c565b909350905080611b635750620d89e891506114c49050565b611b6d8684611f73565b92505b611b9c877ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2768501611f73565b979650505050505050565b600283900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276181480611c065750611bfd7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611fce565b60020b8360020b145b610f06578260020b8260020b128015611c2457508260020b8160020b135b611c5a576040517fe45ac17d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810b60009081526020959095526040808620600190810180547fffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffff1673010000000000000000000000000000000000000062ffffff87811682027fffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff908116939093177001000000000000000000000000000000008a831681029190911790945597860b8a52848a20840180547fffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff1698909916908102979097179097559390920b865290942090930180549092169202919091179055565b81600080611d908785600881901d600181810b60009081526020949094526040909320805460ff9093169390931b80831890935591811490151891565b915091508115611de157610d8a01600181810b60081d80820b6000908152602089905260409020805460ff9094169290921b808418909255821591909214818118935014611de1576001811b831892505b5050949350505050565b600881901d600181900b6000908152602084905260408120548190611e109085611e1c565b93969095509293505050565b60008060ff831684811c808303611e38578460ff179350611f6a565b7f555555555555555555555555555555555555555555555555555555555555555560008290038216908116156fffffffffffffffffffffffffffffffff82161560071b1777ffffffffffffffff0000000000000000ffffffffffffffff82161560061b177bffffffff00000000ffffffff00000000ffffffff00000000ffffffff82161560051b177dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff82161560041b177eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff82161560031b177f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f82161560021b177f33333333333333333333333333333333333333333333333333333333333333339091161560011b1760ff1685019350600192505b50509250929050565b600181900b600090815260208390526040902054600882901b90611f979082611e1c565b509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361200357612003611f9f565b60000392915050565b600282810b9082900b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008112627fffff82131715610c1157610c11611f9f565b6fffffffffffffffffffffffffffffffff81811683821601908082111561207657612076611f9f565b5092915050565b6fffffffffffffffffffffffffffffffff82811682821603908082111561207657612076611f9f565b80820182811260008312801582168215821617156120c6576120c6611f9f565b505092915050565b818103600083128015838313168383128216171561207657612076611f9f56fea164736f6c6343000814000aa164736f6c6343000814000a', - linkReferences: {}, - deployedLinkReferences: {}, -}; +export const algebraEternalFarmingABI = [ + { + inputs: [ + { + internalType: 'contract IAlgebraPoolDeployer', + name: '_deployer', + type: 'address', + }, + { + internalType: 'contract INonfungiblePositionManager', + name: '_nonfungiblePositionManager', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'anotherFarmingIsActive', + type: 'error', + }, + { + inputs: [], + name: 'claimToZeroAddress', + type: 'error', + }, + { + inputs: [], + name: 'emergencyActivated', + type: 'error', + }, + { + inputs: [], + name: 'farmDoesNotExist', + type: 'error', + }, + { + inputs: [], + name: 'incentiveNotExist', + type: 'error', + }, + { + inputs: [], + name: 'incentiveStopped', + type: 'error', + }, + { + inputs: [], + name: 'invalidPool', + type: 'error', + }, + { + inputs: [], + name: 'invalidTokenAmount', + type: 'error', + }, + { + inputs: [], + name: 'minimalPositionWidthTooWide', + type: 'error', + }, + { + inputs: [], + name: 'pluginNotConnected', + type: 'error', + }, + { + inputs: [], + name: 'poolReentrancyLock', + type: 'error', + }, + { + inputs: [], + name: 'positionIsTooNarrow', + type: 'error', + }, + { + inputs: [], + name: 'reentrancyLock', + type: 'error', + }, + { + inputs: [], + name: 'tokenAlreadyFarmed', + type: 'error', + }, + { + inputs: [], + name: 'zeroLiquidity', + type: 'error', + }, + { + inputs: [], + name: 'zeroRewardAmount', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'newStatus', + type: 'bool', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'virtualPool', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint24', + name: 'minimalAllowedPositionWidth', + type: 'uint24', + }, + ], + name: 'EternalFarmingCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'rewardAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'bonusRewardToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + ], + name: 'FarmEnded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint128', + name: 'liquidity', + type: 'uint128', + }, + ], + name: 'FarmEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'farmingCenter', + type: 'address', + }, + ], + name: 'FarmingCenter', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'IncentiveDeactivated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusRewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'RewardAmountsDecreased', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'rewardAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'RewardClaimed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusRewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'RewardsAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'bonusRewardAmount', + type: 'uint256', + }, + ], + name: 'RewardsCollected', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint128', + name: 'rewardRate', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint128', + name: 'bonusRewardRate', + type: 'uint128', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'RewardsRatesChanged', + type: 'event', + }, + { + inputs: [], + name: 'FARMINGS_ADMINISTRATOR_ROLE', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'INCENTIVE_MAKER_ROLE', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'rewardAmount', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardAmount', + type: 'uint128', + }, + ], + name: 'addRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountRequested', + type: 'uint256', + }, + ], + name: 'claimReward', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountRequested', + type: 'uint256', + }, + ], + name: 'claimRewardFrom', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + name: 'collectRewards', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint128', + name: 'reward', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusReward', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'rewardRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardRate', + type: 'uint128', + }, + { + internalType: 'uint24', + name: 'minimalPositionWidth', + type: 'uint24', + }, + ], + internalType: 'struct IAlgebraEternalFarming.IncentiveParams', + name: 'params', + type: 'tuple', + }, + { + internalType: 'address', + name: 'plugin', + type: 'address', + }, + ], + name: 'createEternalFarming', + outputs: [ + { + internalType: 'address', + name: 'virtualPool', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + ], + name: 'deactivateIncentive', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'rewardAmount', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardAmount', + type: 'uint128', + }, + ], + name: 'decreaseRewardsAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'enterFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + name: 'exitFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'farmingCenter', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'farms', + outputs: [ + { + internalType: 'uint128', + name: 'liquidity', + type: 'uint128', + }, + { + internalType: 'int24', + name: 'tickLower', + type: 'int24', + }, + { + internalType: 'int24', + name: 'tickUpper', + type: 'int24', + }, + { + internalType: 'uint256', + name: 'innerRewardGrowth0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'innerRewardGrowth1', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'getRewardInfo', + outputs: [ + { + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'bonusReward', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'incentives', + outputs: [ + { + internalType: 'uint128', + name: 'totalReward', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusReward', + type: 'uint128', + }, + { + internalType: 'address', + name: 'virtualPoolAddress', + type: 'address', + }, + { + internalType: 'uint24', + name: 'minimalPositionWidth', + type: 'uint24', + }, + { + internalType: 'bool', + name: 'deactivated', + type: 'bool', + }, + { + internalType: 'address', + name: 'pluginAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isEmergencyWithdrawActivated', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'incentiveId', + type: 'bytes32', + }, + ], + name: 'isIncentiveDeactivated', + outputs: [ + { + internalType: 'bool', + name: 'res', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'nonfungiblePositionManager', + outputs: [ + { + internalType: 'contract INonfungiblePositionManager', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'numOfIncentives', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + ], + name: 'rewards', + outputs: [ + { + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'newStatus', + type: 'bool', + }, + ], + name: 'setEmergencyWithdrawStatus', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_farmingCenter', + type: 'address', + }, + ], + name: 'setFarmingCenterAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'contract IERC20Minimal', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'contract IERC20Minimal', + name: 'bonusRewardToken', + type: 'address', + }, + { + internalType: 'contract IAlgebraPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + ], + internalType: 'struct IncentiveKey', + name: 'key', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'rewardRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'bonusRewardRate', + type: 'uint128', + }, + ], + name: 'setRates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const; diff --git a/src/abis/farming/farmingCenter.ts b/src/abis/farming/farmingCenter.ts index a72bffd..942f53e 100644 --- a/src/abis/farming/farmingCenter.ts +++ b/src/abis/farming/farmingCenter.ts @@ -1,4 +1,4 @@ -export const farmingCenter = [ +export const farmingCenterABI = [ { inputs: [ { @@ -389,4 +389,4 @@ export const farmingCenter = [ stateMutability: 'view', type: 'function', }, -]; +] as const; diff --git a/wagmi.config.ts b/wagmi.config.ts index a9b2766..e54ac65 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -1,54 +1,82 @@ -import { ContractConfig, defineConfig } from '@wagmi/cli' -import { actions, react } from '@wagmi/cli/plugins' -import { ALGEBRA_FACTORY, ALGEBRA_POSITION_MANAGER, ALGEBRA_QUOTER, ALGEBRA_QUOTER_V2, ALGEBRA_ROUTER } from './src/constants/addresses' -import { algebraFactoryABI, algebraPoolABI, algebraPositionManagerABI, algebraQuoterABI, algebraBasePluginABI, algebraRouterABI, algebraQuoterV2ABI } from './src/abis' +import { ContractConfig, defineConfig } from '@wagmi/cli'; +import { actions, react } from '@wagmi/cli/plugins'; +import { + ALGEBRA_ETERNAL_FARMING, + ALGEBRA_FACTORY, + ALGEBRA_POSITION_MANAGER, + ALGEBRA_QUOTER, + ALGEBRA_QUOTER_V2, + ALGEBRA_ROUTER, + FARMING_CENTER, +} from './src/constants/addresses'; +import { + algebraFactoryABI, + algebraPoolABI, + algebraPositionManagerABI, + algebraQuoterABI, + algebraBasePluginABI, + algebraRouterABI, + algebraQuoterV2ABI, + algebraEternalFarmingABI, + farmingCenterABI, +} from './src/abis'; const contracts: ContractConfig[] = [ - { - address: ALGEBRA_FACTORY, - abi: algebraFactoryABI, - name: 'AlgebraFactory' - }, - { - abi: algebraPoolABI, - name: 'AlgebraPool' - }, - { - abi: algebraBasePluginABI, - name: 'AlgebraBasePlugin' - }, - { - address: ALGEBRA_POSITION_MANAGER, - abi: algebraPositionManagerABI, - name: 'AlgebraPositionManager' - }, - { - address: ALGEBRA_QUOTER, - abi: algebraQuoterABI, - name: 'AlgebraQuoter' - }, - { - address: ALGEBRA_QUOTER_V2, - abi: algebraQuoterV2ABI, - name: 'AlgerbaQuoterV2' - }, - { - address: ALGEBRA_ROUTER, - abi: algebraRouterABI, - name: 'AlgebraRouter' - } -] + { + address: ALGEBRA_FACTORY, + abi: algebraFactoryABI, + name: 'AlgebraFactory', + }, + { + abi: algebraPoolABI, + name: 'AlgebraPool', + }, + { + abi: algebraBasePluginABI, + name: 'AlgebraBasePlugin', + }, + { + address: ALGEBRA_POSITION_MANAGER, + abi: algebraPositionManagerABI, + name: 'AlgebraPositionManager', + }, + { + address: ALGEBRA_QUOTER, + abi: algebraQuoterABI, + name: 'AlgebraQuoter', + }, + { + address: ALGEBRA_QUOTER_V2, + abi: algebraQuoterV2ABI, + name: 'AlgerbaQuoterV2', + }, + { + address: ALGEBRA_ROUTER, + abi: algebraRouterABI, + name: 'AlgebraRouter', + }, + { + address: ALGEBRA_ETERNAL_FARMING, + abi: algebraEternalFarmingABI, + name: 'AlgebraEternalFarming', + }, + { + address: FARMING_CENTER, + abi: farmingCenterABI, + name: 'FarmingCenter', + }, +]; export default defineConfig({ - out: 'src/generated.ts', - contracts, - plugins: [ - actions({ - watchContractEvent: false - }), - react({ - useContractEvent: false, - useContractItemEvent: false - }) - ], -}) + out: 'src/generated.ts', + contracts, + plugins: [ + actions({ + watchContractEvent: false, + }), + react({ + useContractEvent: false, + useContractItemEvent: false, + }), + ], +}); From 27ab159439b237d490c2c901b0d0ba235df5e928 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 6 Mar 2024 02:13:55 +0300 Subject: [PATCH 09/47] fix: add farming interface, types fix --- src/components/pool/ActiveFarming/index.tsx | 16 ++++----- src/components/pool/ClosedFarmings/index.tsx | 2 -- src/components/pool/Farmings/index.tsx | 37 +++++++------------- src/hooks/farming/useFarmIntegralActions.ts | 18 +++++----- src/pages/Pool/index.tsx | 24 +++++++------ src/types/farming-info.ts | 12 +++++++ 6 files changed, 56 insertions(+), 53 deletions(-) create mode 100644 src/types/farming-info.ts diff --git a/src/components/pool/ActiveFarming/index.tsx b/src/components/pool/ActiveFarming/index.tsx index 2259aab..1d10bf5 100644 --- a/src/components/pool/ActiveFarming/index.tsx +++ b/src/components/pool/ActiveFarming/index.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; -import { Farming } from '../Farmings'; import { isSameRewards } from '@/utils/farming/isSameRewards'; import { Deposit } from '@/graphql/generated/graphql'; +import { Farming } from '@/types/farming-info'; interface ActiveFarmingProps { farming: Farming; @@ -10,7 +10,7 @@ interface ActiveFarmingProps { } const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => { - const isSameReward = farming ? isSameRewards(farming?.farming) : false; + const isSameReward = farming ? isSameRewards(farming.farming) : false; return (
@@ -20,26 +20,26 @@ const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => { {isSameReward ? ( <>

- Token - {farming?.rewardToken?.name} + Token - {farming.rewardToken.name}

- Reward Pool - {farming?.farming?.reward / 10 ** 18} + Reward Pool - {farming.farming.reward / 10 ** 18}

) : ( <>

- Token - {farming?.rewardToken?.name} + Token - {farming.rewardToken.name}

- Reward - {farming?.farming?.reward / 10 ** 18} + Reward - {farming.farming.reward / 10 ** 18}

- Bonus Token - {farming?.bonusRewardToken?.name} + Bonus Token - {farming.bonusRewardToken.name}

Bonus Reward -{' '} - {farming?.farming?.bonusReward / 10 ** 18} + {farming.farming.bonusReward / 10 ** 18}

)} diff --git a/src/components/pool/ClosedFarmings/index.tsx b/src/components/pool/ClosedFarmings/index.tsx index fc89860..024b4d0 100644 --- a/src/components/pool/ClosedFarmings/index.tsx +++ b/src/components/pool/ClosedFarmings/index.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { Farming } from '../Farmings'; import { EternalFarming } from '@/graphql/generated/graphql'; interface ActiveFarmingProps { @@ -7,7 +6,6 @@ interface ActiveFarmingProps { } const ClosedFarmings = ({ farmings }: ActiveFarmingProps) => { - console.log(farmings); return (
Closed Farmings diff --git a/src/components/pool/Farmings/index.tsx b/src/components/pool/Farmings/index.tsx index 503429c..6baff99 100644 --- a/src/components/pool/Farmings/index.tsx +++ b/src/components/pool/Farmings/index.tsx @@ -1,35 +1,22 @@ import React, { useEffect, useState } from 'react'; -import MyPositions from '../MyPositions'; import { useEternalFarmingsQuery, useSingleTokenQuery, useDepositsQuery, SinglePoolQuery, - Deposit, - EternalFarming, - SingleTokenQuery, } from '@/graphql/generated/graphql'; import { useClients } from '@/hooks/graphql/useClients'; import { Address, useAccount } from 'wagmi'; -import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; -import { isSameRewards } from '@/utils/farming/isSameRewards'; -import { Token } from 'graphql'; import ActiveFarming from '../ActiveFarming'; import FarmRewards from '../FarmRewards'; import ClosedFarmings from '../ClosedFarmings'; +import { Farming } from '@/types/farming-info'; interface FarmingsProps { poolId: Address; poolInfo: SinglePoolQuery; } -export interface Farming { - farming: EternalFarming; - rewardToken: SingleTokenQuery['token']; - bonusRewardToken: SingleTokenQuery['token']; - pool: SinglePoolQuery; -} - const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { const { address: account } = useAccount(); @@ -71,18 +58,20 @@ const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { if (!activeFarming) { console.error('Active farming not found'); + return; } setFarmingInfo({ - farming: { ...activeFarming }, - rewardToken: { ...rewardToken.token }, - bonusRewardToken: { ...bonusRewardToken.token }, - ...poolInfo, + farming: activeFarming, + rewardToken: rewardToken.token, + bonusRewardToken: bonusRewardToken.token, + pool: poolInfo.pool, }); }, [farmings, rewardToken, bonusRewardToken, poolInfo]); useEffect(() => { - console.log(farmingInfo); + if (!farmingInfo) return; + console.log('Active Farming - ', farmingInfo); }, [farmingInfo]); // All positions for current pool @@ -94,14 +83,14 @@ const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { client: farmingClient, }); - // useEffect(() => { - // if (!deposits) return; - // console.log(deposits); - // }, [deposits]); + useEffect(() => { + if (!deposits) return; + console.log('Deposits - ', deposits.deposits); + }, [deposits]); return (
- {isLoading ? ( + {isLoading || !deposits || !farmingInfo || !closedFarmings ? (
Loading...
) : ( <> diff --git a/src/hooks/farming/useFarmIntegralActions.ts b/src/hooks/farming/useFarmIntegralActions.ts index 2bb7213..9ae5ffe 100644 --- a/src/hooks/farming/useFarmIntegralActions.ts +++ b/src/hooks/farming/useFarmIntegralActions.ts @@ -1,3 +1,10 @@ +import { useToast } from '@/components/ui/use-toast'; +import { + useAlgebraPositionManagerApproveForFarming, + useFarmingCenterEnterFarming, +} from '@/generated'; +import { useAccount } from 'wagmi'; + interface FarmIntegralActionContainerChildrenProps { onApprove: () => void; onStake: () => void; @@ -19,16 +26,11 @@ const useFarmIntegralActions = ({ pool: string; nonce: string; }): FarmIntegralActionContainerChildrenProps => { - const { t } = useTranslation(); - const { toastSuccess } = useToast(); + // const toast = useToast(); const { address: account } = useAccount(); - const signer = useEthersSigner(); - - const gasPrice = useGasPrice(); - const { loading, fetchWithCatchTxError } = useCatchTxError(); - const algebraFarmingCenter = useAlgebraFarmingCenterContract(); - const algebraPositionManager = useAlgebraPositionManagerContract(); + const { data: hash, writeAsync: approveForFarming } = + useAlgebraPositionManagerApproveForFarming(); const onApprove = useCallback(async () => { const calldata = algebraPositionManager.interface.encodeFunctionData( diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index b23fd4c..ffd711f 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -7,14 +7,10 @@ import PositionCard from '@/components/position/PositionCard'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; import { - useDepositsQuery, - useEternalFarmingsQuery, useNativePriceQuery, usePoolFeeDataQuery, useSinglePoolQuery, - useSingleTokenQuery, } from '@/graphql/generated/graphql'; -import { useClients } from '@/hooks/graphql/useClients'; import { usePool } from '@/hooks/pools/usePool'; import { usePositions } from '@/hooks/positions/usePositions'; import { FormattedPosition } from '@/types/formatted-position'; @@ -201,13 +197,19 @@ const PoolPage = () => { ) } /> -

- Farmings -

- + {poolInfo ? ( +
+

+ Farmings +

+ +
+ ) : ( + + )} )}
diff --git a/src/types/farming-info.ts b/src/types/farming-info.ts new file mode 100644 index 0000000..e9357b1 --- /dev/null +++ b/src/types/farming-info.ts @@ -0,0 +1,12 @@ +import { + EternalFarming, + SinglePoolQuery, + SingleTokenQuery, +} from '@/graphql/generated/graphql'; + +export interface Farming { + farming: EternalFarming; + rewardToken: SingleTokenQuery['token']; + bonusRewardToken: SingleTokenQuery['token']; + pool: SinglePoolQuery['pool']; +} From 92c95771f0bbce9d70ec898e61ec6a6dfbd04024 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 6 Mar 2024 18:49:11 +0300 Subject: [PATCH 10/47] add: farming handlers, approve + deposit funcs to selector modal, style selector modal --- .../modals/SelectPositionFarmModal/index.tsx | 99 ++- src/hooks/farming/useFarmIntegralActions.ts | 563 +++++++++--------- src/hooks/farming/useFarmIntegralApprove.ts | 20 + 3 files changed, 383 insertions(+), 299 deletions(-) create mode 100644 src/hooks/farming/useFarmIntegralApprove.ts diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index 391f521..e83a85a 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -1,4 +1,5 @@ import Loader from '@/components/common/Loader'; +import FarmingPositionCard from '@/components/farming/FarmingPositionCard'; import { Button } from '@/components/ui/button'; import { Dialog, @@ -8,23 +9,51 @@ import { DialogTrigger, } from '@/components/ui/dialog'; import { Deposit } from '@/graphql/generated/graphql'; +import useFarmIntegralActions from '@/hooks/farming/useFarmIntegralActions'; +import { useFarmIntegralApprove } from '@/hooks/farming/useFarmIntegralApprove'; +import { cn } from '@/lib/utils'; +import { Farming } from '@/types/farming-info'; +import { useState } from 'react'; interface SelectPositionFarmModalProps { positions: Deposit[]; + farming: Farming; } export function SelectPositionFarmModal({ positions, + farming, }: SelectPositionFarmModalProps) { + const [selectedPosition, setSelectedPosition] = useState(); + const tokenId = selectedPosition ? BigInt(selectedPosition.id) : 0n; + + const { onApprove, onStake } = useFarmIntegralActions({ + tokenId, + rewardToken: farming.farming.rewardToken, + bonusRewardToken: farming.farming.bonusRewardToken, + pool: farming.farming.pool, + nonce: farming.farming.nonce, + }); + + const { approved, isLoading } = useFarmIntegralApprove(tokenId); + + const handleApprove = async () => { + if (approved) return; + onApprove(); + }; + + const handleStake = async () => { + if (!approved) return; + onStake(); + }; + return ( - + @@ -33,18 +62,60 @@ export function SelectPositionFarmModal({ -
    +
      {positions && - positions.map((position) => ( -
    • -

      {position.id}.

      -

      {position.liquidity / 10 ** 18}

      -
    • - ))} + positions.map((position) => { + if (position.eternalFarming !== null) return; + return ( + + setSelectedPosition(position) + } + position={position} + status="In range" + /> + ); + })}
    +
    + {isLoading ? ( + + ) : selectedPosition ? ( + <> + + + + ) : ( + + )} +
); diff --git a/src/hooks/farming/useFarmIntegralActions.ts b/src/hooks/farming/useFarmIntegralActions.ts index 9ae5ffe..201199b 100644 --- a/src/hooks/farming/useFarmIntegralActions.ts +++ b/src/hooks/farming/useFarmIntegralActions.ts @@ -1,4 +1,6 @@ -import { useToast } from '@/components/ui/use-toast'; +import { useCallback } from 'react'; +import { toast } from '@/components/ui/use-toast'; +import { FARMING_CENTER } from '@/constants/addresses'; import { useAlgebraPositionManagerApproveForFarming, useFarmingCenterEnterFarming, @@ -8,9 +10,9 @@ import { useAccount } from 'wagmi'; interface FarmIntegralActionContainerChildrenProps { onApprove: () => void; onStake: () => void; - onUnstake: () => void; - onHarvest: () => void; - onHarvestAll: (calldatas: string[]) => void; + onUnstake?: () => void; + onHarvest?: () => void; + onHarvestAll?: (calldatas: string[]) => void; } const useFarmIntegralActions = ({ @@ -20,303 +22,294 @@ const useFarmIntegralActions = ({ pool, nonce, }: { - tokenId: string; - rewardToken: string; - bonusRewardToken: string; - pool: string; - nonce: string; + tokenId: bigint; + rewardToken: `0x${string}`; + bonusRewardToken: `0x${string}`; + pool: `0x${string}`; + nonce: bigint; }): FarmIntegralActionContainerChildrenProps => { - // const toast = useToast(); const { address: account } = useAccount(); - const { data: hash, writeAsync: approveForFarming } = + const { writeAsync: approveForFarming } = useAlgebraPositionManagerApproveForFarming(); + const { writeAsync: enterFarming } = useFarmingCenterEnterFarming(); + const onApprove = useCallback(async () => { - const calldata = algebraPositionManager.interface.encodeFunctionData( - 'approveForFarming', - [tokenId, true, algebraFarmingCenter.address] - ); - - const txn = { - to: algebraPositionManager.address, - data: calldata, - }; - - const resp = await fetchWithCatchTxError(() => - signer.estimateGas(txn).then((estimate) => { - const newTxn = { - ...txn, - gasPrice, - gasLimit: calculateGasMargin(estimate), - }; - - return signer.sendTransaction(newTxn); - }) - ); - if (resp?.status) { - toastSuccess( - `${t('Approved')}!`, - - {t('Position was approved for farming')} - - ); + try { + console.log(`Approving for ID ${tokenId}`); + + const { hash } = await approveForFarming({ + args: [tokenId, true, FARMING_CENTER], + }); + + toast({ + title: 'Approved!', + description: `Position #${tokenId} was approved for farming!`, + }); + } catch (error) { + console.error('Approval failed:', error); } - }, [ - account, - fetchWithCatchTxError, - signer, - t, - algebraPositionManager, - algebraFarmingCenter, - toastSuccess, - tokenId, - ]); - - const onUnstake = useCallback(async () => { - const callDatas = [ - algebraFarmingCenter.interface.encodeFunctionData('exitFarming', [ - { rewardToken, bonusRewardToken, pool, nonce }, - tokenId, - ]), - algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ - rewardToken, - account, - MaxUint128, - ]), - algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ - bonusRewardToken, - account, - MaxUint128, - ]), - ]; - - const calldata = algebraFarmingCenter.interface.encodeFunctionData( - 'multicall', - [callDatas] - ); - - const txn = { - to: algebraFarmingCenter.address, - data: calldata, - }; - - const resp = await fetchWithCatchTxError(() => - signer.estimateGas(txn).then((estimate) => { - const newTxn = { - ...txn, - gasPrice, - gasLimit: calculateGasMargin(estimate), - }; - - return signer.sendTransaction(newTxn); - }) - ); - if (resp?.status) { - toastSuccess( - `${t('Unstaked')}!`, - - {t('Your earnings have also been harvested to your wallet')} - - ); - } - }, [ - account, - fetchWithCatchTxError, - algebraFarmingCenter, - signer, - t, - toastSuccess, - rewardToken, - tokenId, - ]); + }, [approveForFarming, tokenId, account]); const onStake = useCallback(async () => { - const calldata = algebraFarmingCenter.interface.encodeFunctionData( - 'enterFarming', - [ - { - rewardToken, - bonusRewardToken, - pool, - nonce, - }, - tokenId, - ] - ); - - const txn = { - to: algebraFarmingCenter.address, - data: calldata, - }; - - const resp = await fetchWithCatchTxError(() => - signer.estimateGas(txn).then((estimate) => { - const newTxn = { - ...txn, - gasPrice, - gasLimit: calculateGasMargin(estimate), - }; - - return signer.sendTransaction(newTxn); - }) - ); - - if (resp?.status) { - toastSuccess( - `${t('Staked')}!`, - - {t('Your funds have been staked in the farm')} - - ); - } - }, [ - account, - fetchWithCatchTxError, - algebraFarmingCenter, - signer, - t, - toastSuccess, - rewardToken, - tokenId, - ]); - - const onHarvest = useCallback(async () => { - const collectRewards = - algebraFarmingCenter.interface.encodeFunctionData( - 'collectRewards', - [{ rewardToken, bonusRewardToken, pool, nonce }, tokenId] - ); - const claimReward1 = algebraFarmingCenter.interface.encodeFunctionData( - 'claimReward', - [rewardToken, account, MaxUint128] - ); - const claimReward2 = algebraFarmingCenter.interface.encodeFunctionData( - 'claimReward', - [bonusRewardToken, account, MaxUint128] - ); - - let calldata; - - if (rewardToken.toLowerCase() !== bonusRewardToken.toLowerCase()) { - calldata = [collectRewards, claimReward1, claimReward2]; - } else { - calldata = [collectRewards, claimReward1]; - } - - const mcall = algebraFarmingCenter.interface.encodeFunctionData( - 'multicall', - [calldata] - ); - - const txn = { - to: algebraFarmingCenter.address, - data: mcall, - }; - - const resp = await fetchWithCatchTxError(() => - signer.estimateGas(txn).then((estimate) => { - const newTxn = { - ...txn, - gasPrice, - gasLimit: calculateGasMargin(estimate), - }; - - return signer.sendTransaction(newTxn); - }) - ); - - if (resp?.status) { - toastSuccess( - `${t('Harvested')}!`, - - {t('Earnings have been sent to your wallet!')} - - ); - // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) + try { + console.log(`Staking ID ${tokenId}`); + const data = await enterFarming({ + args: [ + { + rewardToken, + bonusRewardToken, + pool, + nonce, + }, + tokenId, + ], + }); + console.log(data); + toast({ + title: 'Staked!', + description: `Position #${tokenId} was staked for farming!`, + }); + } catch (error) { + console.error('Approval failed:', error); } }, [ account, - fetchWithCatchTxError, - algebraFarmingCenter, - signer, - t, - toastSuccess, rewardToken, tokenId, + bonusRewardToken, + pool, + nonce, + enterFarming, ]); - const onHarvestAll = useCallback( - async (calldatas: string[]) => { - const calldata = algebraFarmingCenter.interface.encodeFunctionData( - 'multicall', - [calldatas] - ); - - const txn = { - to: algebraFarmingCenter.address, - data: calldata, - }; - - const resp = await fetchWithCatchTxError(() => - signer.estimateGas(txn).then((estimate) => { - const newTxn = { - ...txn, - gasPrice, - gasLimit: calculateGasMargin(estimate), - }; - - return signer.sendTransaction(newTxn); - }) - ); - - if (resp?.status) { - toastSuccess( - `${t('Harvested')}!`, - - {t('Earnings have been sent to your wallet!')} - - ); - // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) - } - }, - [ - account, - fetchWithCatchTxError, - algebraFarmingCenter, - signer, - t, - toastSuccess, - rewardToken, - tokenId, - ] - ); - - return { - attemptingTxn: loading, - onApprove, - onStake, - onUnstake, - onHarvest, - onHarvestAll, - }; + return { onApprove, onStake }; + + // const onApprove = useCallback(async () => { + // // const resp = await fetchWithCatchTxError(() => + // // signer.estimateGas(txn).then((estimate) => { + // // const newTxn = { + // // ...txn, + // // gasPrice, + // // gasLimit: calculateGasMargin(estimate), + // // }; + // // return signer.sendTransaction(newTxn); + // // }) + // // ); + // // if (resp?.status) { + // // toastSuccess( + // // `${t('Approved')}!`, + // // + // // {t('Position was approved for farming')} + // // + // // ); + // // } + // }, [ + // account, + // fetchWithCatchTxError, + // signer, + // t, + // algebraPositionManager, + // algebraFarmingCenter, + // toastSuccess, + // tokenId, + // ]); + + // const onUnstake = useCallback(async () => { + // const callDatas = [ + // algebraFarmingCenter.interface.encodeFunctionData('exitFarming', [ + // { rewardToken, bonusRewardToken, pool, nonce }, + // tokenId, + // ]), + // algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ + // rewardToken, + // account, + // MaxUint128, + // ]), + // algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ + // bonusRewardToken, + // account, + // MaxUint128, + // ]), + // ]; + + // const calldata = algebraFarmingCenter.interface.encodeFunctionData( + // 'multicall', + // [callDatas] + // ); + + // const txn = { + // to: algebraFarmingCenter.address, + // data: calldata, + // }; + + // const resp = await fetchWithCatchTxError(() => + // signer.estimateGas(txn).then((estimate) => { + // const newTxn = { + // ...txn, + // gasPrice, + // gasLimit: calculateGasMargin(estimate), + // }; + + // return signer.sendTransaction(newTxn); + // }) + // ); + // if (resp?.status) { + // toastSuccess( + // `${t('Unstaked')}!`, + // + // {t('Your earnings have also been harvested to your wallet')} + // + // ); + // } + // }, [ + // account, + // fetchWithCatchTxError, + // algebraFarmingCenter, + // signer, + // t, + // toastSuccess, + // rewardToken, + // tokenId, + // ]); + + // const onHarvest = useCallback(async () => { + // const collectRewards = + // algebraFarmingCenter.interface.encodeFunctionData( + // 'collectRewards', + // [{ rewardToken, bonusRewardToken, pool, nonce }, tokenId] + // ); + // const claimReward1 = algebraFarmingCenter.interface.encodeFunctionData( + // 'claimReward', + // [rewardToken, account, MaxUint128] + // ); + // const claimReward2 = algebraFarmingCenter.interface.encodeFunctionData( + // 'claimReward', + // [bonusRewardToken, account, MaxUint128] + // ); + + // let calldata; + + // if (rewardToken.toLowerCase() !== bonusRewardToken.toLowerCase()) { + // calldata = [collectRewards, claimReward1, claimReward2]; + // } else { + // calldata = [collectRewards, claimReward1]; + // } + + // const mcall = algebraFarmingCenter.interface.encodeFunctionData( + // 'multicall', + // [calldata] + // ); + + // const txn = { + // to: algebraFarmingCenter.address, + // data: mcall, + // }; + + // const resp = await fetchWithCatchTxError(() => + // signer.estimateGas(txn).then((estimate) => { + // const newTxn = { + // ...txn, + // gasPrice, + // gasLimit: calculateGasMargin(estimate), + // }; + + // return signer.sendTransaction(newTxn); + // }) + // ); + + // if (resp?.status) { + // toastSuccess( + // `${t('Harvested')}!`, + // + // {t('Earnings have been sent to your wallet!')} + // + // ); + // // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) + // } + // }, [ + // account, + // fetchWithCatchTxError, + // algebraFarmingCenter, + // signer, + // t, + // toastSuccess, + // rewardToken, + // tokenId, + // ]); + + // const onHarvestAll = useCallback( + // async (calldatas: string[]) => { + // const calldata = algebraFarmingCenter.interface.encodeFunctionData( + // 'multicall', + // [calldatas] + // ); + + // const txn = { + // to: algebraFarmingCenter.address, + // data: calldata, + // }; + + // const resp = await fetchWithCatchTxError(() => + // signer.estimateGas(txn).then((estimate) => { + // const newTxn = { + // ...txn, + // gasPrice, + // gasLimit: calculateGasMargin(estimate), + // }; + + // return signer.sendTransaction(newTxn); + // }) + // ); + + // if (resp?.status) { + // toastSuccess( + // `${t('Harvested')}!`, + // + // {t('Earnings have been sent to your wallet!')} + // + // ); + // // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) + // } + // }, + // [ + // account, + // fetchWithCatchTxError, + // algebraFarmingCenter, + // signer, + // t, + // toastSuccess, + // rewardToken, + // tokenId, + // ] + // ); + + // return { + // attemptingTxn: loading, + // onApprove, + // onStake, + // onUnstake, + // onHarvest, + // onHarvestAll, + // }; + // }; + + // export function useFarmIntegralApprove(tokenId: string) { + // const [approve, setApprove] = useState(); + + // const algebraPositionManager = useAlgebraPositionManagerContract(); + + // useEffect(() => { + // algebraPositionManager.callStatic + // .farmingApprovals(tokenId) + // .then((approval) => setApprove(approval !== ADDRESS_ZERO)); + // }); + + // return { + // approve, + // isLoading: approve === undefined, + // }; }; -export function useFarmIntegralApprove(tokenId: string) { - const [approve, setApprove] = useState(); - - const algebraPositionManager = useAlgebraPositionManagerContract(); - - useEffect(() => { - algebraPositionManager.callStatic - .farmingApprovals(tokenId) - .then((approval) => setApprove(approval !== ADDRESS_ZERO)); - }); - - return { - approve, - isLoading: approve === undefined, - }; -} - export default useFarmIntegralActions; diff --git a/src/hooks/farming/useFarmIntegralApprove.ts b/src/hooks/farming/useFarmIntegralApprove.ts new file mode 100644 index 0000000..3344096 --- /dev/null +++ b/src/hooks/farming/useFarmIntegralApprove.ts @@ -0,0 +1,20 @@ +import { useAlgebraPositionManagerFarmingApprovals } from '@/generated'; +import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; +import { useEffect, useState } from 'react'; + +export function useFarmIntegralApprove(tokenId: bigint) { + const [approved, setApproved] = useState(); + + const { data } = useAlgebraPositionManagerFarmingApprovals({ + args: [tokenId], + }); + + useEffect(() => { + setApproved(data !== ADDRESS_ZERO); + }, [tokenId, data]); + + return { + approved, + isLoading: approved === undefined, + }; +} From d6c8e66a98bb605d4c68da5dc2f2e6dbdc9efc6a Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 6 Mar 2024 18:50:35 +0300 Subject: [PATCH 11/47] refactor: move farmings components to farming folder --- .../farming/ActiveFarming/index.tsx | 87 +++++++++++++++++++ .../ClosedFarmings/index.tsx | 0 .../{pool => farming}/FarmRewards/index.tsx | 0 .../farming/FarmingPositionCard/index.tsx | 37 ++++++++ .../{pool => farming}/Farmings/index.tsx | 16 ++-- src/components/pool/ActiveFarming/index.tsx | 52 ----------- src/components/pool/PoolHeader/index.tsx | 55 ++++++------ 7 files changed, 161 insertions(+), 86 deletions(-) create mode 100644 src/components/farming/ActiveFarming/index.tsx rename src/components/{pool => farming}/ClosedFarmings/index.tsx (100%) rename src/components/{pool => farming}/FarmRewards/index.tsx (100%) create mode 100644 src/components/farming/FarmingPositionCard/index.tsx rename src/components/{pool => farming}/Farmings/index.tsx (86%) delete mode 100644 src/components/pool/ActiveFarming/index.tsx diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx new file mode 100644 index 0000000..e180a63 --- /dev/null +++ b/src/components/farming/ActiveFarming/index.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; +import { isSameRewards } from '@/utils/farming/isSameRewards'; +import { Deposit } from '@/graphql/generated/graphql'; +import { Farming } from '@/types/farming-info'; +import { Button } from '@/components/ui/button'; +import CardInfo from '@/components/common/CardInfo'; +import { formatUnits } from 'viem'; + +interface ActiveFarmingProps { + farming: Farming; + deposits: Deposit[]; +} + +const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => { + const isSameReward = isSameRewards(farming.farming); + + const rewardRatePerDay = + Number( + formatUnits( + farming.farming.rewardRate, + farming.rewardToken.decimals + ) + ) * + 60 * + 60 * + 24; + + const bonusRewardRatePerDay = isSameReward + ? 0 + : Number( + formatUnits( + farming.farming.bonusRewardRate, + farming.bonusRewardToken.decimals + ) + ) * + 60 * + 60 * + 24; + + return ( +
+
+
+ +

45%

+
+ +

$100

+
+
+ +

$12

+
+
+ + +
+

+ {rewardRatePerDay + ' ' + farming.rewardToken.symbol} / + day +

+ {bonusRewardRatePerDay !== 0 && ( +

+ {bonusRewardRatePerDay}{' '} + {farming.bonusRewardToken.symbol} / day +

+ )} +
+
+ +
+ + +
+
+ ); +}; + +export default ActiveFarming; diff --git a/src/components/pool/ClosedFarmings/index.tsx b/src/components/farming/ClosedFarmings/index.tsx similarity index 100% rename from src/components/pool/ClosedFarmings/index.tsx rename to src/components/farming/ClosedFarmings/index.tsx diff --git a/src/components/pool/FarmRewards/index.tsx b/src/components/farming/FarmRewards/index.tsx similarity index 100% rename from src/components/pool/FarmRewards/index.tsx rename to src/components/farming/FarmRewards/index.tsx diff --git a/src/components/farming/FarmingPositionCard/index.tsx b/src/components/farming/FarmingPositionCard/index.tsx new file mode 100644 index 0000000..2e80475 --- /dev/null +++ b/src/components/farming/FarmingPositionCard/index.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Deposit } from '@/graphql/generated/graphql'; +import { cn } from '@/lib/utils'; + +interface FarmingPositionCardProps { + position: Deposit; + status: string; + className: string; + onClick: () => void; +} + +const FarmingPositionCard = ({ + position, + status, + className, + onClick, +}: FarmingPositionCardProps) => { + return ( +
+
+ {position.id} +
+
+

Position #{position.id}

+

{status}

+
+
+ ); +}; + +export default FarmingPositionCard; diff --git a/src/components/pool/Farmings/index.tsx b/src/components/farming/Farmings/index.tsx similarity index 86% rename from src/components/pool/Farmings/index.tsx rename to src/components/farming/Farmings/index.tsx index 6baff99..1c427db 100644 --- a/src/components/pool/Farmings/index.tsx +++ b/src/components/farming/Farmings/index.tsx @@ -11,6 +11,7 @@ import ActiveFarming from '../ActiveFarming'; import FarmRewards from '../FarmRewards'; import ClosedFarmings from '../ClosedFarmings'; import { Farming } from '@/types/farming-info'; +import { Loader } from 'lucide-react'; interface FarmingsProps { poolId: Address; @@ -40,12 +41,14 @@ const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { ); const { data: rewardToken } = useSingleTokenQuery({ + skip: !activeFarming, variables: { tokenId: activeFarming?.rewardToken, }, }); const { data: bonusRewardToken } = useSingleTokenQuery({ + skip: !activeFarming, variables: { tokenId: activeFarming?.bonusRewardToken, }, @@ -61,10 +64,11 @@ const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { return; } + // ! disabled null check setFarmingInfo({ farming: activeFarming, - rewardToken: rewardToken.token, - bonusRewardToken: bonusRewardToken.token, + rewardToken: rewardToken.token!, + bonusRewardToken: bonusRewardToken.token!, pool: poolInfo.pool, }); }, [farmings, rewardToken, bonusRewardToken, poolInfo]); @@ -89,17 +93,17 @@ const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { }, [deposits]); return ( -
+
{isLoading || !deposits || !farmingInfo || !closedFarmings ? ( -
Loading...
+ ) : ( <> - - + {/* + */} )}
diff --git a/src/components/pool/ActiveFarming/index.tsx b/src/components/pool/ActiveFarming/index.tsx deleted file mode 100644 index 1d10bf5..0000000 --- a/src/components/pool/ActiveFarming/index.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react'; -import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; -import { isSameRewards } from '@/utils/farming/isSameRewards'; -import { Deposit } from '@/graphql/generated/graphql'; -import { Farming } from '@/types/farming-info'; - -interface ActiveFarmingProps { - farming: Farming; - deposits: Deposit[]; -} - -const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => { - const isSameReward = farming ? isSameRewards(farming.farming) : false; - - return ( -
- Active Farm -
-

APR -

- {isSameReward ? ( - <> -

- Token - {farming.rewardToken.name} -

-

- Reward Pool - {farming.farming.reward / 10 ** 18} -

- - ) : ( - <> -

- Token - {farming.rewardToken.name} -

-

- Reward - {farming.farming.reward / 10 ** 18} -

-

- Bonus Token - {farming.bonusRewardToken.name} -

-

- Bonus Reward -{' '} - {farming.farming.bonusReward / 10 ** 18} -

- - )} -
- -
- ); -}; - -export default ActiveFarming; diff --git a/src/components/pool/PoolHeader/index.tsx b/src/components/pool/PoolHeader/index.tsx index 5a6e881..a59f07a 100644 --- a/src/components/pool/PoolHeader/index.tsx +++ b/src/components/pool/PoolHeader/index.tsx @@ -1,35 +1,34 @@ -import CurrencyLogo from "@/components/common/CurrencyLogo" -import PageTitle from "@/components/common/PageTitle" -import { Skeleton } from "@/components/ui/skeleton" -import { formatPercent } from "@/utils/common/formatPercent" -import { Pool } from "@cryptoalgebra/integral-sdk" +import CurrencyLogo from '@/components/common/CurrencyLogo'; +import PageTitle from '@/components/common/PageTitle'; +import { Skeleton } from '@/components/ui/skeleton'; +import { formatPercent } from '@/utils/common/formatPercent'; +import { Pool } from '@cryptoalgebra/integral-sdk'; interface PoolHeaderProps { - pool: Pool | null + pool: Pool | null; } const PoolHeader = ({ pool }: PoolHeaderProps) => { - - const [token0, token1] = pool ? [pool.token0, pool.token1] : [] - - const poolFee = pool && formatPercent.format(pool.fee / 10_00000) - - return
- -
- - + const [token0, token1] = pool ? [pool.token0, pool.token1] : []; + + const poolFee = pool && formatPercent.format(pool.fee / 10_00000); + + return ( +
+
+ + +
+ + {token0 && token1 ? ( + + {`${poolFee}`} + + ) : ( + + )}
+ ); +}; - {token0 && token1 ? - - {`${poolFee}`} - - : - } - -
- -} - -export default PoolHeader; \ No newline at end of file +export default PoolHeader; From fd9f7b30a5770970a520c54528095104dd69beeb Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 6 Mar 2024 18:52:35 +0300 Subject: [PATCH 12/47] add: create reusable CardInfo component --- src/components/common/CardInfo/index.tsx | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/components/common/CardInfo/index.tsx diff --git a/src/components/common/CardInfo/index.tsx b/src/components/common/CardInfo/index.tsx new file mode 100644 index 0000000..b69fae2 --- /dev/null +++ b/src/components/common/CardInfo/index.tsx @@ -0,0 +1,35 @@ +import { cn } from '@/lib/utils'; +import React, { FC } from 'react'; + +interface CardInfoProps { + title: string; + additional?: string; + className?: string; + children?: React.ReactNode; +} + +const CardInfo: FC = ({ + title, + children, + additional, + className, +}) => { + return ( +
+

{title}

+
+
+ {children} +
+ {additional &&

{additional}

} +
+
+ ); +}; + +export default CardInfo; From deee8d7eb55bb66d198c0fe0c23eada2b01a8d3a Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 6 Mar 2024 18:53:44 +0300 Subject: [PATCH 13/47] chore: minor fix, add abstract utils --- src/pages/Pool/index.tsx | 2 +- src/types/farming-info.ts | 6 ++-- src/utils/farming/getFarmingAPR.ts | 0 src/utils/farming/getFarmingRewards.ts | 46 ++++++++++++++++++++++++++ src/utils/farming/isSameRewards.ts | 2 +- 5 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/utils/farming/getFarmingAPR.ts create mode 100644 src/utils/farming/getFarmingRewards.ts diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index ffd711f..d2a99cf 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -1,5 +1,5 @@ import PageContainer from '@/components/common/PageContainer'; -import Farmings from '@/components/pool/Farmings'; +import Farmings from '@/components/farming/Farmings'; import MyPositions from '@/components/pool/MyPositions'; import MyPositionsToolbar from '@/components/pool/MyPositionsToolbar'; import PoolHeader from '@/components/pool/PoolHeader'; diff --git a/src/types/farming-info.ts b/src/types/farming-info.ts index e9357b1..69f224d 100644 --- a/src/types/farming-info.ts +++ b/src/types/farming-info.ts @@ -1,12 +1,12 @@ import { EternalFarming, SinglePoolQuery, - SingleTokenQuery, + TokenFieldsFragment, } from '@/graphql/generated/graphql'; export interface Farming { farming: EternalFarming; - rewardToken: SingleTokenQuery['token']; - bonusRewardToken: SingleTokenQuery['token']; + rewardToken: TokenFieldsFragment; + bonusRewardToken: TokenFieldsFragment; pool: SinglePoolQuery['pool']; } diff --git a/src/utils/farming/getFarmingAPR.ts b/src/utils/farming/getFarmingAPR.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/farming/getFarmingRewards.ts b/src/utils/farming/getFarmingRewards.ts new file mode 100644 index 0000000..610a873 --- /dev/null +++ b/src/utils/farming/getFarmingRewards.ts @@ -0,0 +1,46 @@ +import { MAX_UINT128 } from '@/constants/max-uint128'; +import { getAlgebraPositionManager } from '@/generated'; +import { + CurrencyAmount, + Pool, + unwrappedToken, +} from '@cryptoalgebra/integral-sdk'; + +export async function getFarmingRewards(pool: Pool, positionId: number) { + try { + const algebraPositionManager = getAlgebraPositionManager({}); + + const owner = await algebraPositionManager.read.ownerOf([ + BigInt(positionId), + ]); + + const { + result: [fees0, fees1], + } = await algebraPositionManager.simulate.collect( + [ + { + tokenId: BigInt(positionId), + recipient: owner, + amount0Max: MAX_UINT128, + amount1Max: MAX_UINT128, + }, + ], + { + account: owner, + } + ); + + return [ + CurrencyAmount.fromRawAmount( + unwrappedToken(pool.token0), + fees0.toString() + ), + CurrencyAmount.fromRawAmount( + unwrappedToken(pool.token1), + fees1.toString() + ), + ]; + } catch { + return [undefined, undefined]; + } +} diff --git a/src/utils/farming/isSameRewards.ts b/src/utils/farming/isSameRewards.ts index d96a5f0..91aeeb7 100644 --- a/src/utils/farming/isSameRewards.ts +++ b/src/utils/farming/isSameRewards.ts @@ -1,5 +1,5 @@ import { EternalFarming } from '@/graphql/generated/graphql'; export const isSameRewards = (farming: EternalFarming) => { - return farming.rewardToken === farming.bonusRewardToken ? true : false; + return farming.rewardToken === farming.bonusRewardToken; }; From 7f385e37b6b40b1b21241387c3b992d918d3bdcf Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 7 Mar 2024 18:33:57 +0300 Subject: [PATCH 14/47] add: onHarvest, onHarvestAll handlers --- src/hooks/farming/useFarmIntegralActions.ts | 375 ++++++++------------ src/utils/farming/getRewardsCalldata.ts | 59 +++ 2 files changed, 200 insertions(+), 234 deletions(-) create mode 100644 src/utils/farming/getRewardsCalldata.ts diff --git a/src/hooks/farming/useFarmIntegralActions.ts b/src/hooks/farming/useFarmIntegralActions.ts index 201199b..cd020bc 100644 --- a/src/hooks/farming/useFarmIntegralActions.ts +++ b/src/hooks/farming/useFarmIntegralActions.ts @@ -2,17 +2,24 @@ import { useCallback } from 'react'; import { toast } from '@/components/ui/use-toast'; import { FARMING_CENTER } from '@/constants/addresses'; import { + farmingCenterABI, useAlgebraPositionManagerApproveForFarming, useFarmingCenterEnterFarming, + useFarmingCenterMulticall, } from '@/generated'; import { useAccount } from 'wagmi'; +import { encodeFunctionData } from 'viem'; +import { waitForTransaction } from 'wagmi/actions'; +import { Deposit } from '@/graphql/generated/graphql'; +import { getRewardsCalldata } from '@/utils/farming/getRewardsCalldata'; +import { ViewTxOnExplorer } from '../common/useTransactionAwait'; interface FarmIntegralActionContainerChildrenProps { onApprove: () => void; onStake: () => void; onUnstake?: () => void; - onHarvest?: () => void; - onHarvestAll?: (calldatas: string[]) => void; + onHarvest: () => void; + onHarvestAll: (deposits: Deposit[]) => void; } const useFarmIntegralActions = ({ @@ -35,6 +42,8 @@ const useFarmIntegralActions = ({ const { writeAsync: enterFarming } = useFarmingCenterEnterFarming(); + const { writeAsync: multicall } = useFarmingCenterMulticall(); + const onApprove = useCallback(async () => { try { console.log(`Approving for ID ${tokenId}`); @@ -44,8 +53,17 @@ const useFarmIntegralActions = ({ }); toast({ - title: 'Approved!', - description: `Position #${tokenId} was approved for farming!`, + title: `Approve Position #${tokenId.toString()}`, + description: `Transaction was sent`, + action: ViewTxOnExplorer({ hash }), + }); + + await waitForTransaction({ hash, confirmations: 1 }); + + toast({ + title: `Approve Position #${tokenId.toString()}`, + description: `Transaction confirmed!`, + action: ViewTxOnExplorer({ hash }), }); } catch (error) { console.error('Approval failed:', error); @@ -55,7 +73,8 @@ const useFarmIntegralActions = ({ const onStake = useCallback(async () => { try { console.log(`Staking ID ${tokenId}`); - const data = await enterFarming({ + + const { hash } = await enterFarming({ args: [ { rewardToken, @@ -66,10 +85,19 @@ const useFarmIntegralActions = ({ tokenId, ], }); - console.log(data); + toast({ - title: 'Staked!', - description: `Position #${tokenId} was staked for farming!`, + title: `Deposit Position #${tokenId.toString()}`, + description: `Transaction was sent`, + action: ViewTxOnExplorer({ hash }), + }); + + await waitForTransaction({ hash, confirmations: 1 }); + + toast({ + title: `Deposit Position #${tokenId.toString()}`, + description: `Transaction confirmed!`, + action: ViewTxOnExplorer({ hash }), }); } catch (error) { console.error('Approval failed:', error); @@ -84,232 +112,111 @@ const useFarmIntegralActions = ({ enterFarming, ]); - return { onApprove, onStake }; - - // const onApprove = useCallback(async () => { - // // const resp = await fetchWithCatchTxError(() => - // // signer.estimateGas(txn).then((estimate) => { - // // const newTxn = { - // // ...txn, - // // gasPrice, - // // gasLimit: calculateGasMargin(estimate), - // // }; - // // return signer.sendTransaction(newTxn); - // // }) - // // ); - // // if (resp?.status) { - // // toastSuccess( - // // `${t('Approved')}!`, - // // - // // {t('Position was approved for farming')} - // // - // // ); - // // } - // }, [ - // account, - // fetchWithCatchTxError, - // signer, - // t, - // algebraPositionManager, - // algebraFarmingCenter, - // toastSuccess, - // tokenId, - // ]); - - // const onUnstake = useCallback(async () => { - // const callDatas = [ - // algebraFarmingCenter.interface.encodeFunctionData('exitFarming', [ - // { rewardToken, bonusRewardToken, pool, nonce }, - // tokenId, - // ]), - // algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ - // rewardToken, - // account, - // MaxUint128, - // ]), - // algebraFarmingCenter.interface.encodeFunctionData('claimReward', [ - // bonusRewardToken, - // account, - // MaxUint128, - // ]), - // ]; - - // const calldata = algebraFarmingCenter.interface.encodeFunctionData( - // 'multicall', - // [callDatas] - // ); - - // const txn = { - // to: algebraFarmingCenter.address, - // data: calldata, - // }; - - // const resp = await fetchWithCatchTxError(() => - // signer.estimateGas(txn).then((estimate) => { - // const newTxn = { - // ...txn, - // gasPrice, - // gasLimit: calculateGasMargin(estimate), - // }; - - // return signer.sendTransaction(newTxn); - // }) - // ); - // if (resp?.status) { - // toastSuccess( - // `${t('Unstaked')}!`, - // - // {t('Your earnings have also been harvested to your wallet')} - // - // ); - // } - // }, [ - // account, - // fetchWithCatchTxError, - // algebraFarmingCenter, - // signer, - // t, - // toastSuccess, - // rewardToken, - // tokenId, - // ]); - - // const onHarvest = useCallback(async () => { - // const collectRewards = - // algebraFarmingCenter.interface.encodeFunctionData( - // 'collectRewards', - // [{ rewardToken, bonusRewardToken, pool, nonce }, tokenId] - // ); - // const claimReward1 = algebraFarmingCenter.interface.encodeFunctionData( - // 'claimReward', - // [rewardToken, account, MaxUint128] - // ); - // const claimReward2 = algebraFarmingCenter.interface.encodeFunctionData( - // 'claimReward', - // [bonusRewardToken, account, MaxUint128] - // ); - - // let calldata; - - // if (rewardToken.toLowerCase() !== bonusRewardToken.toLowerCase()) { - // calldata = [collectRewards, claimReward1, claimReward2]; - // } else { - // calldata = [collectRewards, claimReward1]; - // } - - // const mcall = algebraFarmingCenter.interface.encodeFunctionData( - // 'multicall', - // [calldata] - // ); - - // const txn = { - // to: algebraFarmingCenter.address, - // data: mcall, - // }; - - // const resp = await fetchWithCatchTxError(() => - // signer.estimateGas(txn).then((estimate) => { - // const newTxn = { - // ...txn, - // gasPrice, - // gasLimit: calculateGasMargin(estimate), - // }; - - // return signer.sendTransaction(newTxn); - // }) - // ); - - // if (resp?.status) { - // toastSuccess( - // `${t('Harvested')}!`, - // - // {t('Earnings have been sent to your wallet!')} - // - // ); - // // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) - // } - // }, [ - // account, - // fetchWithCatchTxError, - // algebraFarmingCenter, - // signer, - // t, - // toastSuccess, - // rewardToken, - // tokenId, - // ]); - - // const onHarvestAll = useCallback( - // async (calldatas: string[]) => { - // const calldata = algebraFarmingCenter.interface.encodeFunctionData( - // 'multicall', - // [calldatas] - // ); - - // const txn = { - // to: algebraFarmingCenter.address, - // data: calldata, - // }; - - // const resp = await fetchWithCatchTxError(() => - // signer.estimateGas(txn).then((estimate) => { - // const newTxn = { - // ...txn, - // gasPrice, - // gasLimit: calculateGasMargin(estimate), - // }; - - // return signer.sendTransaction(newTxn); - // }) - // ); - - // if (resp?.status) { - // toastSuccess( - // `${t('Harvested')}!`, - // - // {t('Earnings have been sent to your wallet!')} - // - // ); - // // mutate((key) => Array.isArray(key) && key[0] === 'mcv3-harvest', undefined) - // } - // }, - // [ - // account, - // fetchWithCatchTxError, - // algebraFarmingCenter, - // signer, - // t, - // toastSuccess, - // rewardToken, - // tokenId, - // ] - // ); - - // return { - // attemptingTxn: loading, - // onApprove, - // onStake, - // onUnstake, - // onHarvest, - // onHarvestAll, - // }; - // }; - - // export function useFarmIntegralApprove(tokenId: string) { - // const [approve, setApprove] = useState(); - - // const algebraPositionManager = useAlgebraPositionManagerContract(); - - // useEffect(() => { - // algebraPositionManager.callStatic - // .farmingApprovals(tokenId) - // .then((approval) => setApprove(approval !== ADDRESS_ZERO)); - // }); - - // return { - // approve, - // isLoading: approve === undefined, - // }; + const onHarvest = useCallback(async () => { + try { + if (!account) { + console.error('Account not found'); + return; + } + + console.log(`Harvesting ID ${tokenId}`); + + const calldata = getRewardsCalldata({ + rewardToken, + bonusRewardToken, + pool, + nonce, + tokenId, + account, + }); + + const { hash } = await multicall({ + args: [calldata], + }); + + toast({ + title: `Harvest Position #${tokenId.toString()}`, + description: `Transaction was sent`, + action: ViewTxOnExplorer({ hash }), + }); + + await waitForTransaction({ hash, confirmations: 1 }); + + toast({ + title: `Harvest Position #${tokenId.toString()}`, + description: `Transaction confirmed!`, + action: ViewTxOnExplorer({ hash }), + }); + + console.log(`Harvest confirmed!`, hash); + } catch (error) { + console.error('Harvest failed:', error); + } + }, [ + account, + tokenId, + rewardToken, + bonusRewardToken, + pool, + nonce, + multicall, + ]); + + const onHarvestAll = useCallback( + async (deposits: Deposit[]) => { + try { + if (!account) { + console.error('Account not found'); + return; + } + + const calldatas: `0x${string}`[] = []; + + deposits.forEach((deposit) => { + if (deposit.eternalFarming !== null) { + const rewardsCalldata = getRewardsCalldata({ + rewardToken, + bonusRewardToken, + pool, + nonce, + tokenId: BigInt(deposit.id), + account, + }); + + const calldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'multicall', + args: [rewardsCalldata], + }); + calldatas.push(calldata); + } + }); + + const { hash } = await multicall({ + args: [calldatas], + }); + + toast({ + title: `Harvest All Positions`, + description: `Transaction was sent`, + action: ViewTxOnExplorer({ hash }), + }); + + await waitForTransaction({ hash, confirmations: 1 }); + + toast({ + title: `Harvest All Positions`, + description: `Transaction confirmed!`, + action: ViewTxOnExplorer({ hash }), + }); + } catch (error) { + console.error('Harvest failed:', error); + } + }, + [account, rewardToken, bonusRewardToken, pool, nonce, multicall] + ); + + return { onApprove, onStake, onHarvest, onHarvestAll }; }; export default useFarmIntegralActions; diff --git a/src/utils/farming/getRewardsCalldata.ts b/src/utils/farming/getRewardsCalldata.ts new file mode 100644 index 0000000..b3c65b1 --- /dev/null +++ b/src/utils/farming/getRewardsCalldata.ts @@ -0,0 +1,59 @@ +import { farmingCenterABI } from '@/generated'; +import { MaxUint128 } from '@cryptoalgebra/integral-sdk'; +import { encodeFunctionData } from 'viem'; + +export function getRewardsCalldata({ + rewardToken, + bonusRewardToken, + pool, + nonce, + tokenId, + account, +}: { + rewardToken: `0x${string}`; + bonusRewardToken: `0x${string}`; + pool: `0x${string}`; + nonce: bigint; + tokenId: bigint; + account: `0x${string}`; +}): `0x${string}`[] { + const collectRewardsCalldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'collectRewards', + args: [ + { + rewardToken, + bonusRewardToken, + pool, + nonce, + }, + tokenId, + ], + }); + + const rewardClaimCalldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'claimReward', + args: [rewardToken, account, BigInt(MaxUint128)], + }); + + const bonusRewardClaimCalldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'claimReward', + args: [bonusRewardToken, account, BigInt(MaxUint128)], + }); + + let calldata; + + if (rewardToken.toLowerCase() !== bonusRewardToken.toLowerCase()) { + calldata = [ + collectRewardsCalldata, + rewardClaimCalldata, + bonusRewardClaimCalldata, + ]; + } else { + calldata = [collectRewardsCalldata, rewardClaimCalldata]; + } + + return calldata; +} From e7f1d7541cc96f7bcab892377908c5a7a14cc575 Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 7 Mar 2024 18:37:18 +0300 Subject: [PATCH 15/47] add: calculate TVL, add token logo in Rewards, connect Collect Rewards button --- .../farming/ActiveFarming/index.tsx | 142 ++++++++++++++++-- .../farming/FarmingPositionCard/index.tsx | 33 +++- src/components/farming/Farmings/index.tsx | 12 +- src/pages/Pool/index.tsx | 2 + src/utils/farming/getFarmingRewards.ts | 74 +++++---- 5 files changed, 199 insertions(+), 64 deletions(-) diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index e180a63..5d26658 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; import { isSameRewards } from '@/utils/farming/isSameRewards'; import { Deposit } from '@/graphql/generated/graphql'; @@ -6,15 +6,54 @@ import { Farming } from '@/types/farming-info'; import { Button } from '@/components/ui/button'; import CardInfo from '@/components/common/CardInfo'; import { formatUnits } from 'viem'; +import { getFarmingRewards } from '@/utils/farming/getFarmingRewards'; +import useFarmIntegralActions from '@/hooks/farming/useFarmIntegralActions'; +import { FormattedPosition } from '@/types/formatted-position'; +import CurrencyLogo from '@/components/common/CurrencyLogo'; +import { useCurrency } from '@/hooks/common/useCurrency'; interface ActiveFarmingProps { farming: Farming; deposits: Deposit[]; + positionsData: FormattedPosition[]; } -const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => { +const ActiveFarming = ({ + farming, + deposits, + positionsData, +}: ActiveFarmingProps) => { const isSameReward = isSameRewards(farming.farming); + const [rewardEarned, setRewardEarned] = useState(0n); + const [bonusRewardEarned, setBonusRewardEarned] = useState(0n); + + const rewardTokenCurrency = useCurrency(farming.farming.rewardToken); + const bonusRewardTokenCurrency = useCurrency( + farming.farming.bonusRewardToken + ); + + const formattedRewardEarned = Number( + formatUnits(rewardEarned, farming.rewardToken.decimals) + ); + + const formattedBonusRewardEarned = Number( + formatUnits(bonusRewardEarned, farming.bonusRewardToken.decimals) + ); + + const TVL = deposits.reduce((acc, deposit) => { + const currentFormattedPosition = positionsData.find( + (position) => Number(position.id) === Number(deposit.id) + ); + if (deposit.eternalFarming !== null && currentFormattedPosition) { + return acc + currentFormattedPosition.liquidityUSD; + } else { + return acc; + } + }, 0); + + const formattedTVL = TVL.toFixed(2); + const rewardRatePerDay = Number( formatUnits( @@ -38,6 +77,46 @@ const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => { 60 * 24; + // collectRewards query to active farming for all positions + useEffect(() => { + const promises: Promise<{ + reward: bigint; + bonusReward: bigint; + }>[] = []; + deposits.forEach((deposit) => { + if (deposit.eternalFarming !== null) { + promises.push( + getFarmingRewards({ + rewardToken: farming.farming.rewardToken, + bonusRewardToken: farming.farming.bonusRewardToken, + pool: farming.farming.pool, + nonce: farming.farming.nonce, + tokenId: BigInt(deposit.id), + }) + ); + } + }); + if (promises.length === 0) return; + Promise.all(promises).then((rewards) => { + rewards.forEach((reward) => { + setRewardEarned((prev) => prev + reward.reward); + setBonusRewardEarned((prev) => prev + reward.bonusReward); + }); + }); + }, []); + + const { onHarvestAll } = useFarmIntegralActions({ + tokenId: BigInt(deposits[2].id), + rewardToken: farming.farming.rewardToken, + bonusRewardToken: farming.farming.bonusRewardToken, + pool: farming.farming.pool, + nonce: farming.farming.nonce, + }); + + const handleHarvestAll = async () => { + onHarvestAll(deposits); + }; + return (
@@ -46,38 +125,73 @@ const ActiveFarming = ({ farming, deposits }: ActiveFarmingProps) => {

45%

-

$100

+

${formattedTVL}

+ -

$12

+

+ ${formattedRewardEarned + formattedBonusRewardEarned} +

-
-

- {rewardRatePerDay + ' ' + farming.rewardToken.symbol} / - day -

- {bonusRewardRatePerDay !== 0 && ( +
+
+

- {bonusRewardRatePerDay}{' '} - {farming.bonusRewardToken.symbol} / day + {rewardRatePerDay + + ' ' + + farming.rewardToken.symbol}{' '} + / day

+
+ {bonusRewardRatePerDay !== 0 && ( +
+ +

+ {bonusRewardRatePerDay}{' '} + {farming.bonusRewardToken.symbol} / day +

+
)}
- +
diff --git a/src/components/farming/FarmingPositionCard/index.tsx b/src/components/farming/FarmingPositionCard/index.tsx index 2e80475..3ed6cde 100644 --- a/src/components/farming/FarmingPositionCard/index.tsx +++ b/src/components/farming/FarmingPositionCard/index.tsx @@ -5,8 +5,8 @@ import { cn } from '@/lib/utils'; interface FarmingPositionCardProps { position: Deposit; status: string; - className: string; - onClick: () => void; + className?: string; + onClick?: () => void; } const FarmingPositionCard = ({ @@ -23,12 +23,37 @@ const FarmingPositionCard = ({ className )} > -
+
{position.id}

Position #{position.id}

-

{status}

+
+
+
+

{status}

+
+
); diff --git a/src/components/farming/Farmings/index.tsx b/src/components/farming/Farmings/index.tsx index 1c427db..9295cb4 100644 --- a/src/components/farming/Farmings/index.tsx +++ b/src/components/farming/Farmings/index.tsx @@ -8,17 +8,17 @@ import { import { useClients } from '@/hooks/graphql/useClients'; import { Address, useAccount } from 'wagmi'; import ActiveFarming from '../ActiveFarming'; -import FarmRewards from '../FarmRewards'; -import ClosedFarmings from '../ClosedFarmings'; import { Farming } from '@/types/farming-info'; import { Loader } from 'lucide-react'; +import { FormattedPosition } from '@/types/formatted-position'; interface FarmingsProps { poolId: Address; poolInfo: SinglePoolQuery; + positionsData: FormattedPosition[]; } -const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { +const Farmings = ({ poolId, poolInfo, positionsData }: FarmingsProps) => { const { address: account } = useAccount(); const [farmingInfo, setFarmingInfo] = useState(); @@ -89,7 +89,7 @@ const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { useEffect(() => { if (!deposits) return; - console.log('Deposits - ', deposits.deposits); + console.log('Positions - ', deposits.deposits); }, [deposits]); return ( @@ -101,9 +101,9 @@ const Farmings = ({ poolId, poolInfo }: FarmingsProps) => { - {/* - */} + {/* */} )}
diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index d2a99cf..74ee27f 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -107,6 +107,7 @@ const PoolPage = () => { getPositionsAPRs(); }, [filteredPositions, poolInfo, poolId, poolFeeData, bundles]); + // should be reusable const formatLiquidityUSD = (position: Position) => { if (!poolInfo?.pool) return 0; @@ -205,6 +206,7 @@ const PoolPage = () => {
) : ( diff --git a/src/utils/farming/getFarmingRewards.ts b/src/utils/farming/getFarmingRewards.ts index 610a873..6a50bfe 100644 --- a/src/utils/farming/getFarmingRewards.ts +++ b/src/utils/farming/getFarmingRewards.ts @@ -1,46 +1,40 @@ -import { MAX_UINT128 } from '@/constants/max-uint128'; -import { getAlgebraPositionManager } from '@/generated'; -import { - CurrencyAmount, - Pool, - unwrappedToken, -} from '@cryptoalgebra/integral-sdk'; +import { getFarmingCenter } from '@/generated'; -export async function getFarmingRewards(pool: Pool, positionId: number) { +export async function getFarmingRewards({ + rewardToken, + bonusRewardToken, + pool, + nonce, + tokenId, +}: { + rewardToken: `0x${string}`; + bonusRewardToken: `0x${string}`; + pool: `0x${string}`; + nonce: bigint; + tokenId: bigint; +}): Promise<{ reward: bigint; bonusReward: bigint }> { try { - const algebraPositionManager = getAlgebraPositionManager({}); - - const owner = await algebraPositionManager.read.ownerOf([ - BigInt(positionId), - ]); - + const farmingCenter = getFarmingCenter({}); const { - result: [fees0, fees1], - } = await algebraPositionManager.simulate.collect( - [ - { - tokenId: BigInt(positionId), - recipient: owner, - amount0Max: MAX_UINT128, - amount1Max: MAX_UINT128, - }, - ], + result: [reward, bonusReward], + } = await farmingCenter.simulate.collectRewards([ { - account: owner, - } - ); - - return [ - CurrencyAmount.fromRawAmount( - unwrappedToken(pool.token0), - fees0.toString() - ), - CurrencyAmount.fromRawAmount( - unwrappedToken(pool.token1), - fees1.toString() - ), - ]; - } catch { - return [undefined, undefined]; + rewardToken, + bonusRewardToken, + pool, + nonce, + }, + tokenId, + ]); + return { + reward, + bonusReward, + }; + } catch (e) { + console.error(e); + return { + reward: 0n, + bonusReward: 0n, + }; } } From 5824b6693547cf144d6b5ea2e2fc09e75f8e7bdc Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 7 Mar 2024 18:38:42 +0300 Subject: [PATCH 16/47] add: position status about FarmingPositionCard --- .../modals/SelectPositionFarmModal/index.tsx | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index e83a85a..8cc943c 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -13,16 +13,19 @@ import useFarmIntegralActions from '@/hooks/farming/useFarmIntegralActions'; import { useFarmIntegralApprove } from '@/hooks/farming/useFarmIntegralApprove'; import { cn } from '@/lib/utils'; import { Farming } from '@/types/farming-info'; +import { FormattedPosition } from '@/types/formatted-position'; import { useState } from 'react'; interface SelectPositionFarmModalProps { positions: Deposit[]; farming: Farming; + positionsData: FormattedPosition[]; } export function SelectPositionFarmModal({ positions, farming, + positionsData, }: SelectPositionFarmModalProps) { const [selectedPosition, setSelectedPosition] = useState(); const tokenId = selectedPosition ? BigInt(selectedPosition.id) : 0n; @@ -35,12 +38,11 @@ export function SelectPositionFarmModal({ nonce: farming.farming.nonce, }); - const { approved, isLoading } = useFarmIntegralApprove(tokenId); - const handleApprove = async () => { if (approved) return; onApprove(); }; + const { approved, isLoading } = useFarmIntegralApprove(tokenId); const handleStake = async () => { if (!approved) return; @@ -57,15 +59,20 @@ export function SelectPositionFarmModal({ style={{ borderRadius: '32px' }} > - + Select Position -
    +
      {positions && positions.map((position) => { if (position.eternalFarming !== null) return; + const currentFormattedPosition = positionsData.find( + (position) => + Number(position.id) === Number(position.id) + ); + if (!currentFormattedPosition) return; return ( ); })} From a8cee697bdaeedaf086417570e6497a4c2d2e594 Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 7 Mar 2024 18:39:55 +0300 Subject: [PATCH 17/47] chore: remove unnecessary query, fix syntax --- src/components/pool/MyPositions/index.tsx | 35 ++-- .../position/PositionCard/index.tsx | 162 ++++++++++-------- src/graphql/queries/farmings.ts | 13 -- src/hooks/common/useTransactionAwait.tsx | 70 ++++---- 4 files changed, 157 insertions(+), 123 deletions(-) diff --git a/src/components/pool/MyPositions/index.tsx b/src/components/pool/MyPositions/index.tsx index c771cef..acff8af 100644 --- a/src/components/pool/MyPositions/index.tsx +++ b/src/components/pool/MyPositions/index.tsx @@ -1,21 +1,30 @@ -import { myPositionsColumns } from "@/components/common/Table/myPositionsColumns" -import DataTable from "@/components/common/Table/dataTable" -import { Address } from "wagmi" -import { FormattedPosition } from "@/types/formatted-position" +import { myPositionsColumns } from '@/components/common/Table/myPositionsColumns'; +import DataTable from '@/components/common/Table/dataTable'; +import { Address } from 'wagmi'; +import { FormattedPosition } from '@/types/formatted-position'; interface MyPositionsProps { positions: FormattedPosition[]; poolId: Address | undefined; selectedPosition: number | undefined; - selectPosition: (positionId: number | null) => void; + selectPosition: (positionId: number | null) => void; } -const MyPositions = ({ positions, selectedPosition, selectPosition }: MyPositionsProps) => { +const MyPositions = ({ + positions, + selectedPosition, + selectPosition, +}: MyPositionsProps) => { + return ( +
      + +
      + ); +}; - return
      - -
      - -} - -export default MyPositions \ No newline at end of file +export default MyPositions; diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index 2762afb..ed4146d 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -1,32 +1,36 @@ -import { usePool } from "@/hooks/pools/usePool"; -import { usePosition } from "@/hooks/positions/usePositions"; -import { INITIAL_POOL_FEE, Position } from "@cryptoalgebra/integral-sdk"; -import PositionNFT from "../PositionNFT"; -import { FormattedPosition } from "@/types/formatted-position"; -import { formatUSD } from "@/utils/common/formatUSD"; -import { Skeleton } from "@/components/ui/skeleton"; -import PositionRangeChart from "../PositionRangeChart"; -import TokenRatio from "@/components/create-position/TokenRatio"; -import { useDerivedMintInfo } from "@/state/mintStore"; -import CollectFees from "../CollectFees"; -import RemoveLiquidityModal from "@/components/modals/RemoveLiquidityModal"; +import { usePool } from '@/hooks/pools/usePool'; +import { usePosition } from '@/hooks/positions/usePositions'; +import { INITIAL_POOL_FEE, Position } from '@cryptoalgebra/integral-sdk'; +import PositionNFT from '../PositionNFT'; +import { FormattedPosition } from '@/types/formatted-position'; +import { formatUSD } from '@/utils/common/formatUSD'; +import { Skeleton } from '@/components/ui/skeleton'; +import PositionRangeChart from '../PositionRangeChart'; +import TokenRatio from '@/components/create-position/TokenRatio'; +import { useDerivedMintInfo } from '@/state/mintStore'; +import CollectFees from '../CollectFees'; +import RemoveLiquidityModal from '@/components/modals/RemoveLiquidityModal'; +import { Button } from '@/components/ui/button'; +import useFarmIntegralActions from '@/hooks/farming/useFarmIntegralActions'; interface PositionCardProps { - selectedPosition: FormattedPosition | undefined + selectedPosition: FormattedPosition | undefined; } const PositionCard = ({ selectedPosition }: PositionCardProps) => { + const { loading, position } = usePosition(selectedPosition?.id); - const { loading, position } = usePosition(selectedPosition?.id) + const [, pool] = usePool(position?.pool); - const [, pool] = usePool(position?.pool) - - const positionEntity = pool && position && new Position({ - pool, - liquidity: position.liquidity.toString(), - tickLower: Number(position.tickLower), - tickUpper: Number(position.tickUpper) - }) + const positionEntity = + pool && + position && + new Position({ + pool, + liquidity: position.liquidity.toString(), + tickLower: Number(position.tickLower), + tickUpper: Number(position.tickUpper), + }); const mintInfo = useDerivedMintInfo( positionEntity?.amount0.currency, @@ -35,63 +39,85 @@ const PositionCard = ({ selectedPosition }: PositionCardProps) => { INITIAL_POOL_FEE, positionEntity?.amount0.currency, positionEntity || undefined - ) + ); - const [positionLiquidityUSD, positionFeesUSD, positionAPR] = selectedPosition ? [ - formatUSD.format(selectedPosition.liquidityUSD), - formatUSD.format(selectedPosition.feesUSD), - `${selectedPosition.apr.toFixed(2)}%` - ] : [] + const [positionLiquidityUSD, positionFeesUSD, positionAPR] = + selectedPosition + ? [ + formatUSD.format(selectedPosition.liquidityUSD), + formatUSD.format(selectedPosition.feesUSD), + `${selectedPosition.apr.toFixed(2)}%`, + ] + : []; - if (!selectedPosition || loading) return + if (!selectedPosition || loading) return; - return
      -
      -
      - -
      -
      -

      {`Position #${selectedPosition?.id}`}

      -
      -
      -
      LIQUIDITY
      -
      - {positionLiquidityUSD ? {positionLiquidityUSD} : } + return ( +
      +
      +
      + +
      +
      +

      {`Position #${selectedPosition?.id}`}

      +
      +
      +
      LIQUIDITY
      +
      + {positionLiquidityUSD ? ( + + {positionLiquidityUSD} + + ) : ( + + )} +
      -
      -
      -
      APR
      -
      - {positionAPR ? {positionAPR} : } +
      +
      APR
      +
      + {positionAPR ? ( + + {positionAPR} + + ) : ( + + )} +
      -
      - - + + - { - positionEntity && -
      -
      - {`${positionEntity.amount0.toFixed(2)} ${positionEntity.amount0.currency.symbol}`} -
      -
      - {`${positionEntity.amount1.toFixed(2)} ${positionEntity.amount1.currency.symbol}`} + {positionEntity && ( +
      +
      + {`${positionEntity.amount0.toFixed(2)} ${ + positionEntity.amount0.currency.symbol + }`} +
      +
      + {`${positionEntity.amount1.toFixed(2)} ${ + positionEntity.amount1.currency.symbol + }`} +
      + )} + {pool && positionEntity && ( + + )} +
      +
      - } - { - pool && positionEntity && - - } -
      -
      -
      - -} + ); +}; -export default PositionCard \ No newline at end of file +export default PositionCard; diff --git a/src/graphql/queries/farmings.ts b/src/graphql/queries/farmings.ts index 16c0987..f9f7532 100644 --- a/src/graphql/queries/farmings.ts +++ b/src/graphql/queries/farmings.ts @@ -31,16 +31,3 @@ export const DEPOSITS = gql` } } `; - -export const DEPOSIT = gql` - query Deposit($id: ID!) { - deposit(id: $id) { - id - liquidity - owner - pool - rangeLength - eternalFarming - } - } -`; diff --git a/src/hooks/common/useTransactionAwait.tsx b/src/hooks/common/useTransactionAwait.tsx index b77cf47..fec6ee9 100644 --- a/src/hooks/common/useTransactionAwait.tsx +++ b/src/hooks/common/useTransactionAwait.tsx @@ -1,26 +1,39 @@ -import { ToastAction } from "@/components/ui/toast"; -import { useToast } from "@/components/ui/use-toast"; -import { ExternalLinkIcon } from "lucide-react"; -import { useEffect } from "react"; -import { Link, useNavigate } from "react-router-dom"; -import { Address, useWaitForTransaction } from "wagmi"; +import { ToastAction } from '@/components/ui/toast'; +import { useToast } from '@/components/ui/use-toast'; +import { ExternalLinkIcon } from 'lucide-react'; +import { useEffect } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import { Address, useWaitForTransaction } from 'wagmi'; -const ViewTxOnExplorer = ({hash}: { hash: Address | undefined }) => hash ? - - View on explorer - - - : null +export const ViewTxOnExplorer = ({ hash }: { hash: Address | undefined }) => + hash ? ( + + + View on explorer + + + + ) : ( + <> + ); -export function useTransitionAwait(hash: Address | undefined, title: string, description?: string, redirectPath?: string) { +export function useTransitionAwait( + hash: Address | undefined, + title: string, + description?: string, + redirectPath?: string +) { + const { toast } = useToast(); - const { toast } = useToast() - - const navigate = useNavigate() + const navigate = useNavigate(); const { data, isError, isLoading, isSuccess } = useWaitForTransaction({ - hash - }) + hash, + }); useEffect(() => { if (isLoading) { @@ -28,9 +41,9 @@ export function useTransitionAwait(hash: Address | undefined, title: string, des title: title, description: description || 'Transaction was sent', action: , - }) + }); } - }, [isLoading]) + }, [isLoading]); useEffect(() => { if (isLoading) { @@ -38,9 +51,9 @@ export function useTransitionAwait(hash: Address | undefined, title: string, des title: title, description: description || 'Transaction failed', action: , - }) + }); } - }, [isError]) + }, [isError]); useEffect(() => { if (isSuccess) { @@ -48,18 +61,17 @@ export function useTransitionAwait(hash: Address | undefined, title: string, des title: title, description: description || 'Transaction confirmed', action: , - }) + }); if (redirectPath) { - navigate(redirectPath) + navigate(redirectPath); } } - }, [isSuccess]) + }, [isSuccess]); return { data, isError, isLoading, - isSuccess - } - -} \ No newline at end of file + isSuccess, + }; +} From bea84e4e8241cf853264185d8ac2f7fec6ec4ce8 Mon Sep 17 00:00:00 2001 From: damnnou Date: Sun, 10 Mar 2024 23:37:39 +0300 Subject: [PATCH 18/47] fix: add loading states, edit isSameRewards --- .../farming/ActiveFarming/index.tsx | 19 +++++++++++---- src/components/farming/Farmings/index.tsx | 18 +++++++------- .../modals/SelectPositionFarmModal/index.tsx | 17 +++++++++---- src/hooks/farming/useFarmIntegralActions.ts | 24 ++++++++++++++++--- src/utils/farming/getRewardsCalldata.ts | 5 +++- src/utils/farming/isSameRewards.ts | 9 +++---- 6 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 5d26658..f881bb5 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -23,11 +23,16 @@ const ActiveFarming = ({ deposits, positionsData, }: ActiveFarmingProps) => { - const isSameReward = isSameRewards(farming.farming); + const [isLoading, setIsLoading] = useState(false); const [rewardEarned, setRewardEarned] = useState(0n); const [bonusRewardEarned, setBonusRewardEarned] = useState(0n); + const isSameReward = isSameRewards( + farming.farming.rewardToken, + farming.farming.bonusRewardToken + ); + const rewardTokenCurrency = useCurrency(farming.farming.rewardToken); const bonusRewardTokenCurrency = useCurrency( farming.farming.bonusRewardToken @@ -114,7 +119,10 @@ const ActiveFarming = ({ }); const handleHarvestAll = async () => { - onHarvestAll(deposits); + if (isLoading) return; + setIsLoading(true); + await onHarvestAll(deposits); + setIsLoading(false); }; return ( @@ -180,13 +188,14 @@ const ActiveFarming = ({
      { }, }); + // All positions for current pool + const { data: deposits } = useDepositsQuery({ + variables: { + owner: account, + pool: poolId, + }, + client: farmingClient, + }); + useEffect(() => { if (!farmings?.eternalFarmings || farmings.eternalFarmings.length === 0) return; @@ -78,15 +87,6 @@ const Farmings = ({ poolId, poolInfo, positionsData }: FarmingsProps) => { console.log('Active Farming - ', farmingInfo); }, [farmingInfo]); - // All positions for current pool - const { data: deposits } = useDepositsQuery({ - variables: { - owner: account, - pool: poolId, - }, - client: farmingClient, - }); - useEffect(() => { if (!deposits) return; console.log('Positions - ', deposits.deposits); diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index 8cc943c..413d3b0 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -30,6 +30,8 @@ export function SelectPositionFarmModal({ const [selectedPosition, setSelectedPosition] = useState(); const tokenId = selectedPosition ? BigInt(selectedPosition.id) : 0n; + const [isLoading, setIsLoading] = useState(false); + const { onApprove, onStake } = useFarmIntegralActions({ tokenId, rewardToken: farming.farming.rewardToken, @@ -38,15 +40,20 @@ export function SelectPositionFarmModal({ nonce: farming.farming.nonce, }); + const { approved, isLoading: isApproving } = + useFarmIntegralApprove(tokenId); + const handleApprove = async () => { if (approved) return; onApprove(); }; - const { approved, isLoading } = useFarmIntegralApprove(tokenId); const handleStake = async () => { if (!approved) return; - onStake(); + if (isLoading) return; + setIsLoading(true); + await onStake(); + setIsLoading(false); }; return ( @@ -96,7 +103,7 @@ export function SelectPositionFarmModal({ })}
    - {isLoading ? ( + {isApproving ? ( @@ -114,11 +121,11 @@ export function SelectPositionFarmModal({ )} ) : ( diff --git a/src/hooks/farming/useFarmIntegralActions.ts b/src/hooks/farming/useFarmIntegralActions.ts index cd020bc..ec0957a 100644 --- a/src/hooks/farming/useFarmIntegralActions.ts +++ b/src/hooks/farming/useFarmIntegralActions.ts @@ -10,16 +10,21 @@ import { import { useAccount } from 'wagmi'; import { encodeFunctionData } from 'viem'; import { waitForTransaction } from 'wagmi/actions'; -import { Deposit } from '@/graphql/generated/graphql'; +import { + Deposit, + useDepositsQuery, + useEternalFarmingsQuery, +} from '@/graphql/generated/graphql'; import { getRewardsCalldata } from '@/utils/farming/getRewardsCalldata'; import { ViewTxOnExplorer } from '../common/useTransactionAwait'; +import { farmingClient } from '@/graphql/clients'; interface FarmIntegralActionContainerChildrenProps { onApprove: () => void; - onStake: () => void; + onStake: () => Promise<`0x${string}` | undefined>; onUnstake?: () => void; onHarvest: () => void; - onHarvestAll: (deposits: Deposit[]) => void; + onHarvestAll: (deposits: Deposit[]) => Promise<`0x${string}` | undefined>; } const useFarmIntegralActions = ({ @@ -44,6 +49,13 @@ const useFarmIntegralActions = ({ const { writeAsync: multicall } = useFarmingCenterMulticall(); + // const { refetch } = useEternalFarmingsQuery({ + // variables: { + // pool, + // }, + // client: farmingClient, + // }); + const onApprove = useCallback(async () => { try { console.log(`Approving for ID ${tokenId}`); @@ -99,6 +111,8 @@ const useFarmIntegralActions = ({ description: `Transaction confirmed!`, action: ViewTxOnExplorer({ hash }), }); + + return hash; } catch (error) { console.error('Approval failed:', error); } @@ -209,6 +223,10 @@ const useFarmIntegralActions = ({ description: `Transaction confirmed!`, action: ViewTxOnExplorer({ hash }), }); + + // await refetch(); + + return hash; } catch (error) { console.error('Harvest failed:', error); } diff --git a/src/utils/farming/getRewardsCalldata.ts b/src/utils/farming/getRewardsCalldata.ts index b3c65b1..7cc1466 100644 --- a/src/utils/farming/getRewardsCalldata.ts +++ b/src/utils/farming/getRewardsCalldata.ts @@ -1,6 +1,7 @@ import { farmingCenterABI } from '@/generated'; import { MaxUint128 } from '@cryptoalgebra/integral-sdk'; import { encodeFunctionData } from 'viem'; +import { isSameRewards } from './isSameRewards'; export function getRewardsCalldata({ rewardToken, @@ -45,7 +46,9 @@ export function getRewardsCalldata({ let calldata; - if (rewardToken.toLowerCase() !== bonusRewardToken.toLowerCase()) { + const isSameReward = isSameRewards(rewardToken, bonusRewardToken); + + if (isSameReward) { calldata = [ collectRewardsCalldata, rewardClaimCalldata, diff --git a/src/utils/farming/isSameRewards.ts b/src/utils/farming/isSameRewards.ts index 91aeeb7..438853e 100644 --- a/src/utils/farming/isSameRewards.ts +++ b/src/utils/farming/isSameRewards.ts @@ -1,5 +1,6 @@ -import { EternalFarming } from '@/graphql/generated/graphql'; - -export const isSameRewards = (farming: EternalFarming) => { - return farming.rewardToken === farming.bonusRewardToken; +export const isSameRewards = ( + rewardToken: `0x${string}`, + bonusRewardToken: `0x${string}` +): boolean => { + return rewardToken.toLowerCase() === bonusRewardToken.toLowerCase(); }; From 9519fffd0ab7077abfd679ac3c5642413b7f35c6 Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 11 Mar 2024 11:28:04 +0300 Subject: [PATCH 19/47] refactor: rewrite farming handlers --- .../farming/ActiveFarming/index.tsx | 34 +-- .../modals/SelectPositionFarmModal/index.tsx | 35 +-- src/hooks/farming/useFarmApprove.ts | 31 +++ ...egralApprove.ts => useFarmCheckApprove.ts} | 2 +- src/hooks/farming/useFarmHarvest.ts | 111 ++++++++ src/hooks/farming/useFarmIntegralActions.ts | 240 ------------------ src/hooks/farming/useFarmStake.ts | 82 ++++++ 7 files changed, 263 insertions(+), 272 deletions(-) create mode 100644 src/hooks/farming/useFarmApprove.ts rename src/hooks/farming/{useFarmIntegralApprove.ts => useFarmCheckApprove.ts} (89%) create mode 100644 src/hooks/farming/useFarmHarvest.ts delete mode 100644 src/hooks/farming/useFarmIntegralActions.ts create mode 100644 src/hooks/farming/useFarmStake.ts diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index f881bb5..0caf5bc 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; import { isSameRewards } from '@/utils/farming/isSameRewards'; import { Deposit } from '@/graphql/generated/graphql'; @@ -7,10 +7,11 @@ import { Button } from '@/components/ui/button'; import CardInfo from '@/components/common/CardInfo'; import { formatUnits } from 'viem'; import { getFarmingRewards } from '@/utils/farming/getFarmingRewards'; -import useFarmIntegralActions from '@/hooks/farming/useFarmIntegralActions'; import { FormattedPosition } from '@/types/formatted-position'; import CurrencyLogo from '@/components/common/CurrencyLogo'; import { useCurrency } from '@/hooks/common/useCurrency'; +import { useAccount } from 'wagmi'; +import { useFarmHarvestAll } from '@/hooks/farming/useFarmHarvest'; interface ActiveFarmingProps { farming: Farming; @@ -23,7 +24,7 @@ const ActiveFarming = ({ deposits, positionsData, }: ActiveFarmingProps) => { - const [isLoading, setIsLoading] = useState(false); + const { address: account } = useAccount(); const [rewardEarned, setRewardEarned] = useState(0n); const [bonusRewardEarned, setBonusRewardEarned] = useState(0n); @@ -108,21 +109,22 @@ const ActiveFarming = ({ setBonusRewardEarned((prev) => prev + reward.bonusReward); }); }); - }, []); - - const { onHarvestAll } = useFarmIntegralActions({ - tokenId: BigInt(deposits[2].id), - rewardToken: farming.farming.rewardToken, - bonusRewardToken: farming.farming.bonusRewardToken, - pool: farming.farming.pool, - nonce: farming.farming.nonce, - }); + }, [farming, deposits]); + + const { isLoading, onHarvestAll } = useFarmHarvestAll( + { + rewardToken: farming.farming.rewardToken, + bonusRewardToken: farming.farming.bonusRewardToken, + pool: farming.farming.pool, + nonce: farming.farming.nonce, + account: account!, + }, + deposits + ); const handleHarvestAll = async () => { - if (isLoading) return; - setIsLoading(true); - await onHarvestAll(deposits); - setIsLoading(false); + if (isLoading || !onHarvestAll) return; + onHarvestAll(); }; return ( diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index 413d3b0..3f06ab6 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -9,12 +9,13 @@ import { DialogTrigger, } from '@/components/ui/dialog'; import { Deposit } from '@/graphql/generated/graphql'; -import useFarmIntegralActions from '@/hooks/farming/useFarmIntegralActions'; -import { useFarmIntegralApprove } from '@/hooks/farming/useFarmIntegralApprove'; +import { useFarmApprove } from '@/hooks/farming/useFarmApprove'; +import { useFarmCheckApprove } from '@/hooks/farming/useFarmCheckApprove'; import { cn } from '@/lib/utils'; import { Farming } from '@/types/farming-info'; import { FormattedPosition } from '@/types/formatted-position'; import { useState } from 'react'; +import { useFarmStake } from '@/hooks/farming/useFarmStake'; interface SelectPositionFarmModalProps { positions: Deposit[]; @@ -30,9 +31,9 @@ export function SelectPositionFarmModal({ const [selectedPosition, setSelectedPosition] = useState(); const tokenId = selectedPosition ? BigInt(selectedPosition.id) : 0n; - const [isLoading, setIsLoading] = useState(false); + const { isLoading: isApproveLoading, onApprove } = useFarmApprove(tokenId); - const { onApprove, onStake } = useFarmIntegralActions({ + const { isLoading: isStakeLoading, onStake } = useFarmStake({ tokenId, rewardToken: farming.farming.rewardToken, bonusRewardToken: farming.farming.bonusRewardToken, @@ -40,20 +41,22 @@ export function SelectPositionFarmModal({ nonce: farming.farming.nonce, }); - const { approved, isLoading: isApproving } = - useFarmIntegralApprove(tokenId); + const { approved, isLoading: isApproving } = useFarmCheckApprove(tokenId); const handleApprove = async () => { - if (approved) return; + if (approved || !onApprove) return; onApprove(); }; const handleStake = async () => { - if (!approved) return; - if (isLoading) return; - setIsLoading(true); - await onStake(); - setIsLoading(false); + if (!approved || !onStake) return; + if (isStakeLoading || isApproveLoading) return; + onStake(); + }; + + const handleSelectPosition = (position: Deposit) => { + if (isStakeLoading || isApproveLoading || isApproving) return; + setSelectedPosition(position); }; return ( @@ -90,7 +93,7 @@ export function SelectPositionFarmModal({ : '' )} onClick={() => - setSelectedPosition(position) + handleSelectPosition(position) } position={position} status={ @@ -116,16 +119,18 @@ export function SelectPositionFarmModal({ > {approved ? ( 1. Approved + ) : isApproveLoading ? ( + ) : ( 1. Approve )} ) : ( diff --git a/src/hooks/farming/useFarmApprove.ts b/src/hooks/farming/useFarmApprove.ts new file mode 100644 index 0000000..e05fe11 --- /dev/null +++ b/src/hooks/farming/useFarmApprove.ts @@ -0,0 +1,31 @@ +import { + ALGEBRA_POSITION_MANAGER, + FARMING_CENTER, +} from '@/constants/addresses'; +import { algebraPositionManagerABI } from '@/generated'; +import { useContractWrite, usePrepareContractWrite } from 'wagmi'; +import { useTransitionAwait } from '../common/useTransactionAwait'; + +export function useFarmApprove(tokenId: bigint) { + const APPROVE = true; + + const { config } = usePrepareContractWrite({ + address: tokenId ? ALGEBRA_POSITION_MANAGER : undefined, + abi: algebraPositionManagerABI, + functionName: 'approveForFarming', + args: [tokenId, APPROVE, FARMING_CENTER], + }); + + const { data: data, writeAsync: onApprove } = useContractWrite(config); + + const { isLoading, isSuccess } = useTransitionAwait( + data?.hash, + `Approve Position #${tokenId}` + ); + + return { + isLoading, + isSuccess, + onApprove, + }; +} diff --git a/src/hooks/farming/useFarmIntegralApprove.ts b/src/hooks/farming/useFarmCheckApprove.ts similarity index 89% rename from src/hooks/farming/useFarmIntegralApprove.ts rename to src/hooks/farming/useFarmCheckApprove.ts index 3344096..de658f3 100644 --- a/src/hooks/farming/useFarmIntegralApprove.ts +++ b/src/hooks/farming/useFarmCheckApprove.ts @@ -2,7 +2,7 @@ import { useAlgebraPositionManagerFarmingApprovals } from '@/generated'; import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; import { useEffect, useState } from 'react'; -export function useFarmIntegralApprove(tokenId: bigint) { +export function useFarmCheckApprove(tokenId: bigint) { const [approved, setApproved] = useState(); const { data } = useAlgebraPositionManagerFarmingApprovals({ diff --git a/src/hooks/farming/useFarmHarvest.ts b/src/hooks/farming/useFarmHarvest.ts new file mode 100644 index 0000000..2587884 --- /dev/null +++ b/src/hooks/farming/useFarmHarvest.ts @@ -0,0 +1,111 @@ +import { FARMING_CENTER } from '@/constants/addresses'; +import { farmingCenterABI } from '@/generated'; +import { getRewardsCalldata } from '@/utils/farming/getRewardsCalldata'; +import { Address, useContractWrite, usePrepareContractWrite } from 'wagmi'; +import { useTransitionAwait } from '../common/useTransactionAwait'; +import { encodeFunctionData } from 'viem'; +import { Deposit } from '@/graphql/generated/graphql'; + +export function useFarmHarvest({ + tokenId, + rewardToken, + bonusRewardToken, + pool, + nonce, + account, +}: { + tokenId: bigint; + rewardToken: Address; + bonusRewardToken: Address; + pool: Address; + nonce: bigint; + account: Address; +}) { + const calldata = getRewardsCalldata({ + rewardToken, + bonusRewardToken, + pool, + nonce, + tokenId, + account, + }); + + const { config } = usePrepareContractWrite({ + address: FARMING_CENTER, + abi: farmingCenterABI, + functionName: 'multicall', + args: [calldata], + }); + + const { data: data, writeAsync: onHarvest } = useContractWrite(config); + + const { isLoading, isSuccess } = useTransitionAwait( + data?.hash, + `Harvest Position #${tokenId}` + ); + + return { + isLoading, + isSuccess, + onHarvest, + }; +} + +export function useFarmHarvestAll( + { + rewardToken, + bonusRewardToken, + pool, + nonce, + account, + }: { + rewardToken: Address; + bonusRewardToken: Address; + pool: Address; + nonce: bigint; + account: Address; + }, + deposits: Deposit[] +) { + const calldatas: Address[] = []; + + deposits.forEach((deposit) => { + if (deposit.eternalFarming !== null) { + const rewardsCalldata = getRewardsCalldata({ + rewardToken, + bonusRewardToken, + pool, + nonce, + tokenId: BigInt(deposit.id), + account, + }); + + const calldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'multicall', + args: [rewardsCalldata], + }); + calldatas.push(calldata); + } + }); + + const { config } = usePrepareContractWrite({ + address: FARMING_CENTER, + abi: farmingCenterABI, + functionName: 'multicall', + args: [calldatas], + }); + + const { data: data, writeAsync: onHarvestAll } = useContractWrite(config); + + const { isLoading, isSuccess } = useTransitionAwait( + data?.hash, + `Harvest All Positions` + ); + + return { + isLoading, + isSuccess, + onHarvestAll, + }; +} diff --git a/src/hooks/farming/useFarmIntegralActions.ts b/src/hooks/farming/useFarmIntegralActions.ts deleted file mode 100644 index ec0957a..0000000 --- a/src/hooks/farming/useFarmIntegralActions.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { useCallback } from 'react'; -import { toast } from '@/components/ui/use-toast'; -import { FARMING_CENTER } from '@/constants/addresses'; -import { - farmingCenterABI, - useAlgebraPositionManagerApproveForFarming, - useFarmingCenterEnterFarming, - useFarmingCenterMulticall, -} from '@/generated'; -import { useAccount } from 'wagmi'; -import { encodeFunctionData } from 'viem'; -import { waitForTransaction } from 'wagmi/actions'; -import { - Deposit, - useDepositsQuery, - useEternalFarmingsQuery, -} from '@/graphql/generated/graphql'; -import { getRewardsCalldata } from '@/utils/farming/getRewardsCalldata'; -import { ViewTxOnExplorer } from '../common/useTransactionAwait'; -import { farmingClient } from '@/graphql/clients'; - -interface FarmIntegralActionContainerChildrenProps { - onApprove: () => void; - onStake: () => Promise<`0x${string}` | undefined>; - onUnstake?: () => void; - onHarvest: () => void; - onHarvestAll: (deposits: Deposit[]) => Promise<`0x${string}` | undefined>; -} - -const useFarmIntegralActions = ({ - tokenId, - rewardToken, - bonusRewardToken, - pool, - nonce, -}: { - tokenId: bigint; - rewardToken: `0x${string}`; - bonusRewardToken: `0x${string}`; - pool: `0x${string}`; - nonce: bigint; -}): FarmIntegralActionContainerChildrenProps => { - const { address: account } = useAccount(); - - const { writeAsync: approveForFarming } = - useAlgebraPositionManagerApproveForFarming(); - - const { writeAsync: enterFarming } = useFarmingCenterEnterFarming(); - - const { writeAsync: multicall } = useFarmingCenterMulticall(); - - // const { refetch } = useEternalFarmingsQuery({ - // variables: { - // pool, - // }, - // client: farmingClient, - // }); - - const onApprove = useCallback(async () => { - try { - console.log(`Approving for ID ${tokenId}`); - - const { hash } = await approveForFarming({ - args: [tokenId, true, FARMING_CENTER], - }); - - toast({ - title: `Approve Position #${tokenId.toString()}`, - description: `Transaction was sent`, - action: ViewTxOnExplorer({ hash }), - }); - - await waitForTransaction({ hash, confirmations: 1 }); - - toast({ - title: `Approve Position #${tokenId.toString()}`, - description: `Transaction confirmed!`, - action: ViewTxOnExplorer({ hash }), - }); - } catch (error) { - console.error('Approval failed:', error); - } - }, [approveForFarming, tokenId, account]); - - const onStake = useCallback(async () => { - try { - console.log(`Staking ID ${tokenId}`); - - const { hash } = await enterFarming({ - args: [ - { - rewardToken, - bonusRewardToken, - pool, - nonce, - }, - tokenId, - ], - }); - - toast({ - title: `Deposit Position #${tokenId.toString()}`, - description: `Transaction was sent`, - action: ViewTxOnExplorer({ hash }), - }); - - await waitForTransaction({ hash, confirmations: 1 }); - - toast({ - title: `Deposit Position #${tokenId.toString()}`, - description: `Transaction confirmed!`, - action: ViewTxOnExplorer({ hash }), - }); - - return hash; - } catch (error) { - console.error('Approval failed:', error); - } - }, [ - account, - rewardToken, - tokenId, - bonusRewardToken, - pool, - nonce, - enterFarming, - ]); - - const onHarvest = useCallback(async () => { - try { - if (!account) { - console.error('Account not found'); - return; - } - - console.log(`Harvesting ID ${tokenId}`); - - const calldata = getRewardsCalldata({ - rewardToken, - bonusRewardToken, - pool, - nonce, - tokenId, - account, - }); - - const { hash } = await multicall({ - args: [calldata], - }); - - toast({ - title: `Harvest Position #${tokenId.toString()}`, - description: `Transaction was sent`, - action: ViewTxOnExplorer({ hash }), - }); - - await waitForTransaction({ hash, confirmations: 1 }); - - toast({ - title: `Harvest Position #${tokenId.toString()}`, - description: `Transaction confirmed!`, - action: ViewTxOnExplorer({ hash }), - }); - - console.log(`Harvest confirmed!`, hash); - } catch (error) { - console.error('Harvest failed:', error); - } - }, [ - account, - tokenId, - rewardToken, - bonusRewardToken, - pool, - nonce, - multicall, - ]); - - const onHarvestAll = useCallback( - async (deposits: Deposit[]) => { - try { - if (!account) { - console.error('Account not found'); - return; - } - - const calldatas: `0x${string}`[] = []; - - deposits.forEach((deposit) => { - if (deposit.eternalFarming !== null) { - const rewardsCalldata = getRewardsCalldata({ - rewardToken, - bonusRewardToken, - pool, - nonce, - tokenId: BigInt(deposit.id), - account, - }); - - const calldata = encodeFunctionData({ - abi: farmingCenterABI, - functionName: 'multicall', - args: [rewardsCalldata], - }); - calldatas.push(calldata); - } - }); - - const { hash } = await multicall({ - args: [calldatas], - }); - - toast({ - title: `Harvest All Positions`, - description: `Transaction was sent`, - action: ViewTxOnExplorer({ hash }), - }); - - await waitForTransaction({ hash, confirmations: 1 }); - - toast({ - title: `Harvest All Positions`, - description: `Transaction confirmed!`, - action: ViewTxOnExplorer({ hash }), - }); - - // await refetch(); - - return hash; - } catch (error) { - console.error('Harvest failed:', error); - } - }, - [account, rewardToken, bonusRewardToken, pool, nonce, multicall] - ); - - return { onApprove, onStake, onHarvest, onHarvestAll }; -}; - -export default useFarmIntegralActions; diff --git a/src/hooks/farming/useFarmStake.ts b/src/hooks/farming/useFarmStake.ts new file mode 100644 index 0000000..1c1daff --- /dev/null +++ b/src/hooks/farming/useFarmStake.ts @@ -0,0 +1,82 @@ +import { FARMING_CENTER } from '@/constants/addresses'; +import { farmingCenterABI } from '@/generated'; +import { Address, useContractWrite, usePrepareContractWrite } from 'wagmi'; +import { useTransitionAwait } from '../common/useTransactionAwait'; + +export function useFarmStake({ + tokenId, + rewardToken, + bonusRewardToken, + pool, + nonce, +}: { + tokenId: bigint; + rewardToken: Address; + bonusRewardToken: Address; + pool: Address; + nonce: bigint; +}) { + const { config } = usePrepareContractWrite({ + address: tokenId ? FARMING_CENTER : undefined, + abi: farmingCenterABI, + functionName: 'enterFarming', + args: [ + { + rewardToken, + bonusRewardToken, + pool, + nonce, + }, + tokenId, + ], + }); + + const { data: data, writeAsync: onStake } = useContractWrite(config); + + const { isLoading, isSuccess } = useTransitionAwait( + data?.hash, + `Stake Position #${tokenId}` + ); + + return { + isLoading, + isSuccess, + onStake, + }; +} + +// export function useFarmUnstake( +// tokenId: bigint, +// rewardToken: Address, +// bonusRewardToken: Address, +// pool: Address, +// nonce: bigint +// ) { +// const { config } = usePrepareContractWrite({ +// address: FARMING_CENTER, +// abi: farmingCenterABI, +// functionName: 'enterFarming', +// args: [ +// { +// rewardToken, +// bonusRewardToken, +// pool, +// nonce, +// }, +// tokenId, +// ], +// }); + +// const { data: data, writeAsync: onStake } = useContractWrite(config); + +// const { isLoading, isSuccess } = useTransitionAwait( +// data?.hash, +// `Stake Position #${tokenId}` +// ); + +// return { +// isLoading, +// isSuccess, +// onStake, +// }; +// } From 194c82e36d7dd56e8cf485f8dd7148e51a23c525 Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 11 Mar 2024 11:32:27 +0300 Subject: [PATCH 20/47] refactor: add type Address from viem --- src/utils/farming/getFarmingAPR.ts | 0 src/utils/farming/getFarmingRewards.ts | 7 ++++--- src/utils/farming/getRewardsCalldata.ts | 12 ++++++------ src/utils/farming/isSameRewards.ts | 6 ++++-- 4 files changed, 14 insertions(+), 11 deletions(-) delete mode 100644 src/utils/farming/getFarmingAPR.ts diff --git a/src/utils/farming/getFarmingAPR.ts b/src/utils/farming/getFarmingAPR.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/utils/farming/getFarmingRewards.ts b/src/utils/farming/getFarmingRewards.ts index 6a50bfe..85371ae 100644 --- a/src/utils/farming/getFarmingRewards.ts +++ b/src/utils/farming/getFarmingRewards.ts @@ -1,4 +1,5 @@ import { getFarmingCenter } from '@/generated'; +import { Address } from 'viem'; export async function getFarmingRewards({ rewardToken, @@ -7,9 +8,9 @@ export async function getFarmingRewards({ nonce, tokenId, }: { - rewardToken: `0x${string}`; - bonusRewardToken: `0x${string}`; - pool: `0x${string}`; + rewardToken: Address; + bonusRewardToken: Address; + pool: Address; nonce: bigint; tokenId: bigint; }): Promise<{ reward: bigint; bonusReward: bigint }> { diff --git a/src/utils/farming/getRewardsCalldata.ts b/src/utils/farming/getRewardsCalldata.ts index 7cc1466..d5d72a5 100644 --- a/src/utils/farming/getRewardsCalldata.ts +++ b/src/utils/farming/getRewardsCalldata.ts @@ -1,6 +1,6 @@ import { farmingCenterABI } from '@/generated'; import { MaxUint128 } from '@cryptoalgebra/integral-sdk'; -import { encodeFunctionData } from 'viem'; +import { Address, encodeFunctionData } from 'viem'; import { isSameRewards } from './isSameRewards'; export function getRewardsCalldata({ @@ -11,13 +11,13 @@ export function getRewardsCalldata({ tokenId, account, }: { - rewardToken: `0x${string}`; - bonusRewardToken: `0x${string}`; - pool: `0x${string}`; + rewardToken: Address; + bonusRewardToken: Address; + pool: Address; nonce: bigint; tokenId: bigint; - account: `0x${string}`; -}): `0x${string}`[] { + account: Address; +}): Address[] { const collectRewardsCalldata = encodeFunctionData({ abi: farmingCenterABI, functionName: 'collectRewards', diff --git a/src/utils/farming/isSameRewards.ts b/src/utils/farming/isSameRewards.ts index 438853e..010026b 100644 --- a/src/utils/farming/isSameRewards.ts +++ b/src/utils/farming/isSameRewards.ts @@ -1,6 +1,8 @@ +import { Address } from 'viem'; + export const isSameRewards = ( - rewardToken: `0x${string}`, - bonusRewardToken: `0x${string}` + rewardToken: Address, + bonusRewardToken: Address ): boolean => { return rewardToken.toLowerCase() === bonusRewardToken.toLowerCase(); }; From 7457c8a35473602903d61b280dd31d41a722f89f Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 11 Mar 2024 11:50:21 +0300 Subject: [PATCH 21/47] add: available positions check in farming modal --- .../modals/SelectPositionFarmModal/index.tsx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index 3f06ab6..2e5b256 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -59,6 +59,10 @@ export function SelectPositionFarmModal({ setSelectedPosition(position); }; + const availablePositions = positions.filter( + (position) => position.eternalFarming === null + ); + return ( @@ -75,9 +79,8 @@ export function SelectPositionFarmModal({
      - {positions && - positions.map((position) => { - if (position.eternalFarming !== null) return; + {availablePositions.length > 0 ? ( + availablePositions.map((position) => { const currentFormattedPosition = positionsData.find( (position) => Number(position.id) === Number(position.id) @@ -103,14 +106,19 @@ export function SelectPositionFarmModal({ } /> ); - })} + }) + ) : ( +

      + You don't have available positions for this pool +

      + )}
    {isApproving ? ( - ) : selectedPosition ? ( + ) : selectedPosition && availablePositions.length > 0 ? ( <> (); const tokenId = selectedPosition ? BigInt(selectedPosition.id) : 0n; @@ -66,7 +68,12 @@ export function SelectPositionFarmModal({ return ( - + Date: Mon, 11 Mar 2024 16:51:40 +0300 Subject: [PATCH 23/47] add: harvest + unstake funcs in positions, refactor active farming --- .../farming/ActiveFarming/index.tsx | 8 +- src/components/farming/Farmings/index.tsx | 97 +------- .../position/PositionCard/index.tsx | 59 ++++- src/hooks/farming/useActiveFarming.ts | 90 ++++++++ src/hooks/farming/useFarmStake.ts | 98 ++++++--- src/hooks/positions/usePositions.ts | 208 +++++++++++------- src/pages/Pool/index.tsx | 27 ++- 7 files changed, 366 insertions(+), 221 deletions(-) create mode 100644 src/hooks/farming/useActiveFarming.ts diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 6d41475..65fe0a5 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -100,9 +100,6 @@ const ActiveFarming = ({ onHarvestAll(); }; - const [refet, setRefet] = useState(false); - - // collectRewards query to active farming for all positions useEffect(() => { const promises: Promise<{ reward: bigint; @@ -157,10 +154,7 @@ const ActiveFarming = ({ className="w-1/2" title="EARNED" > -

    setRefet(!refet)} - className="text-cyan-300" - > +

    ${formattedRewardEarned + formattedBonusRewardEarned}

    diff --git a/src/components/farming/Farmings/index.tsx b/src/components/farming/Farmings/index.tsx index b57d073..8909421 100644 --- a/src/components/farming/Farmings/index.tsx +++ b/src/components/farming/Farmings/index.tsx @@ -1,106 +1,25 @@ -import React, { useEffect, useState } from 'react'; -import { - useEternalFarmingsQuery, - useSingleTokenQuery, - useDepositsQuery, - SinglePoolQuery, -} from '@/graphql/generated/graphql'; -import { useClients } from '@/hooks/graphql/useClients'; -import { Address, useAccount } from 'wagmi'; -import ActiveFarming from '../ActiveFarming'; +import { Deposit } from '@/graphql/generated/graphql'; import { Farming } from '@/types/farming-info'; import { Loader } from 'lucide-react'; import { FormattedPosition } from '@/types/formatted-position'; +import ActiveFarming from '../ActiveFarming'; interface FarmingsProps { - poolId: Address; - poolInfo: SinglePoolQuery; + farming: Farming; + deposits: Deposit[]; positionsData: FormattedPosition[]; } -const Farmings = ({ poolId, poolInfo, positionsData }: FarmingsProps) => { - const { address: account } = useAccount(); - - const [farmingInfo, setFarmingInfo] = useState(); - - const { farmingClient } = useClients(); - - const { data: farmings, loading: isLoading } = useEternalFarmingsQuery({ - variables: { - pool: poolId, - }, - client: farmingClient, - }); - - const activeFarming = farmings?.eternalFarmings.filter( - (farming) => !farming.isDeactivated - )[0]; - - const closedFarmings = farmings?.eternalFarmings.filter( - (farming) => farming.isDeactivated - ); - - const { data: rewardToken } = useSingleTokenQuery({ - skip: !activeFarming, - variables: { - tokenId: activeFarming?.rewardToken, - }, - }); - - const { data: bonusRewardToken } = useSingleTokenQuery({ - skip: !activeFarming, - variables: { - tokenId: activeFarming?.bonusRewardToken, - }, - }); - - // All positions for current pool - const { data: deposits } = useDepositsQuery({ - variables: { - owner: account, - pool: poolId, - }, - client: farmingClient, - }); - - useEffect(() => { - if (!farmings?.eternalFarmings || farmings.eternalFarmings.length === 0) - return; - if (!rewardToken || !bonusRewardToken || !poolInfo) return; - - if (!activeFarming) { - console.error('Active farming not found'); - return; - } - - // ! disabled null check - setFarmingInfo({ - farming: activeFarming, - rewardToken: rewardToken.token!, - bonusRewardToken: bonusRewardToken.token!, - pool: poolInfo.pool, - }); - }, [farmings, rewardToken, bonusRewardToken, poolInfo]); - - useEffect(() => { - if (!farmingInfo) return; - console.log('Active Farming - ', farmingInfo); - }, [farmingInfo]); - - useEffect(() => { - if (!deposits) return; - console.log('Positions - ', deposits.deposits); - }, [deposits]); - +const Farmings = ({ farming, deposits, positionsData }: FarmingsProps) => { return (
    - {isLoading || !deposits || !farmingInfo || !closedFarmings ? ( + {!farming || !deposits ? ( ) : ( <> {/* */} diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index ed4146d..ba1824d 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -1,5 +1,8 @@ import { usePool } from '@/hooks/pools/usePool'; -import { usePosition } from '@/hooks/positions/usePositions'; +import { + usePosition, + usePositionInFarming, +} from '@/hooks/positions/usePositions'; import { INITIAL_POOL_FEE, Position } from '@cryptoalgebra/integral-sdk'; import PositionNFT from '../PositionNFT'; import { FormattedPosition } from '@/types/formatted-position'; @@ -11,17 +14,55 @@ import { useDerivedMintInfo } from '@/state/mintStore'; import CollectFees from '../CollectFees'; import RemoveLiquidityModal from '@/components/modals/RemoveLiquidityModal'; import { Button } from '@/components/ui/button'; -import useFarmIntegralActions from '@/hooks/farming/useFarmIntegralActions'; +import { useFarmUnstake } from '@/hooks/farming/useFarmStake'; +import { Address, useAccount } from 'wagmi'; +import Loader from '@/components/common/Loader'; +import { Farming } from '@/types/farming-info'; +import { useFarmHarvest } from '@/hooks/farming/useFarmHarvest'; interface PositionCardProps { selectedPosition: FormattedPosition | undefined; + farming: Farming; } -const PositionCard = ({ selectedPosition }: PositionCardProps) => { +const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { const { loading, position } = usePosition(selectedPosition?.id); - const [, pool] = usePool(position?.pool); + const { address: account } = useAccount(); + + const positionInFarming = usePositionInFarming(selectedPosition?.id); + + const { onHarvest, isLoading: isHarvesting } = useFarmHarvest({ + tokenId: positionInFarming ? BigInt(positionInFarming?.id) : 0n, + rewardToken: farming.farming.rewardToken, + bonusRewardToken: farming.farming.bonusRewardToken, + pool: farming.farming.pool, + nonce: farming.farming.nonce, + account: account as Address, + }); + + const { onUnstake, isLoading: isUnstaking } = useFarmUnstake({ + tokenId: positionInFarming ? BigInt(positionInFarming?.id) : 0n, + rewardToken: farming.farming.rewardToken, + bonusRewardToken: farming.farming.bonusRewardToken, + pool: farming.farming.pool, + nonce: farming.farming.nonce, + account: account as Address, + }); + + const handleUnstake = async () => { + if (!positionInFarming) return; + if (!onUnstake) return; + onUnstake(); + }; + const handleHarvest = async () => { + if (!positionInFarming) return; + if (!onHarvest) return; + onHarvest(); + }; + + const [, pool] = usePool(position?.pool); const positionEntity = pool && position && @@ -116,6 +157,16 @@ const PositionCard = ({ selectedPosition }: PositionCardProps) => {
    + {positionInFarming && ( +
    + + +
    + )}
    ); }; diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts new file mode 100644 index 0000000..ed5d9bf --- /dev/null +++ b/src/hooks/farming/useActiveFarming.ts @@ -0,0 +1,90 @@ +import { Address, useAccount } from 'wagmi'; +import { useClients } from '../graphql/useClients'; +import { useEffect, useState } from 'react'; +import { + useDepositsQuery, + useEternalFarmingsQuery, + useSingleTokenQuery, + SinglePoolQuery, +} from '@/graphql/generated/graphql'; +import { Farming } from '@/types/farming-info'; + +export function useActiveFarming({ + poolId, + poolInfo, +}: { + poolId: Address; + poolInfo: SinglePoolQuery | undefined; +}) { + const { address: account } = useAccount(); + + const [farmingInfo, setFarmingInfo] = useState(); + + const { farmingClient } = useClients(); + + const { data: farmings, loading: isLoading } = useEternalFarmingsQuery({ + variables: { + pool: poolId, + }, + client: farmingClient, + skip: !poolInfo, + }); + + const activeFarming = farmings?.eternalFarmings.filter( + (farming) => !farming.isDeactivated + )[0]; + + const { data: rewardToken } = useSingleTokenQuery({ + skip: !activeFarming, + variables: { + tokenId: activeFarming?.rewardToken, + }, + }); + + const { data: bonusRewardToken } = useSingleTokenQuery({ + skip: !activeFarming, + variables: { + tokenId: activeFarming?.bonusRewardToken, + }, + }); + + const { data: deposits } = useDepositsQuery({ + variables: { + owner: account, + pool: poolId, + }, + client: farmingClient, + skip: !poolInfo, + }); + + useEffect(() => { + if (!farmings?.eternalFarmings || farmings.eternalFarmings.length === 0) + return; + if (!rewardToken || !bonusRewardToken || !poolInfo) return; + + if (!activeFarming) { + console.error('Active farming not found'); + return; + } + + // ! disabled null check + setFarmingInfo({ + farming: activeFarming, + rewardToken: rewardToken.token!, + bonusRewardToken: bonusRewardToken.token!, + pool: poolInfo.pool, + }); + }, [farmings, rewardToken, bonusRewardToken, poolInfo]); + + useEffect(() => { + if (!farmingInfo) return; + console.log('Active Farming - ', farmingInfo); + }, [farmingInfo]); + + useEffect(() => { + if (!deposits) return; + console.log('Positions - ', deposits.deposits); + }, [deposits]); + + return { farmingInfo, deposits, isLoading }; +} diff --git a/src/hooks/farming/useFarmStake.ts b/src/hooks/farming/useFarmStake.ts index 1c1daff..35c73d2 100644 --- a/src/hooks/farming/useFarmStake.ts +++ b/src/hooks/farming/useFarmStake.ts @@ -2,6 +2,8 @@ import { FARMING_CENTER } from '@/constants/addresses'; import { farmingCenterABI } from '@/generated'; import { Address, useContractWrite, usePrepareContractWrite } from 'wagmi'; import { useTransitionAwait } from '../common/useTransactionAwait'; +import { encodeFunctionData } from 'viem'; +import { MaxUint128 } from '@cryptoalgebra/integral-sdk'; export function useFarmStake({ tokenId, @@ -45,38 +47,70 @@ export function useFarmStake({ }; } -// export function useFarmUnstake( -// tokenId: bigint, -// rewardToken: Address, -// bonusRewardToken: Address, -// pool: Address, -// nonce: bigint -// ) { -// const { config } = usePrepareContractWrite({ -// address: FARMING_CENTER, -// abi: farmingCenterABI, -// functionName: 'enterFarming', -// args: [ -// { -// rewardToken, -// bonusRewardToken, -// pool, -// nonce, -// }, -// tokenId, -// ], -// }); +export function useFarmUnstake({ + tokenId, + rewardToken, + bonusRewardToken, + pool, + nonce, + account, +}: { + tokenId: bigint; + rewardToken: Address; + bonusRewardToken: Address; + pool: Address; + nonce: bigint; + account: Address; +}) { + const exitFarmingCalldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'exitFarming', + args: [ + { + rewardToken, + bonusRewardToken, + pool, + nonce, + }, + tokenId, + ], + }); + + const rewardClaimCalldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'claimReward', + args: [rewardToken, account, BigInt(MaxUint128)], + }); -// const { data: data, writeAsync: onStake } = useContractWrite(config); + const bonusRewardClaimCalldata = encodeFunctionData({ + abi: farmingCenterABI, + functionName: 'claimReward', + args: [bonusRewardToken, account, BigInt(MaxUint128)], + }); -// const { isLoading, isSuccess } = useTransitionAwait( -// data?.hash, -// `Stake Position #${tokenId}` -// ); + const calldatas = [ + exitFarmingCalldata, + rewardClaimCalldata, + bonusRewardClaimCalldata, + ]; + + const { config } = usePrepareContractWrite({ + address: tokenId ? FARMING_CENTER : undefined, + abi: farmingCenterABI, + functionName: 'multicall', + args: [calldatas], + }); -// return { -// isLoading, -// isSuccess, -// onStake, -// }; -// } + const { data: data, writeAsync: onUnstake } = useContractWrite(config); + + const { isLoading, isSuccess } = useTransitionAwait( + data?.hash, + `Unstake Position #${tokenId}` + ); + + return { + isLoading, + isSuccess, + onUnstake, + }; +} diff --git a/src/hooks/positions/usePositions.ts b/src/hooks/positions/usePositions.ts index d4f2497..e3bf9b1 100644 --- a/src/hooks/positions/usePositions.ts +++ b/src/hooks/positions/usePositions.ts @@ -1,10 +1,12 @@ -import { algebraPositionManagerABI } from "@/abis" -import { ALGEBRA_POSITION_MANAGER } from "@/constants/addresses" -import { DEFAULT_CHAIN_ID } from "@/constants/default-chain-id" -import { useAlgebraPositionManagerBalanceOf } from "@/generated" -import { Token, computePoolAddress } from "@cryptoalgebra/integral-sdk" -import { useMemo } from "react" -import { Address, useAccount, useContractReads } from "wagmi" +import { algebraPositionManagerABI } from '@/abis'; +import { ALGEBRA_POSITION_MANAGER } from '@/constants/addresses'; +import { DEFAULT_CHAIN_ID } from '@/constants/default-chain-id'; +import { useAlgebraPositionManagerBalanceOf } from '@/generated'; +import { farmingClient } from '@/graphql/clients'; +import { useDepositsQuery } from '@/graphql/generated/graphql'; +import { Token, computePoolAddress } from '@cryptoalgebra/integral-sdk'; +import { useMemo } from 'react'; +import { Address, useAccount, useContractReads } from 'wagmi'; export interface PositionFromTokenId { tokenId: number; @@ -22,125 +24,165 @@ export interface PositionFromTokenId { pool: Address; } -function usePositionsFromTokenIds(tokenIds: any[] | undefined): { isLoading: boolean; positions: PositionFromTokenId[] | undefined } { - - const inputs = useMemo(() => (tokenIds ? tokenIds.map((tokenId) => tokenId) : []), [tokenIds]) - - const { data: results, isLoading, isError, error } = useContractReads({ - contracts: inputs.map(x => ({ +function usePositionsFromTokenIds(tokenIds: any[] | undefined): { + isLoading: boolean; + positions: PositionFromTokenId[] | undefined; +} { + const inputs = useMemo( + () => (tokenIds ? tokenIds.map((tokenId) => tokenId) : []), + [tokenIds] + ); + + const { + data: results, + isLoading, + isError, + error, + } = useContractReads({ + contracts: inputs.map((x) => ({ address: ALGEBRA_POSITION_MANAGER, abi: algebraPositionManagerABI, functionName: 'positions', - args: [[Number(x)]] + args: [[Number(x)]], })), - cacheTime: 10_000 - }) + cacheTime: 10_000, + }); - const { address: account } = useAccount() + const { address: account } = useAccount(); const positions = useMemo(() => { if (!isLoading && !isError && tokenIds && !error) { - return results?.filter(v => !v.error).map((call, i) => { - const tokenId = tokenIds[i] - const result = call.result as any - - const pool = computePoolAddress({ - tokenA: new Token(DEFAULT_CHAIN_ID, result[2], 18), - tokenB: new Token(DEFAULT_CHAIN_ID, result[3], 18) - }) as Address - - return { - tokenId, - feeGrowthInside0LastX128: result[7], - feeGrowthInside1LastX128: result[8], - liquidity: result[6], - nonce: result[0], - operator: result[1], - tickLower: result[4], - tickUpper: result[5], - token0: result[2], - token1: result[3], - tokensOwed0: result[9], - tokensOwed1: result[10], - pool - } - }) + return results + ?.filter((v) => !v.error) + .map((call, i) => { + const tokenId = tokenIds[i]; + const result = call.result as any; + + const pool = computePoolAddress({ + tokenA: new Token(DEFAULT_CHAIN_ID, result[2], 18), + tokenB: new Token(DEFAULT_CHAIN_ID, result[3], 18), + }) as Address; + + return { + tokenId, + feeGrowthInside0LastX128: result[7], + feeGrowthInside1LastX128: result[8], + liquidity: result[6], + nonce: result[0], + operator: result[1], + tickLower: result[4], + tickUpper: result[5], + token0: result[2], + token1: result[3], + tokensOwed0: result[9], + tokensOwed1: result[10], + pool, + }; + }); } - return undefined - }, [isLoading, isError, error, results, tokenIds, account]) + return undefined; + }, [isLoading, isError, error, results, tokenIds, account]); return useMemo(() => { return { isLoading, - positions - } - }, [isLoading, positions]) + positions, + }; + }, [isLoading, positions]); } export function usePositions() { + const { address: account } = useAccount(); - const { address: account } = useAccount() - - const { data: balanceResult, isLoading: balanceLoading } = useAlgebraPositionManagerBalanceOf({ - args: account ? [account] : undefined, - cacheTime: 10_000 - }) + const { data: balanceResult, isLoading: balanceLoading } = + useAlgebraPositionManagerBalanceOf({ + args: account ? [account] : undefined, + cacheTime: 10_000, + }); const tokenIdsArgs: [Address, number][] = useMemo(() => { + if (!balanceResult || !account) return []; - if (!balanceResult || !account) return [] - - const tokenRequests: any[] = [] + const tokenRequests: any[] = []; for (let i = 0; i < balanceResult; i++) { - tokenRequests.push([account, i]) + tokenRequests.push([account, i]); } - return tokenRequests - }, [account, balanceResult]) + return tokenRequests; + }, [account, balanceResult]); - - const { data: tokenIdResults, isLoading: someTokenIdsLoading } = useContractReads({ - contracts: tokenIdsArgs.map((args) => ({ - address: ALGEBRA_POSITION_MANAGER, - abi: algebraPositionManagerABI, - functionName: 'tokenOfOwnerByIndex', - args - })), - cacheTime: 10_000 - }) + const { data: tokenIdResults, isLoading: someTokenIdsLoading } = + useContractReads({ + contracts: tokenIdsArgs.map((args) => ({ + address: ALGEBRA_POSITION_MANAGER, + abi: algebraPositionManagerABI, + functionName: 'tokenOfOwnerByIndex', + args, + })), + cacheTime: 10_000, + }); const tokenIds = useMemo(() => { if (account) { return tokenIdResults ?.map(({ result }) => result) .filter((result) => !!result) - .map((result) => result) + .map((result) => result); } - return [] - }, [account, tokenIdResults]) + return []; + }, [account, tokenIdResults]); - const { positions, isLoading: positionsLoading } = usePositionsFromTokenIds(tokenIds) + const { positions, isLoading: positionsLoading } = + usePositionsFromTokenIds(tokenIds); return { loading: someTokenIdsLoading || balanceLoading || positionsLoading, - positions - } + positions, + }; } -export function usePosition(tokenId: string | number | undefined): { loading: boolean; position: PositionFromTokenId | undefined } { - +export function usePosition(tokenId: string | number | undefined): { + loading: boolean; + position: PositionFromTokenId | undefined; +} { const tokenIdArr = useMemo(() => { - if (!tokenId) return - return [tokenId] - }, [tokenId]) + if (!tokenId) return; + return [tokenId]; + }, [tokenId]); - const { isLoading, positions } = usePositionsFromTokenIds(tokenIdArr) + const { isLoading, positions } = usePositionsFromTokenIds(tokenIdArr); return useMemo(() => { return { loading: isLoading, position: positions?.[0], - } - }, [isLoading, positions]) + }; + }, [isLoading, positions]); +} + +export function usePositionInFarming(tokenId: string | number | undefined) { + const { position } = usePosition(tokenId); + + const { address: account } = useAccount(); + + const { data: deposits } = useDepositsQuery({ + variables: { + owner: account ? account : undefined, + pool: position?.pool, + }, + client: farmingClient, + }); + + if (!deposits) return; + const openedPositions = deposits.deposits.filter( + (deposit) => deposit.eternalFarming !== null + ); + + const positionInFarming = openedPositions.find( + (deposit) => Number(deposit.id) === Number(tokenId) + ); + + if (!positionInFarming) return null; + else return positionInFarming; } diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 74ee27f..f05fe09 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -11,6 +11,7 @@ import { usePoolFeeDataQuery, useSinglePoolQuery, } from '@/graphql/generated/graphql'; +import { useActiveFarming } from '@/hooks/farming/useActiveFarming'; import { usePool } from '@/hooks/pools/usePool'; import { usePositions } from '@/hooks/positions/usePositions'; import { FormattedPosition } from '@/types/formatted-position'; @@ -170,6 +171,15 @@ const PoolPage = () => { const noPositions = !positionsLoading && positionsData.length === 0 && poolEntity; + const { + farmingInfo, + deposits, + isLoading: isFarmingLoading, + } = useActiveFarming({ + poolId: poolId, + poolInfo: poolInfo, + }); + return ( @@ -198,14 +208,14 @@ const PoolPage = () => { ) } /> - {poolInfo ? ( + {farmingInfo && deposits && !isFarmingLoading ? (

    Farmings

    @@ -216,9 +226,14 @@ const PoolPage = () => { )}
    -
    - -
    + {farmingInfo && ( +
    + +
    + )}
    ); From 6347ddaa37ea05ea5e88a85d1add5082549e9af1 Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 11 Mar 2024 16:55:56 +0300 Subject: [PATCH 24/47] fix: fix lint warnings for deploy --- src/components/farming/ClosedFarmings/index.tsx | 1 - src/components/farming/FarmRewards/index.tsx | 2 -- src/components/farming/FarmingPositionCard/index.tsx | 1 - 3 files changed, 4 deletions(-) diff --git a/src/components/farming/ClosedFarmings/index.tsx b/src/components/farming/ClosedFarmings/index.tsx index 024b4d0..2487961 100644 --- a/src/components/farming/ClosedFarmings/index.tsx +++ b/src/components/farming/ClosedFarmings/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { EternalFarming } from '@/graphql/generated/graphql'; interface ActiveFarmingProps { diff --git a/src/components/farming/FarmRewards/index.tsx b/src/components/farming/FarmRewards/index.tsx index d65e849..de39a3c 100644 --- a/src/components/farming/FarmRewards/index.tsx +++ b/src/components/farming/FarmRewards/index.tsx @@ -1,5 +1,3 @@ -import React from 'react'; - const FarmRewards = () => { return (
    diff --git a/src/components/farming/FarmingPositionCard/index.tsx b/src/components/farming/FarmingPositionCard/index.tsx index 3ed6cde..0508d0c 100644 --- a/src/components/farming/FarmingPositionCard/index.tsx +++ b/src/components/farming/FarmingPositionCard/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { Deposit } from '@/graphql/generated/graphql'; import { cn } from '@/lib/utils'; From 98127df29d2442046598700139ac37b6ec10e1e2 Mon Sep 17 00:00:00 2001 From: damnnou Date: Mon, 11 Mar 2024 19:14:26 +0300 Subject: [PATCH 25/47] fix: edit check approve func, fix disconnected wallet access --- .../modals/SelectPositionFarmModal/index.tsx | 4 ++-- src/components/position/PositionCard/index.tsx | 12 ++++++++---- src/hooks/farming/useFarmCheckApprove.ts | 9 +++++---- src/hooks/farming/useFarmHarvest.ts | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index e0ecf46..6830391 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -89,8 +89,8 @@ export function SelectPositionFarmModal({ {availablePositions.length > 0 ? ( availablePositions.map((position) => { const currentFormattedPosition = positionsData.find( - (position) => - Number(position.id) === Number(position.id) + (fposition) => + Number(fposition.id) === Number(position.id) ); if (!currentFormattedPosition) return; return ( diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index ba1824d..c8ec765 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -3,7 +3,11 @@ import { usePosition, usePositionInFarming, } from '@/hooks/positions/usePositions'; -import { INITIAL_POOL_FEE, Position } from '@cryptoalgebra/integral-sdk'; +import { + ADDRESS_ZERO, + INITIAL_POOL_FEE, + Position, +} from '@cryptoalgebra/integral-sdk'; import PositionNFT from '../PositionNFT'; import { FormattedPosition } from '@/types/formatted-position'; import { formatUSD } from '@/utils/common/formatUSD'; @@ -15,7 +19,7 @@ import CollectFees from '../CollectFees'; import RemoveLiquidityModal from '@/components/modals/RemoveLiquidityModal'; import { Button } from '@/components/ui/button'; import { useFarmUnstake } from '@/hooks/farming/useFarmStake'; -import { Address, useAccount } from 'wagmi'; +import { useAccount } from 'wagmi'; import Loader from '@/components/common/Loader'; import { Farming } from '@/types/farming-info'; import { useFarmHarvest } from '@/hooks/farming/useFarmHarvest'; @@ -38,7 +42,7 @@ const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { bonusRewardToken: farming.farming.bonusRewardToken, pool: farming.farming.pool, nonce: farming.farming.nonce, - account: account as Address, + account: account ?? ADDRESS_ZERO, }); const { onUnstake, isLoading: isUnstaking } = useFarmUnstake({ @@ -47,7 +51,7 @@ const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { bonusRewardToken: farming.farming.bonusRewardToken, pool: farming.farming.pool, nonce: farming.farming.nonce, - account: account as Address, + account: account ?? ADDRESS_ZERO, }); const handleUnstake = async () => { diff --git a/src/hooks/farming/useFarmCheckApprove.ts b/src/hooks/farming/useFarmCheckApprove.ts index de658f3..5db9422 100644 --- a/src/hooks/farming/useFarmCheckApprove.ts +++ b/src/hooks/farming/useFarmCheckApprove.ts @@ -5,9 +5,10 @@ import { useEffect, useState } from 'react'; export function useFarmCheckApprove(tokenId: bigint) { const [approved, setApproved] = useState(); - const { data } = useAlgebraPositionManagerFarmingApprovals({ - args: [tokenId], - }); + const { data, isLoading: isApproveLoading } = + useAlgebraPositionManagerFarmingApprovals({ + args: [tokenId], + }); useEffect(() => { setApproved(data !== ADDRESS_ZERO); @@ -15,6 +16,6 @@ export function useFarmCheckApprove(tokenId: bigint) { return { approved, - isLoading: approved === undefined, + isLoading: approved === undefined || isApproveLoading, }; } diff --git a/src/hooks/farming/useFarmHarvest.ts b/src/hooks/farming/useFarmHarvest.ts index 2587884..b6a61bc 100644 --- a/src/hooks/farming/useFarmHarvest.ts +++ b/src/hooks/farming/useFarmHarvest.ts @@ -31,7 +31,7 @@ export function useFarmHarvest({ }); const { config } = usePrepareContractWrite({ - address: FARMING_CENTER, + address: account ? FARMING_CENTER : undefined, abi: farmingCenterABI, functionName: 'multicall', args: [calldata], From f9952688c37a82cb315b4b9bf4f5b1f6ebaed0e4 Mon Sep 17 00:00:00 2001 From: damnnou Date: Tue, 12 Mar 2024 12:44:22 +0300 Subject: [PATCH 26/47] add: auto refetch after farming stake/unstake --- .../modals/SelectPositionFarmModal/index.tsx | 18 ++++++++++---- src/hooks/farming/useFarmStake.ts | 24 +++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index 6830391..53476b3 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -14,7 +14,7 @@ import { useFarmCheckApprove } from '@/hooks/farming/useFarmCheckApprove'; import { cn } from '@/lib/utils'; import { Farming } from '@/types/farming-info'; import { FormattedPosition } from '@/types/formatted-position'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useFarmStake } from '@/hooks/farming/useFarmStake'; interface SelectPositionFarmModalProps { @@ -30,12 +30,18 @@ export function SelectPositionFarmModal({ positionsData, isHarvestLoading, }: SelectPositionFarmModalProps) { - const [selectedPosition, setSelectedPosition] = useState(); + const [selectedPosition, setSelectedPosition] = useState( + null + ); const tokenId = selectedPosition ? BigInt(selectedPosition.id) : 0n; const { isLoading: isApproveLoading, onApprove } = useFarmApprove(tokenId); - const { isLoading: isStakeLoading, onStake } = useFarmStake({ + const { + isLoading: isStakeLoading, + onStake, + isSuccess, + } = useFarmStake({ tokenId, rewardToken: farming.farming.rewardToken, bonusRewardToken: farming.farming.bonusRewardToken, @@ -65,6 +71,10 @@ export function SelectPositionFarmModal({ (position) => position.eternalFarming === null ); + useEffect(() => { + setSelectedPosition(null); + }, [isSuccess]); + return ( @@ -128,7 +138,7 @@ export function SelectPositionFarmModal({ ) : selectedPosition && availablePositions.length > 0 ? ( <> + +
    )} - - }) : - - No results. - - - } - - - { - showPagination && -
    - - -
    } - -} + + ); +}; -const LoadingState = () =>
    - {[1,2,3,4].map(v => )} -
    +const LoadingState = () => ( +
    + {[1, 2, 3, 4].map((v) => ( + + ))} +
    +); -export default DataTable \ No newline at end of file +export default DataTable; diff --git a/src/components/pool/MyPositions/index.tsx b/src/components/pool/MyPositions/index.tsx index acff8af..7c56886 100644 --- a/src/components/pool/MyPositions/index.tsx +++ b/src/components/pool/MyPositions/index.tsx @@ -18,6 +18,7 @@ const MyPositions = ({ return (
    { - query.refetch().then(); - }, - }); -} diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index 9072fd1..f42ede4 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -48,16 +48,14 @@ export function useActiveFarming({ }, }); - const { - data: deposits, - // refetch, - } = useDepositsQuery({ + const { data: deposits } = useDepositsQuery({ variables: { owner: account, pool: poolId, }, client: farmingClient, skip: !poolInfo, + pollInterval: 5000, }); useEffect(() => { @@ -89,15 +87,5 @@ export function useActiveFarming({ console.log('Positions - ', deposits.deposits); }, [deposits]); - // useEffect(() => { - // if (!deposits) return; - - // const timeoutId = setInterval(() => { - // console.log('refetching deps... '); - // refetch(); - // }, 5000); - - // }, []); - return { farmingInfo, deposits, isLoading }; } diff --git a/src/hooks/farming/useFarmStake.ts b/src/hooks/farming/useFarmStake.ts index 4dcb0b0..9098dc8 100644 --- a/src/hooks/farming/useFarmStake.ts +++ b/src/hooks/farming/useFarmStake.ts @@ -4,8 +4,6 @@ import { Address, useContractWrite, usePrepareContractWrite } from 'wagmi'; import { useTransitionAwait } from '../common/useTransactionAwait'; import { encodeFunctionData } from 'viem'; import { MaxUint128 } from '@cryptoalgebra/integral-sdk'; -import { useEffect } from 'react'; -import { refetchDepositsQuery } from '@/graphql/utils/refetchDepositsQuery'; export function useFarmStake({ tokenId, @@ -42,12 +40,6 @@ export function useFarmStake({ `Stake Position #${tokenId}` ); - useEffect(() => { - if (isSuccess) { - refetchDepositsQuery(); - } - }, [isSuccess]); - return { isLoading, isSuccess, @@ -116,12 +108,6 @@ export function useFarmUnstake({ `Unstake Position #${tokenId}` ); - useEffect(() => { - if (isSuccess) { - refetchDepositsQuery(); - } - }, [isSuccess]); - return { isLoading, isSuccess, diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index f05fe09..72d3c1f 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -47,6 +47,15 @@ const PoolPage = () => { const { data: bundles } = useNativePriceQuery(); + const { + farmingInfo, + deposits, + isLoading: isFarmingLoading, + } = useActiveFarming({ + poolId: poolId, + poolInfo: poolInfo, + }); + const [positionsFees, setPositionsFees] = useState(); const [positionsAPRs, setPositionsAPRs] = useState(); @@ -143,22 +152,32 @@ const PoolPage = () => { }; const positionsData = useMemo(() => { - if (!filteredPositions || !poolEntity) return []; - - return filteredPositions.map( - ({ positionId, position }, idx) => - ({ - id: positionId, - outOfRange: - poolEntity.tickCurrent < position.tickLower || - poolEntity.tickCurrent > position.tickUpper, - range: `${position.token0PriceLower.toFixed()} — ${position.token0PriceUpper.toFixed()}`, - liquidityUSD: formatLiquidityUSD(position), - feesUSD: formatFeesUSD(idx), - apr: formatAPR(idx), - } as FormattedPosition) - ); - }, [filteredPositions, poolEntity, poolInfo, positionsFees, positionsAPRs]); + if (!filteredPositions || !poolEntity || !deposits) return []; + + return filteredPositions.map(({ positionId, position }, idx) => { + const currentPosition = deposits.deposits.find( + (deposit) => Number(deposit.id) === Number(positionId) + ); + return { + id: positionId, + outOfRange: + poolEntity.tickCurrent < position.tickLower || + poolEntity.tickCurrent > position.tickUpper, + range: `${position.token0PriceLower.toFixed()} — ${position.token0PriceUpper.toFixed()}`, + liquidityUSD: formatLiquidityUSD(position), + feesUSD: formatFeesUSD(idx), + apr: formatAPR(idx), + inFarming: currentPosition?.eternalFarming ? true : false, + } as FormattedPosition; + }); + }, [ + filteredPositions, + poolEntity, + poolInfo, + positionsFees, + positionsAPRs, + deposits, + ]); const selectedPosition = useMemo(() => { if (!positionsData || !selectedPositionId) return; @@ -171,15 +190,6 @@ const PoolPage = () => { const noPositions = !positionsLoading && positionsData.length === 0 && poolEntity; - const { - farmingInfo, - deposits, - isLoading: isFarmingLoading, - } = useActiveFarming({ - poolId: poolId, - poolInfo: poolInfo, - }); - return ( From ffa76d0747501471c17dfbad4f859407b6d8764a Mon Sep 17 00:00:00 2001 From: damnnou Date: Tue, 12 Mar 2024 22:21:47 +0300 Subject: [PATCH 29/47] fix: fix farming loading --- src/hooks/farming/useActiveFarming.ts | 6 +++++- src/pages/Pool/index.tsx | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index f42ede4..bd00d2b 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -87,5 +87,9 @@ export function useActiveFarming({ console.log('Positions - ', deposits.deposits); }, [deposits]); - return { farmingInfo, deposits, isLoading }; + return { + farmingInfo, + deposits, + isLoading: isLoading || farmingInfo === undefined, + }; } diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 72d3c1f..9fbac56 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -230,7 +230,8 @@ const PoolPage = () => { />
    ) : ( - + !isFarmingLoading && + !farmingInfo && )} )} From c93cb46ecdef3e09d1fb5abe661e950c7dd2279f Mon Sep 17 00:00:00 2001 From: damnnou Date: Tue, 12 Mar 2024 22:35:33 +0300 Subject: [PATCH 30/47] refactor: remove useless components, fix farming loading --- .../farming/ActiveFarming/index.tsx | 135 +++++++++--------- .../farming/ClosedFarmings/index.tsx | 22 --- src/components/farming/FarmRewards/index.tsx | 9 -- src/components/farming/Farmings/index.tsx | 32 ----- src/hooks/farming/useActiveFarming.ts | 2 +- src/pages/Pool/index.tsx | 6 +- 6 files changed, 73 insertions(+), 133 deletions(-) delete mode 100644 src/components/farming/ClosedFarmings/index.tsx delete mode 100644 src/components/farming/FarmRewards/index.tsx delete mode 100644 src/components/farming/Farmings/index.tsx diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 65fe0a5..69f056b 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -130,83 +130,86 @@ const ActiveFarming = ({ }, [deposits, farming, isSuccess]); return ( -
    -
    -
    - -

    45%

    -
    - -

    ${formattedTVL}

    +
    +
    +
    +
    + +

    45%

    +
    + +

    ${formattedTVL}

    +
    +
    + + +

    + $ + {formattedRewardEarned + formattedBonusRewardEarned} +

    - -

    - ${formattedRewardEarned + formattedBonusRewardEarned} -

    -
    -
    - - -
    -
    - -

    - {rewardRatePerDay + - ' ' + - farming.rewardToken.symbol}{' '} - / day -

    -
    - {bonusRewardRatePerDay !== 0 && ( + +

    - {bonusRewardRatePerDay}{' '} - {farming.bonusRewardToken.symbol} / day + {rewardRatePerDay + + ' ' + + farming.rewardToken.symbol}{' '} + / day

    - )} + {bonusRewardRatePerDay !== 0 && ( +
    + +

    + {bonusRewardRatePerDay}{' '} + {farming.bonusRewardToken.symbol} / day +

    +
    + )} +
    +
    + +
    + +
    - - -
    - -
    ); diff --git a/src/components/farming/ClosedFarmings/index.tsx b/src/components/farming/ClosedFarmings/index.tsx deleted file mode 100644 index 2487961..0000000 --- a/src/components/farming/ClosedFarmings/index.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { EternalFarming } from '@/graphql/generated/graphql'; - -interface ActiveFarmingProps { - farmings: EternalFarming[]; -} - -const ClosedFarmings = ({ farmings }: ActiveFarmingProps) => { - return ( -
    - Closed Farmings -
      - {farmings && - farmings.length > 0 && - farmings.map((farm) => ( -
    • {farm.id.slice(0, 12)}
    • - ))} -
    -
    - ); -}; - -export default ClosedFarmings; diff --git a/src/components/farming/FarmRewards/index.tsx b/src/components/farming/FarmRewards/index.tsx deleted file mode 100644 index de39a3c..0000000 --- a/src/components/farming/FarmRewards/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -const FarmRewards = () => { - return ( -
    - Farm Rewards -
    - ); -}; - -export default FarmRewards; diff --git a/src/components/farming/Farmings/index.tsx b/src/components/farming/Farmings/index.tsx deleted file mode 100644 index 8909421..0000000 --- a/src/components/farming/Farmings/index.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Deposit } from '@/graphql/generated/graphql'; -import { Farming } from '@/types/farming-info'; -import { Loader } from 'lucide-react'; -import { FormattedPosition } from '@/types/formatted-position'; -import ActiveFarming from '../ActiveFarming'; - -interface FarmingsProps { - farming: Farming; - deposits: Deposit[]; - positionsData: FormattedPosition[]; -} - -const Farmings = ({ farming, deposits, positionsData }: FarmingsProps) => { - return ( -
    - {!farming || !deposits ? ( - - ) : ( - <> - - {/* */} - - )} -
    - ); -}; - -export default Farmings; diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index bd00d2b..6374587 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -90,6 +90,6 @@ export function useActiveFarming({ return { farmingInfo, deposits, - isLoading: isLoading || farmingInfo === undefined, + isLoading, }; } diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 9fbac56..daeb9dc 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -1,4 +1,5 @@ import PageContainer from '@/components/common/PageContainer'; +import ActiveFarming from '@/components/farming/ActiveFarming'; import Farmings from '@/components/farming/Farmings'; import MyPositions from '@/components/pool/MyPositions'; import MyPositionsToolbar from '@/components/pool/MyPositionsToolbar'; @@ -223,15 +224,14 @@ const PoolPage = () => {

    Farmings

    -
    ) : ( - !isFarmingLoading && - !farmingInfo && + isFarmingLoading && )} )} From e64b2bb633320d5a799d51065d5313f5e154ad18 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 10:42:34 +0300 Subject: [PATCH 31/47] fix: card open for non-farming positions --- .../position/PositionCard/index.tsx | 52 +++++++++++-------- src/hooks/farming/useActiveFarming.ts | 15 +++--- src/pages/Pool/index.tsx | 15 +++--- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index c8ec765..487bce8 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -26,7 +26,7 @@ import { useFarmHarvest } from '@/hooks/farming/useFarmHarvest'; interface PositionCardProps { selectedPosition: FormattedPosition | undefined; - farming: Farming; + farming?: Farming | null; } const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { @@ -36,23 +36,27 @@ const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { const positionInFarming = usePositionInFarming(selectedPosition?.id); - const { onHarvest, isLoading: isHarvesting } = useFarmHarvest({ - tokenId: positionInFarming ? BigInt(positionInFarming?.id) : 0n, - rewardToken: farming.farming.rewardToken, - bonusRewardToken: farming.farming.bonusRewardToken, - pool: farming.farming.pool, - nonce: farming.farming.nonce, - account: account ?? ADDRESS_ZERO, - }); - - const { onUnstake, isLoading: isUnstaking } = useFarmUnstake({ - tokenId: positionInFarming ? BigInt(positionInFarming?.id) : 0n, - rewardToken: farming.farming.rewardToken, - bonusRewardToken: farming.farming.bonusRewardToken, - pool: farming.farming.pool, - nonce: farming.farming.nonce, - account: account ?? ADDRESS_ZERO, - }); + const farmingArgs = { + tokenId: + positionInFarming && farming ? BigInt(positionInFarming?.id) : 0n, + rewardToken: + positionInFarming && farming + ? farming.farming.rewardToken + : ADDRESS_ZERO, + bonusRewardToken: + positionInFarming && farming + ? farming.farming.bonusRewardToken + : ADDRESS_ZERO, + pool: + positionInFarming && farming ? farming.farming.pool : ADDRESS_ZERO, + nonce: positionInFarming && farming ? farming.farming.nonce : 0n, + account: + account && positionInFarming && farming ? account : ADDRESS_ZERO, + }; + + const { onHarvest, isLoading: isHarvesting } = useFarmHarvest(farmingArgs); + + const { onUnstake, isLoading: isUnstaking } = useFarmUnstake(farmingArgs); const handleUnstake = async () => { if (!positionInFarming) return; @@ -161,12 +165,18 @@ const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => {
    - {positionInFarming && ( + {positionInFarming && farming && (
    - -
    diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index 6374587..360abe7 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -18,7 +18,7 @@ export function useActiveFarming({ }) { const { address: account } = useAccount(); - const [farmingInfo, setFarmingInfo] = useState(); + const [farmingInfo, setFarmingInfo] = useState(); const { farmingClient } = useClients(); @@ -59,14 +59,15 @@ export function useActiveFarming({ }); useEffect(() => { - if (!farmings?.eternalFarmings || farmings.eternalFarmings.length === 0) - return; - if (!rewardToken || !bonusRewardToken || !poolInfo) return; - + if (!farmings?.eternalFarmings) return; if (!activeFarming) { - console.error('Active farming not found'); + console.log('Active farming not found'); + setFarmingInfo(null); return; } + if (!poolInfo) return; + if (!rewardToken) return; + if (!bonusRewardToken) return; // ! disabled null check setFarmingInfo({ @@ -75,7 +76,7 @@ export function useActiveFarming({ bonusRewardToken: bonusRewardToken.token!, pool: poolInfo.pool, }); - }, [farmings, rewardToken, bonusRewardToken, poolInfo]); + }, [farmings, rewardToken, bonusRewardToken, poolInfo, activeFarming]); useEffect(() => { if (!farmingInfo) return; diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index daeb9dc..4f9c8ae 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -1,6 +1,5 @@ import PageContainer from '@/components/common/PageContainer'; import ActiveFarming from '@/components/farming/ActiveFarming'; -import Farmings from '@/components/farming/Farmings'; import MyPositions from '@/components/pool/MyPositions'; import MyPositionsToolbar from '@/components/pool/MyPositionsToolbar'; import PoolHeader from '@/components/pool/PoolHeader'; @@ -237,14 +236,12 @@ const PoolPage = () => { )}
    - {farmingInfo && ( -
    - -
    - )} +
    + +
    ); From ace5c0264d931eb69d4d9d77f8471402f1e86275 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 13:19:08 +0300 Subject: [PATCH 32/47] fix: add Collect Farmings block in Position Card --- .../farming/ActiveFarming/index.tsx | 10 +- .../position/CollectFarmings/index.tsx | 105 ++++++++++++++++++ .../position/PositionCard/index.tsx | 68 ++---------- 3 files changed, 117 insertions(+), 66 deletions(-) create mode 100644 src/components/position/CollectFarmings/index.tsx diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 69f056b..32d7579 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -35,11 +35,6 @@ const ActiveFarming = ({ farming.farming.bonusRewardToken ); - const rewardTokenCurrency = useCurrency(farming.farming.rewardToken); - const bonusRewardTokenCurrency = useCurrency( - farming.farming.bonusRewardToken - ); - const formattedRewardEarned = Number( formatUnits(rewardEarned, farming.rewardToken.decimals) ); @@ -48,6 +43,11 @@ const ActiveFarming = ({ formatUnits(bonusRewardEarned, farming.bonusRewardToken.decimals) ); + const rewardTokenCurrency = useCurrency(farming.farming.rewardToken); + const bonusRewardTokenCurrency = useCurrency( + farming.farming.bonusRewardToken + ); + const TVL = deposits.reduce((acc, deposit) => { const currentFormattedPosition = positionsData.find( (position) => Number(position.id) === Number(deposit.id) diff --git a/src/components/position/CollectFarmings/index.tsx b/src/components/position/CollectFarmings/index.tsx new file mode 100644 index 0000000..f215618 --- /dev/null +++ b/src/components/position/CollectFarmings/index.tsx @@ -0,0 +1,105 @@ +import { useEffect, useState } from 'react'; +import { Farming } from '@/types/farming-info'; +import { formatUnits } from 'viem'; +import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; +import { useFarmHarvest } from '@/hooks/farming/useFarmHarvest'; +import { useFarmUnstake } from '@/hooks/farming/useFarmStake'; +import { useAccount } from 'wagmi'; +import { getFarmingRewards } from '@/utils/farming/getFarmingRewards'; +import { Button } from '@/components/ui/button'; +import Loader from '@/components/common/Loader'; +import { Deposit } from '@/graphql/generated/graphql'; + +interface CollectFarmingsProps { + farming: Farming; + selectedPosition: Deposit; +} + +const CollectFarmings = ({ + farming, + selectedPosition, +}: CollectFarmingsProps) => { + const { address: account } = useAccount(); + + const [rewardEarned, setRewardEarned] = useState(0n); + const [bonusRewardEarned, setBonusRewardEarned] = useState(0n); + + const formattedRewardEarned = Number( + formatUnits(rewardEarned, farming.rewardToken.decimals) + ); + + const formattedBonusRewardEarned = Number( + formatUnits(bonusRewardEarned, farming.bonusRewardToken.decimals) + ); + + const farmingRewards = ( + formattedRewardEarned + formattedBonusRewardEarned + ).toFixed(4); + + const farmingArgs = { + tokenId: BigInt(selectedPosition.id), + rewardToken: farming.farming.rewardToken, + bonusRewardToken: farming.farming.bonusRewardToken, + pool: farming.farming.pool, + nonce: farming.farming.nonce, + account: account ?? ADDRESS_ZERO, + }; + + const { + onHarvest, + isLoading: isHarvesting, + isSuccess: isHarvested, + } = useFarmHarvest(farmingArgs); + + const { onUnstake, isLoading: isUnstaking } = useFarmUnstake(farmingArgs); + + const handleUnstake = async () => { + if (!account) return; + if (!onUnstake) return; + onUnstake(); + }; + + const handleHarvest = async () => { + if (!account) return; + if (!onHarvest) return; + onHarvest(); + }; + + useEffect(() => { + if (!account) return; + getFarmingRewards(farmingArgs).then((rewards) => { + setRewardEarned(rewards.reward); + setBonusRewardEarned(rewards.bonusReward); + }); + }, [farming, account, selectedPosition, isHarvested]); + + return ( +
    +
    +
    +
    EARNED FARMINGS
    +
    + + ${farmingRewards} + +
    +
    + +
    + +
    + ); +}; + +export default CollectFarmings; diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index 487bce8..ea05570 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -3,11 +3,7 @@ import { usePosition, usePositionInFarming, } from '@/hooks/positions/usePositions'; -import { - ADDRESS_ZERO, - INITIAL_POOL_FEE, - Position, -} from '@cryptoalgebra/integral-sdk'; +import { INITIAL_POOL_FEE, Position } from '@cryptoalgebra/integral-sdk'; import PositionNFT from '../PositionNFT'; import { FormattedPosition } from '@/types/formatted-position'; import { formatUSD } from '@/utils/common/formatUSD'; @@ -17,12 +13,8 @@ import TokenRatio from '@/components/create-position/TokenRatio'; import { useDerivedMintInfo } from '@/state/mintStore'; import CollectFees from '../CollectFees'; import RemoveLiquidityModal from '@/components/modals/RemoveLiquidityModal'; -import { Button } from '@/components/ui/button'; -import { useFarmUnstake } from '@/hooks/farming/useFarmStake'; -import { useAccount } from 'wagmi'; -import Loader from '@/components/common/Loader'; import { Farming } from '@/types/farming-info'; -import { useFarmHarvest } from '@/hooks/farming/useFarmHarvest'; +import CollectFarmings from '../CollectFarmings'; interface PositionCardProps { selectedPosition: FormattedPosition | undefined; @@ -32,44 +24,8 @@ interface PositionCardProps { const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { const { loading, position } = usePosition(selectedPosition?.id); - const { address: account } = useAccount(); - const positionInFarming = usePositionInFarming(selectedPosition?.id); - const farmingArgs = { - tokenId: - positionInFarming && farming ? BigInt(positionInFarming?.id) : 0n, - rewardToken: - positionInFarming && farming - ? farming.farming.rewardToken - : ADDRESS_ZERO, - bonusRewardToken: - positionInFarming && farming - ? farming.farming.bonusRewardToken - : ADDRESS_ZERO, - pool: - positionInFarming && farming ? farming.farming.pool : ADDRESS_ZERO, - nonce: positionInFarming && farming ? farming.farming.nonce : 0n, - account: - account && positionInFarming && farming ? account : ADDRESS_ZERO, - }; - - const { onHarvest, isLoading: isHarvesting } = useFarmHarvest(farmingArgs); - - const { onUnstake, isLoading: isUnstaking } = useFarmUnstake(farmingArgs); - - const handleUnstake = async () => { - if (!positionInFarming) return; - if (!onUnstake) return; - onUnstake(); - }; - - const handleHarvest = async () => { - if (!positionInFarming) return; - if (!onHarvest) return; - onHarvest(); - }; - const [, pool] = usePool(position?.pool); const positionEntity = pool && @@ -165,21 +121,11 @@ const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => {
    - {positionInFarming && farming && ( -
    - - -
    + {farming && selectedPosition && positionInFarming && ( + )}
    ); From f58a2fbdcc647c15316fd57a8a7a6889b5bfd5b3 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 13:36:25 +0300 Subject: [PATCH 33/47] fix: round to 4 decimals farmings info --- .../farming/ActiveFarming/index.tsx | 63 ++++++++++++------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 32d7579..753c5ec 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -61,28 +61,44 @@ const ActiveFarming = ({ const formattedTVL = TVL.toFixed(2); - const rewardRatePerDay = - Number( - formatUnits( - farming.farming.rewardRate, - farming.rewardToken.decimals - ) - ) * - 60 * - 60 * - 24; + const rewardRatePerDay = isSameReward + ? ( + Number( + formatUnits( + farming.farming.rewardRate, + farming.rewardToken.decimals + ) + ) * + 60 * + 60 * + 24 * + 2 + ).toFixed(2) + : ( + Number( + formatUnits( + farming.farming.rewardRate, + farming.rewardToken.decimals + ) + ) * + 60 * + 60 * + 24 + ).toFixed(2); const bonusRewardRatePerDay = isSameReward ? 0 - : Number( - formatUnits( - farming.farming.bonusRewardRate, - farming.bonusRewardToken.decimals - ) - ) * - 60 * - 60 * - 24; + : ( + Number( + formatUnits( + farming.farming.bonusRewardRate, + farming.bonusRewardToken.decimals + ) + ) * + 60 * + 60 * + 24 + ).toFixed(2); const { isLoading, onHarvestAll, isSuccess } = useFarmHarvestAll( { @@ -145,10 +161,10 @@ const ActiveFarming = ({

    $ - {formattedRewardEarned + formattedBonusRewardEarned} + {( + formattedRewardEarned + + formattedBonusRewardEarned + ).toFixed(4)}

From ab8110abb3a9415579eb2f1fcec8095733305bfd Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 14:13:23 +0300 Subject: [PATCH 34/47] chore: fix horse pool --- src/hooks/farming/useActiveFarming.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index 360abe7..46fe4f9 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -60,14 +60,14 @@ export function useActiveFarming({ useEffect(() => { if (!farmings?.eternalFarmings) return; - if (!activeFarming) { + if (!poolInfo) return; + if (!rewardToken) return; + if (!bonusRewardToken) return; + if (!activeFarming || !bonusRewardToken.token || !rewardToken.token) { console.log('Active farming not found'); setFarmingInfo(null); return; } - if (!poolInfo) return; - if (!rewardToken) return; - if (!bonusRewardToken) return; // ! disabled null check setFarmingInfo({ From ff5384097284b6291b6c9cbf4526c8dce9f61f92 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 14:20:06 +0300 Subject: [PATCH 35/47] fix: ts warnings --- src/components/common/Table/dataTable.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/common/Table/dataTable.tsx b/src/components/common/Table/dataTable.tsx index 0cdb64c..c04a564 100644 --- a/src/components/common/Table/dataTable.tsx +++ b/src/components/common/Table/dataTable.tsx @@ -66,15 +66,17 @@ const DataTable = ({ }, }); - const farmingPositions = data.filter((pos) => pos.inFarming); + const farmingPositions = data.filter((pos: any) => pos.inFarming); - const zeroLiquidityPositions = data.filter((pos) => pos.liquidityUSD === 0); + const zeroLiquidityPositions = data.filter( + (pos: any) => pos.liquidityUSD === 0 + ); function renderFarmingPositions() { if (farmingPositions.length === 0) return null; let firstMatchFound = false; - return table.getRowModel().rows.map((row) => { + return table.getRowModel().rows.map((row: any) => { const isSelected = Number(selectedRow) === Number(row.original.id); if (row.original.inFarming) { const renderIndex = firstMatchFound ? null : ( @@ -131,7 +133,7 @@ const DataTable = ({ if (zeroLiquidityPositions.length === 0) return null; let firstMatchFound = false; - return table.getRowModel().rows.map((row) => { + return table.getRowModel().rows.map((row: any) => { const isSelected = Number(selectedRow) === Number(row.original.id); if (row.original.liquidityUSD === 0) { const renderIndex = firstMatchFound ? null : ( From db054d1c7b06dc2babb72549079d6f4ac6cacd04 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 14:28:13 +0300 Subject: [PATCH 36/47] fix: ts warnings --- src/components/common/Table/dataTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/common/Table/dataTable.tsx b/src/components/common/Table/dataTable.tsx index c04a564..b161144 100644 --- a/src/components/common/Table/dataTable.tsx +++ b/src/components/common/Table/dataTable.tsx @@ -113,7 +113,7 @@ const DataTable = ({ } }} > - {row.getVisibleCells().map((cell) => ( + {row.getVisibleCells().map((cell: any) => ( {flexRender( cell.column.columnDef.cell, @@ -170,7 +170,7 @@ const DataTable = ({ } }} > - {row.getVisibleCells().map((cell) => ( + {row.getVisibleCells().map((cell: any) => ( {flexRender( cell.column.columnDef.cell, From b8b52acc26590b3bea71f9a53dd2336448b4e996 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 15:50:59 +0300 Subject: [PATCH 37/47] fix: change rpc, add handleCheckApprove, chore fixes --- .env | 2 +- src/components/common/Table/dataTable.tsx | 2 +- .../farming/ActiveFarming/index.tsx | 8 +-- .../farming/ClosedFarming/index.tsx | 13 ++++ .../modals/SelectPositionFarmModal/index.tsx | 4 +- .../position/CollectFarmings/index.tsx | 6 +- src/hooks/farming/useActiveFarming.ts | 9 ++- src/hooks/farming/useClosedFarmings.ts | 64 +++++++++++++++++++ src/hooks/farming/useFarmApprove.ts | 10 +++ src/hooks/farming/useFarmCheckApprove.ts | 14 ++-- src/pages/Pool/index.tsx | 20 ++++++ src/types/farming-info.ts | 2 +- src/utils/farming/isSameRewards.ts | 6 +- 13 files changed, 138 insertions(+), 22 deletions(-) create mode 100644 src/components/farming/ClosedFarming/index.tsx create mode 100644 src/hooks/farming/useClosedFarmings.ts diff --git a/.env b/.env index 0afcd55..8ed9160 100644 --- a/.env +++ b/.env @@ -2,5 +2,5 @@ VITE_INFO_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/integral-core VITE_LIMIT_ORDERS_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/integral-limit-order VITE_BLOCKS_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/goerli-blocks VITE_FARMING_GRAPH=https://api.thegraph.com/subgraphs/name/iliaazhel/farming-test -VITE_INFURA_RPC=https://1rpc.io/holesky +VITE_INFURA_RPC=https://ethereum-holesky-rpc.publicnode.com VITE_WALLETCONNECT_PROJECT_ID=79c313a96c99edbc26d06cd97bff1126 \ No newline at end of file diff --git a/src/components/common/Table/dataTable.tsx b/src/components/common/Table/dataTable.tsx index b161144..111df45 100644 --- a/src/components/common/Table/dataTable.tsx +++ b/src/components/common/Table/dataTable.tsx @@ -84,7 +84,7 @@ const DataTable = ({ key={'in-farming-positions'} className="hover:bg-transparent flex p-4 border-none" > - In Farming + On Farming ); firstMatchFound = true; diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 753c5ec..a9b2640 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -40,7 +40,7 @@ const ActiveFarming = ({ ); const formattedBonusRewardEarned = Number( - formatUnits(bonusRewardEarned, farming.bonusRewardToken.decimals) + formatUnits(bonusRewardEarned, farming.bonusRewardToken?.decimals) ); const rewardTokenCurrency = useCurrency(farming.farming.rewardToken); @@ -92,7 +92,7 @@ const ActiveFarming = ({ Number( formatUnits( farming.farming.bonusRewardRate, - farming.bonusRewardToken.decimals + farming.bonusRewardToken?.decimals ) ) * 60 * @@ -165,7 +165,7 @@ const ActiveFarming = ({ farming.rewardToken.symbol } + ${formattedBonusRewardEarned.toFixed( 2 - )} ${farming.bonusRewardToken.symbol}` + )} ${farming.bonusRewardToken?.symbol}` : '' } className="w-1/2" @@ -203,7 +203,7 @@ const ActiveFarming = ({ />

{bonusRewardRatePerDay}{' '} - {farming.bonusRewardToken.symbol} / day + {farming.bonusRewardToken?.symbol} / day

)} diff --git a/src/components/farming/ClosedFarming/index.tsx b/src/components/farming/ClosedFarming/index.tsx new file mode 100644 index 0000000..12017e1 --- /dev/null +++ b/src/components/farming/ClosedFarming/index.tsx @@ -0,0 +1,13 @@ +import { EternalFarming } from '@/graphql/generated/graphql'; +import React from 'react'; + +export interface ClosedFarmingProps { + farming: EternalFarming; +} + +const ClosedFarming = React.memo(({ farming }: ClosedFarmingProps) => { + console.log(farming); + return
ClosedFarming
; +}); + +export default ClosedFarming; diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index 911a5f9..1f8549c 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -73,7 +73,9 @@ export function SelectPositionFarmModal({ ); useEffect(() => { - if (isSuccess) setSelectedPosition(null); + if (isSuccess) { + setSelectedPosition(null); + } }, [isSuccess]); return ( diff --git a/src/components/position/CollectFarmings/index.tsx b/src/components/position/CollectFarmings/index.tsx index f215618..1b38c31 100644 --- a/src/components/position/CollectFarmings/index.tsx +++ b/src/components/position/CollectFarmings/index.tsx @@ -29,7 +29,7 @@ const CollectFarmings = ({ ); const formattedBonusRewardEarned = Number( - formatUnits(bonusRewardEarned, farming.bonusRewardToken.decimals) + formatUnits(bonusRewardEarned, farming.bonusRewardToken?.decimals) ); const farmingRewards = ( @@ -77,7 +77,7 @@ const CollectFarmings = ({
-
EARNED FARMINGS
+
EARNED REWARDS
${farmingRewards} @@ -89,7 +89,7 @@ const CollectFarmings = ({ disabled={isHarvesting || isUnstaking} onClick={handleHarvest} > - {isHarvesting ? : 'Collect farmings'} + {isHarvesting ? : 'Collect'}
diff --git a/src/types/farming-info.ts b/src/types/farming-info.ts index 69f224d..c5f5ed7 100644 --- a/src/types/farming-info.ts +++ b/src/types/farming-info.ts @@ -7,6 +7,6 @@ import { export interface Farming { farming: EternalFarming; rewardToken: TokenFieldsFragment; - bonusRewardToken: TokenFieldsFragment; + bonusRewardToken: TokenFieldsFragment | null; pool: SinglePoolQuery['pool']; } diff --git a/src/utils/farming/isSameRewards.ts b/src/utils/farming/isSameRewards.ts index 010026b..663fb30 100644 --- a/src/utils/farming/isSameRewards.ts +++ b/src/utils/farming/isSameRewards.ts @@ -1,8 +1,12 @@ +import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; import { Address } from 'viem'; export const isSameRewards = ( rewardToken: Address, bonusRewardToken: Address ): boolean => { - return rewardToken.toLowerCase() === bonusRewardToken.toLowerCase(); + return ( + rewardToken.toLowerCase() === bonusRewardToken.toLowerCase() || + bonusRewardToken === ADDRESS_ZERO + ); }; From dadbdef2ee95ecd54f872e39901e10b978ca9050 Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 16:04:25 +0300 Subject: [PATCH 38/47] fix: ts warnings --- src/pages/Pool/index.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 7208fa9..5a1fc87 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -58,11 +58,10 @@ const PoolPage = () => { poolInfo: poolInfo, }); - const { closedFarmings, isLoading: isClosedFarmingsLoading } = - useClosedFarmings({ - poolId: poolId, - poolInfo: poolInfo, - }); + const { closedFarmings } = useClosedFarmings({ + poolId: poolId, + poolInfo: poolInfo, + }); const [positionsFees, setPositionsFees] = useState(); const [positionsAPRs, setPositionsAPRs] = useState(); From 7ccd05a71edf5ac31a2a8af55b92053c1bef2fbd Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 16:39:47 +0300 Subject: [PATCH 39/47] fix: enable deposit after approve --- src/components/modals/SelectPositionFarmModal/index.tsx | 8 +++----- src/hooks/farming/useFarmStake.ts | 7 ++++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/modals/SelectPositionFarmModal/index.tsx b/src/components/modals/SelectPositionFarmModal/index.tsx index 1f8549c..9e61c29 100644 --- a/src/components/modals/SelectPositionFarmModal/index.tsx +++ b/src/components/modals/SelectPositionFarmModal/index.tsx @@ -30,11 +30,11 @@ export function SelectPositionFarmModal({ positionsData, isHarvestLoading, }: SelectPositionFarmModalProps) { - const [selectedPosition, setSelectedPosition] = useState( - null - ); + const [selectedPosition, setSelectedPosition] = useState(); const tokenId = selectedPosition ? BigInt(selectedPosition.id) : 0n; + const { approved, isLoading: isApproving } = useFarmCheckApprove(tokenId); + const { isLoading: isApproveLoading, onApprove } = useFarmApprove(tokenId); const { @@ -49,8 +49,6 @@ export function SelectPositionFarmModal({ nonce: farming.farming.nonce, }); - const { approved, isLoading: isApproving } = useFarmCheckApprove(tokenId); - const handleApprove = async () => { if (approved || !onApprove) return; onApprove(); diff --git a/src/hooks/farming/useFarmStake.ts b/src/hooks/farming/useFarmStake.ts index 9098dc8..ce1db94 100644 --- a/src/hooks/farming/useFarmStake.ts +++ b/src/hooks/farming/useFarmStake.ts @@ -4,6 +4,7 @@ import { Address, useContractWrite, usePrepareContractWrite } from 'wagmi'; import { useTransitionAwait } from '../common/useTransactionAwait'; import { encodeFunctionData } from 'viem'; import { MaxUint128 } from '@cryptoalgebra/integral-sdk'; +import { useFarmCheckApprove } from './useFarmCheckApprove'; export function useFarmStake({ tokenId, @@ -18,8 +19,12 @@ export function useFarmStake({ pool: Address; nonce: bigint; }) { + const { approved } = useFarmCheckApprove(tokenId); + + const address = approved ? FARMING_CENTER : undefined; + const { config } = usePrepareContractWrite({ - address: tokenId ? FARMING_CENTER : undefined, + address, abi: farmingCenterABI, functionName: 'enterFarming', args: [ From 0294da7228590247e5ecda8bd968e0fbcbba17ce Mon Sep 17 00:00:00 2001 From: damnnou Date: Wed, 13 Mar 2024 18:29:22 +0300 Subject: [PATCH 40/47] add: deactivated farmings harvest for position --- .../farming/ClosedFarming/index.tsx | 13 ----- .../position/PositionCard/index.tsx | 51 ++++++++++++++++++- src/hooks/farming/useClosedFarmings.ts | 41 +++++---------- src/pages/Pool/index.tsx | 14 +---- 4 files changed, 63 insertions(+), 56 deletions(-) delete mode 100644 src/components/farming/ClosedFarming/index.tsx diff --git a/src/components/farming/ClosedFarming/index.tsx b/src/components/farming/ClosedFarming/index.tsx deleted file mode 100644 index 12017e1..0000000 --- a/src/components/farming/ClosedFarming/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { EternalFarming } from '@/graphql/generated/graphql'; -import React from 'react'; - -export interface ClosedFarmingProps { - farming: EternalFarming; -} - -const ClosedFarming = React.memo(({ farming }: ClosedFarmingProps) => { - console.log(farming); - return
ClosedFarming
; -}); - -export default ClosedFarming; diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index ea05570..c84412b 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -3,7 +3,11 @@ import { usePosition, usePositionInFarming, } from '@/hooks/positions/usePositions'; -import { INITIAL_POOL_FEE, Position } from '@cryptoalgebra/integral-sdk'; +import { + ADDRESS_ZERO, + INITIAL_POOL_FEE, + Position, +} from '@cryptoalgebra/integral-sdk'; import PositionNFT from '../PositionNFT'; import { FormattedPosition } from '@/types/formatted-position'; import { formatUSD } from '@/utils/common/formatUSD'; @@ -15,17 +19,55 @@ import CollectFees from '../CollectFees'; import RemoveLiquidityModal from '@/components/modals/RemoveLiquidityModal'; import { Farming } from '@/types/farming-info'; import CollectFarmings from '../CollectFarmings'; +import { EternalFarming } from '@/graphql/generated/graphql'; +import { Button } from '@/components/ui/button'; +import { useAccount } from 'wagmi'; +import { useFarmUnstake } from '@/hooks/farming/useFarmStake'; +import Loader from '@/components/common/Loader'; interface PositionCardProps { selectedPosition: FormattedPosition | undefined; farming?: Farming | null; + closedFarmings?: EternalFarming[] | null; } -const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { +const PositionCard = ({ + selectedPosition, + farming, + closedFarmings, +}: PositionCardProps) => { + const { address: account } = useAccount(); + const { loading, position } = usePosition(selectedPosition?.id); const positionInFarming = usePositionInFarming(selectedPosition?.id); + const positionInEndedFarming = closedFarmings?.filter( + (closedFarming) => + closedFarming.id === positionInFarming?.eternalFarming + )[0]; + + const farmingArgs = { + tokenId: positionInEndedFarming + ? BigInt(selectedPosition?.id ?? 0) + : 0n, + rewardToken: positionInEndedFarming + ? positionInEndedFarming.rewardToken + : ADDRESS_ZERO, + bonusRewardToken: positionInEndedFarming + ? positionInEndedFarming.bonusRewardToken + : ADDRESS_ZERO, + pool: positionInEndedFarming + ? positionInEndedFarming.pool + : ADDRESS_ZERO, + nonce: positionInEndedFarming + ? positionInEndedFarming.nonce + : ADDRESS_ZERO, + account: account ?? ADDRESS_ZERO, + }; + + const { onUnstake, isLoading: isUnstaking } = useFarmUnstake(farmingArgs); + const [, pool] = usePool(position?.pool); const positionEntity = pool && @@ -127,6 +169,11 @@ const PositionCard = ({ selectedPosition, farming }: PositionCardProps) => { selectedPosition={positionInFarming} /> )} + {positionInEndedFarming && ( + + )}
); }; diff --git a/src/hooks/farming/useClosedFarmings.ts b/src/hooks/farming/useClosedFarmings.ts index a2ba533..2c945d7 100644 --- a/src/hooks/farming/useClosedFarmings.ts +++ b/src/hooks/farming/useClosedFarmings.ts @@ -1,12 +1,10 @@ import { - SinglePoolQuery, EternalFarming, + SinglePoolQuery, useEternalFarmingsQuery, - useDepositsQuery, } from '@/graphql/generated/graphql'; import { useEffect, useState } from 'react'; import { Address } from 'viem'; -import { useAccount } from 'wagmi'; import { useClients } from '../graphql/useClients'; export function useClosedFarmings({ @@ -16,15 +14,13 @@ export function useClosedFarmings({ poolId: Address; poolInfo: SinglePoolQuery | undefined; }) { - const { address: account } = useAccount(); - const [closedFarmings, setClosedFarmings] = useState< EternalFarming[] | null >(); const { farmingClient } = useClients(); - const { data: farmings, loading: isLoading } = useEternalFarmingsQuery({ + const { data: initialData, loading: isLoading } = useEternalFarmingsQuery({ variables: { pool: poolId, }, @@ -32,33 +28,22 @@ export function useClosedFarmings({ skip: !poolInfo, }); - const filteredFarmings = farmings?.eternalFarmings.filter( - (farming) => farming.isDeactivated - ); - - const { data: deposits } = useDepositsQuery({ - variables: { - owner: account, - pool: poolId, - }, - client: farmingClient, - skip: !poolInfo, - }); - useEffect(() => { - if (!farmings?.eternalFarmings) return; - if (!poolInfo) return; - if (!filteredFarmings) { - console.log('Closed farmings not found'); - setClosedFarmings(null); - return; + if (initialData && initialData.eternalFarmings) { + const filteredFarmings = initialData.eternalFarmings.filter( + (farming) => farming.isDeactivated + ); + setClosedFarmings(filteredFarmings); } - setClosedFarmings(closedFarmings); - }, [deposits, farmings, poolInfo, closedFarmings]); + }, [initialData]); + + useEffect(() => { + if (!closedFarmings) return; + console.log('closedFarmings', closedFarmings); + }, [closedFarmings]); return { closedFarmings, - deposits, isLoading, }; } diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 5a1fc87..91706b6 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -1,6 +1,5 @@ import PageContainer from '@/components/common/PageContainer'; import ActiveFarming from '@/components/farming/ActiveFarming'; -import ClosedFarming from '@/components/farming/ClosedFarming'; import MyPositions from '@/components/pool/MyPositions'; import MyPositionsToolbar from '@/components/pool/MyPositionsToolbar'; import PoolHeader from '@/components/pool/PoolHeader'; @@ -239,18 +238,6 @@ const PoolPage = () => { ) : ( isFarmingLoading && )} - {closedFarmings && ( -
-

- Closed Farmings -

- {closedFarmings.map((farming) => { - return ( - - ); - })} -
- )} )}
@@ -258,6 +245,7 @@ const PoolPage = () => {
From 28d27ba22347e7bfbe2b1e63c8caf84d8edaa99c Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 14 Mar 2024 00:19:58 +0300 Subject: [PATCH 41/47] fix: add skeleton loading --- src/components/farming/ActiveFarming/index.tsx | 3 ++- src/hooks/farming/useActiveFarming.ts | 2 +- src/hooks/farming/useFarmStake.ts | 2 +- src/pages/Pool/index.tsx | 6 ++---- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index a9b2640..141e6f5 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -13,6 +13,7 @@ import { useCurrency } from '@/hooks/common/useCurrency'; import { useAccount } from 'wagmi'; import { useFarmHarvestAll } from '@/hooks/farming/useFarmHarvest'; import Loader from '@/components/common/Loader'; +import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; interface ActiveFarmingProps { farming: Farming; @@ -106,7 +107,7 @@ const ActiveFarming = ({ bonusRewardToken: farming.farming.bonusRewardToken, pool: farming.farming.pool, nonce: farming.farming.nonce, - account: account!, + account: account ?? ADDRESS_ZERO, }, deposits ); diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index b264c73..49a473e 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -90,6 +90,6 @@ export function useActiveFarming({ return { farmingInfo, deposits, - isLoading, + isLoading: isLoading || deposits === undefined, }; } diff --git a/src/hooks/farming/useFarmStake.ts b/src/hooks/farming/useFarmStake.ts index ce1db94..baeec84 100644 --- a/src/hooks/farming/useFarmStake.ts +++ b/src/hooks/farming/useFarmStake.ts @@ -21,7 +21,7 @@ export function useFarmStake({ }) { const { approved } = useFarmCheckApprove(tokenId); - const address = approved ? FARMING_CENTER : undefined; + const address = tokenId && approved ? FARMING_CENTER : undefined; const { config } = usePrepareContractWrite({ address, diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 91706b6..b855205 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -204,7 +204,7 @@ const PoolPage = () => {
{!account ? ( - ) : positionsLoading ? ( + ) : positionsLoading || isFarmingLoading ? ( ) : noPositions ? ( @@ -224,7 +224,7 @@ const PoolPage = () => { ) } /> - {farmingInfo && deposits && !isFarmingLoading ? ( + {farmingInfo && deposits && !isFarmingLoading && (

Farmings @@ -235,8 +235,6 @@ const PoolPage = () => { positionsData={positionsData} />

- ) : ( - isFarmingLoading && )} )} From e51f7149a4e5ab76acd1a047398fde50b96a664a Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 14 Mar 2024 11:23:18 +0300 Subject: [PATCH 42/47] fix: refactor code, style fixes --- src/components/common/CardInfo/index.tsx | 2 +- .../farming/ActiveFarming/index.tsx | 168 ++++++++------- .../position/CollectFarmings/index.tsx | 18 +- src/hooks/farming/useActiveFarming.ts | 20 +- src/hooks/farming/useClosedFarmings.ts | 4 +- src/hooks/positions/usePositions.ts | 4 +- src/pages/Pool/index.tsx | 52 ++--- src/utils/farming/isSameRewards.ts | 6 +- tailwind.config.js | 191 +++++++++--------- 9 files changed, 256 insertions(+), 209 deletions(-) diff --git a/src/components/common/CardInfo/index.tsx b/src/components/common/CardInfo/index.tsx index b69fae2..66788af 100644 --- a/src/components/common/CardInfo/index.tsx +++ b/src/components/common/CardInfo/index.tsx @@ -26,7 +26,7 @@ const CardInfo: FC = ({
{children}
- {additional &&

{additional}

} + {additional &&

{additional}

}
); diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 141e6f5..341b088 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; import { isSameRewards } from '@/utils/farming/isSameRewards'; -import { Deposit } from '@/graphql/generated/graphql'; +import { Deposit, useNativePriceQuery } from '@/graphql/generated/graphql'; import { Farming } from '@/types/farming-info'; import { Button } from '@/components/ui/button'; import CardInfo from '@/components/common/CardInfo'; @@ -31,6 +31,9 @@ const ActiveFarming = ({ const [rewardEarned, setRewardEarned] = useState(0n); const [bonusRewardEarned, setBonusRewardEarned] = useState(0n); + const { data: nativePrice, loading: nativePriceLoading } = + useNativePriceQuery(); + const isSameReward = isSameRewards( farming.farming.rewardToken, farming.farming.bonusRewardToken @@ -44,6 +47,16 @@ const ActiveFarming = ({ formatUnits(bonusRewardEarned, farming.bonusRewardToken?.decimals) ); + const rewardEarnedUSD = + formattedRewardEarned * + farming.rewardToken.derivedMatic * + nativePrice?.bundles[0].maticPriceUSD; + + const bonusRewardEarnedUSD = + formattedBonusRewardEarned * + farming.bonusRewardToken?.derivedMatic * + nativePrice?.bundles[0].maticPriceUSD; + const rewardTokenCurrency = useCurrency(farming.farming.rewardToken); const bonusRewardTokenCurrency = useCurrency( farming.farming.bonusRewardToken @@ -62,44 +75,27 @@ const ActiveFarming = ({ const formattedTVL = TVL.toFixed(2); - const rewardRatePerDay = isSameReward - ? ( - Number( - formatUnits( - farming.farming.rewardRate, - farming.rewardToken.decimals - ) - ) * - 60 * - 60 * - 24 * - 2 - ).toFixed(2) - : ( - Number( - formatUnits( - farming.farming.rewardRate, - farming.rewardToken.decimals - ) - ) * - 60 * - 60 * - 24 - ).toFixed(2); - - const bonusRewardRatePerDay = isSameReward - ? 0 - : ( - Number( - formatUnits( - farming.farming.bonusRewardRate, - farming.bonusRewardToken?.decimals - ) - ) * - 60 * - 60 * - 24 - ).toFixed(2); + const rewardRatePerDay = + Number( + formatUnits( + farming.farming.rewardRate, + farming.rewardToken.decimals + ) + ) * + 60 * + 60 * + 24; + + const bonusRewardRatePerDay = + Number( + formatUnits( + farming.farming.bonusRewardRate, + farming.bonusRewardToken?.decimals + ) + ) * + 60 * + 60 * + 24; const { isLoading, onHarvestAll, isSuccess } = useFarmHarvestAll( { @@ -148,13 +144,13 @@ const ActiveFarming = ({ return (
-
-
-
- +
+
+
+

45%

- +

${formattedTVL}

@@ -169,45 +165,73 @@ const ActiveFarming = ({ )} ${farming.bonusRewardToken?.symbol}` : '' } - className="w-1/2" + className="w-full" title="EARNED" >

$ - {( - formattedRewardEarned + - formattedBonusRewardEarned - ).toFixed(4)} + {!nativePriceLoading && + ( + rewardEarnedUSD + bonusRewardEarnedUSD + ).toFixed(4)}

-
+
- -

- {rewardRatePerDay + - ' ' + - farming.rewardToken.symbol}{' '} - / day -

+ {isSameReward ? ( + <> + +

+ {`${( + rewardRatePerDay + + bonusRewardRatePerDay + ).toFixed(2)} ${ + farming.rewardToken.symbol + } / day`} +

+ + ) : ( +
+
+ +

+ {`${rewardRatePerDay.toFixed(2)} ${ + farming.rewardToken.symbol + } / day`} +

+
+ {bonusRewardRatePerDay > 0 && ( +
+ +

+ {`${bonusRewardRatePerDay.toFixed( + 2 + )} ${ + farming.bonusRewardToken + ?.symbol + } / day`} +

+
+ )} +
+ )}
- {bonusRewardRatePerDay !== 0 && ( -
- -

- {bonusRewardRatePerDay}{' '} - {farming.bonusRewardToken?.symbol} / day -

-
- )}
diff --git a/src/components/position/CollectFarmings/index.tsx b/src/components/position/CollectFarmings/index.tsx index 1b38c31..0168f8b 100644 --- a/src/components/position/CollectFarmings/index.tsx +++ b/src/components/position/CollectFarmings/index.tsx @@ -8,7 +8,7 @@ import { useAccount } from 'wagmi'; import { getFarmingRewards } from '@/utils/farming/getFarmingRewards'; import { Button } from '@/components/ui/button'; import Loader from '@/components/common/Loader'; -import { Deposit } from '@/graphql/generated/graphql'; +import { Deposit, useNativePriceQuery } from '@/graphql/generated/graphql'; interface CollectFarmingsProps { farming: Farming; @@ -24,6 +24,8 @@ const CollectFarmings = ({ const [rewardEarned, setRewardEarned] = useState(0n); const [bonusRewardEarned, setBonusRewardEarned] = useState(0n); + const { data: nativePrice } = useNativePriceQuery(); + const formattedRewardEarned = Number( formatUnits(rewardEarned, farming.rewardToken.decimals) ); @@ -32,9 +34,17 @@ const CollectFarmings = ({ formatUnits(bonusRewardEarned, farming.bonusRewardToken?.decimals) ); - const farmingRewards = ( - formattedRewardEarned + formattedBonusRewardEarned - ).toFixed(4); + const rewardEarnedUSD = + formattedRewardEarned * + farming.rewardToken.derivedMatic * + nativePrice?.bundles[0].maticPriceUSD; + + const bonusRewardEarnedUSD = + formattedBonusRewardEarned * + farming.bonusRewardToken?.derivedMatic * + nativePrice?.bundles[0].maticPriceUSD; + + const farmingRewards = (rewardEarnedUSD + bonusRewardEarnedUSD).toFixed(4); const farmingArgs = { tokenId: BigInt(selectedPosition.id), diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index 49a473e..a8b560a 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -22,13 +22,14 @@ export function useActiveFarming({ const { farmingClient } = useClients(); - const { data: farmings, loading: isLoading } = useEternalFarmingsQuery({ - variables: { - pool: poolId, - }, - client: farmingClient, - skip: !poolInfo, - }); + const { data: farmings, loading: isFarmingLoading } = + useEternalFarmingsQuery({ + variables: { + pool: poolId, + }, + client: farmingClient, + skip: !poolInfo, + }); const activeFarming = farmings?.eternalFarmings.filter( (farming) => !farming.isDeactivated @@ -48,7 +49,7 @@ export function useActiveFarming({ }, }); - const { data: deposits } = useDepositsQuery({ + const { data: deposits, loading: areDepositsLoading } = useDepositsQuery({ variables: { owner: account, pool: poolId, @@ -90,6 +91,7 @@ export function useActiveFarming({ return { farmingInfo, deposits, - isLoading: isLoading || deposits === undefined, + isFarmingLoading, + areDepositsLoading, }; } diff --git a/src/hooks/farming/useClosedFarmings.ts b/src/hooks/farming/useClosedFarmings.ts index 2c945d7..b426b6e 100644 --- a/src/hooks/farming/useClosedFarmings.ts +++ b/src/hooks/farming/useClosedFarmings.ts @@ -3,7 +3,7 @@ import { SinglePoolQuery, useEternalFarmingsQuery, } from '@/graphql/generated/graphql'; -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { Address } from 'viem'; import { useClients } from '../graphql/useClients'; @@ -28,7 +28,7 @@ export function useClosedFarmings({ skip: !poolInfo, }); - useEffect(() => { + useMemo(() => { if (initialData && initialData.eternalFarmings) { const filteredFarmings = initialData.eternalFarmings.filter( (farming) => farming.isDeactivated diff --git a/src/hooks/positions/usePositions.ts b/src/hooks/positions/usePositions.ts index e3bf9b1..24d5fb8 100644 --- a/src/hooks/positions/usePositions.ts +++ b/src/hooks/positions/usePositions.ts @@ -183,6 +183,6 @@ export function usePositionInFarming(tokenId: string | number | undefined) { (deposit) => Number(deposit.id) === Number(tokenId) ); - if (!positionInFarming) return null; - else return positionInFarming; + if (!positionInFarming) return; + return positionInFarming; } diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index b855205..7b2c1b9 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -48,14 +48,11 @@ const PoolPage = () => { const { data: bundles } = useNativePriceQuery(); - const { - farmingInfo, - deposits, - isLoading: isFarmingLoading, - } = useActiveFarming({ - poolId: poolId, - poolInfo: poolInfo, - }); + const { farmingInfo, deposits, isFarmingLoading, areDepositsLoading } = + useActiveFarming({ + poolId: poolId, + poolInfo: poolInfo, + }); const { closedFarmings } = useClosedFarmings({ poolId: poolId, @@ -173,7 +170,7 @@ const PoolPage = () => { liquidityUSD: formatLiquidityUSD(position), feesUSD: formatFeesUSD(idx), apr: formatAPR(idx), - inFarming: currentPosition?.eternalFarming ? true : false, + inFarming: Boolean(currentPosition?.eternalFarming), } as FormattedPosition; }); }, [ @@ -194,7 +191,9 @@ const PoolPage = () => { }, [selectedPositionId, positionsData]); const noPositions = - !positionsLoading && positionsData.length === 0 && poolEntity; + (!positionsLoading || !isFarmingLoading || !areDepositsLoading) && + positionsData.length === 0 && + poolEntity; return ( @@ -204,7 +203,9 @@ const PoolPage = () => {
{!account ? ( - ) : positionsLoading || isFarmingLoading ? ( + ) : positionsLoading || + isFarmingLoading || + areDepositsLoading ? ( ) : noPositions ? ( @@ -224,18 +225,23 @@ const PoolPage = () => { ) } /> - {farmingInfo && deposits && !isFarmingLoading && ( -
-

- Farmings -

- -
- )} + {farmingInfo && + deposits && + !isFarmingLoading && + !areDepositsLoading && ( +
+

+ Farmings +

+ +
+ )} )}
diff --git a/src/utils/farming/isSameRewards.ts b/src/utils/farming/isSameRewards.ts index 663fb30..010026b 100644 --- a/src/utils/farming/isSameRewards.ts +++ b/src/utils/farming/isSameRewards.ts @@ -1,12 +1,8 @@ -import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; import { Address } from 'viem'; export const isSameRewards = ( rewardToken: Address, bonusRewardToken: Address ): boolean => { - return ( - rewardToken.toLowerCase() === bonusRewardToken.toLowerCase() || - bonusRewardToken === ADDRESS_ZERO - ); + return rewardToken.toLowerCase() === bonusRewardToken.toLowerCase(); }; diff --git a/tailwind.config.js b/tailwind.config.js index 3b06674..c7131d5 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,97 +1,106 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - darkMode: ["class"], - content: [ - './pages/**/*.{ts,tsx}', - './components/**/*.{ts,tsx}', - './app/**/*.{ts,tsx}', - './src/**/*.{ts,tsx}', - ], - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - colors: { - border: "#5F5F82", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - button: "#2797ff", - text: "#56adff" - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - primary: "#0a2b49" - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", + darkMode: ['class'], + content: [ + './pages/**/*.{ts,tsx}', + './components/**/*.{ts,tsx}', + './app/**/*.{ts,tsx}', + './src/**/*.{ts,tsx}', + ], + theme: { + screens: { + xs: '380px', + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + '2xl': '1400px', }, - card: { - DEFAULT: "#1A1D2B", - foreground: "hsl(var(--card-foreground))", - hover: "#2e3242", - dark: "#101321", - light: "#31333e" - } - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: 0 }, - to: { height: "var(--radix-accordion-content-height)" }, + container: { + center: true, + padding: '2rem', + screens: { + '2xl': '1400px', + }, }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: 0 }, + extend: { + colors: { + border: '#5F5F82', + input: 'hsl(var(--input))', + ring: 'hsl(var(--ring))', + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', + primary: { + DEFAULT: 'hsl(var(--primary))', + foreground: 'hsl(var(--primary-foreground))', + button: '#2797ff', + text: '#56adff', + }, + secondary: { + DEFAULT: 'hsl(var(--secondary))', + foreground: 'hsl(var(--secondary-foreground))', + }, + destructive: { + DEFAULT: 'hsl(var(--destructive))', + foreground: 'hsl(var(--destructive-foreground))', + }, + muted: { + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground))', + primary: '#0a2b49', + }, + accent: { + DEFAULT: 'hsl(var(--accent))', + foreground: 'hsl(var(--accent-foreground))', + }, + popover: { + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))', + }, + card: { + DEFAULT: '#1A1D2B', + foreground: 'hsl(var(--card-foreground))', + hover: '#2e3242', + dark: '#101321', + light: '#31333e', + }, + }, + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)', + }, + keyframes: { + 'accordion-down': { + from: { height: 0 }, + to: { height: 'var(--radix-accordion-content-height)' }, + }, + 'accordion-up': { + from: { height: 'var(--radix-accordion-content-height)' }, + to: { height: 0 }, + }, + 'fade-in': { + '0%': { opacity: 0, transform: 'translateY(10px)' }, + '100%': { opacity: 1, transform: 'translateY(0)' }, + }, + }, + animation: { + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out', + 'fade-in': 'fade-in 0.2s ease-out', + }, + backgroundImage: { + 'card-gradient': + 'linear-gradient(224deg, #1A1D2B 1.67%, #090B15 97.94%)', + }, + borderColor: { + 'card-border': '#5F5F82', + }, + dropShadow: { + cyan: '0 0 5px rgba(7, 142, 253, 0.8)', + pink: '0 0 5px rgba(255, 120, 217, 0.7)', + }, }, - "fade-in": { - '0%': { opacity: 0, transform: 'translateY(10px)' }, - '100%': { opacity: 1, transform: 'translateY(0)' } - } - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - "fade-in": "fade-in 0.2s ease-out" - }, - backgroundImage: { - "card-gradient": "linear-gradient(224deg, #1A1D2B 1.67%, #090B15 97.94%)" - }, - borderColor: { - "card-border": "#5F5F82" - }, - dropShadow: { - "cyan": "0 0 5px rgba(7, 142, 253, 0.8)", - "pink": "0 0 5px rgba(255, 120, 217, 0.7)" - } }, - }, - plugins: [require("tailwindcss-animate")], -} \ No newline at end of file + plugins: [require('tailwindcss-animate')], +}; From bfde60d0ceb5709a71e640697217fd64619f25ca Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 14 Mar 2024 12:07:03 +0300 Subject: [PATCH 43/47] add: useRewardEarnedUSD hook --- .../farming/ActiveFarming/index.tsx | 33 +++++++++---------- .../position/CollectFarmings/index.tsx | 30 ++++++----------- src/hooks/farming/useRewardEarnedUSD.ts | 29 ++++++++++++++++ 3 files changed, 54 insertions(+), 38 deletions(-) create mode 100644 src/hooks/farming/useRewardEarnedUSD.ts diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 341b088..5e7e7bb 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { SelectPositionFarmModal } from '@/components/modals/SelectPositionFarmModal'; import { isSameRewards } from '@/utils/farming/isSameRewards'; -import { Deposit, useNativePriceQuery } from '@/graphql/generated/graphql'; +import { Deposit } from '@/graphql/generated/graphql'; import { Farming } from '@/types/farming-info'; import { Button } from '@/components/ui/button'; import CardInfo from '@/components/common/CardInfo'; @@ -14,6 +14,7 @@ import { useAccount } from 'wagmi'; import { useFarmHarvestAll } from '@/hooks/farming/useFarmHarvest'; import Loader from '@/components/common/Loader'; import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; +import { useRewardEarnedUSD } from '@/hooks/farming/useRewardEarnedUSD'; interface ActiveFarmingProps { farming: Farming; @@ -31,9 +32,6 @@ const ActiveFarming = ({ const [rewardEarned, setRewardEarned] = useState(0n); const [bonusRewardEarned, setBonusRewardEarned] = useState(0n); - const { data: nativePrice, loading: nativePriceLoading } = - useNativePriceQuery(); - const isSameReward = isSameRewards( farming.farming.rewardToken, farming.farming.bonusRewardToken @@ -47,15 +45,15 @@ const ActiveFarming = ({ formatUnits(bonusRewardEarned, farming.bonusRewardToken?.decimals) ); - const rewardEarnedUSD = - formattedRewardEarned * - farming.rewardToken.derivedMatic * - nativePrice?.bundles[0].maticPriceUSD; + const rewardEarnedUSD = useRewardEarnedUSD({ + token: farming.rewardToken, + reward: rewardEarned, + }); - const bonusRewardEarnedUSD = - formattedBonusRewardEarned * - farming.bonusRewardToken?.derivedMatic * - nativePrice?.bundles[0].maticPriceUSD; + const bonusRewardEarnedUSD = useRewardEarnedUSD({ + token: farming.rewardToken, + reward: bonusRewardEarned, + }); const rewardTokenCurrency = useCurrency(farming.farming.rewardToken); const bonusRewardTokenCurrency = useCurrency( @@ -170,10 +168,9 @@ const ActiveFarming = ({ >

$ - {!nativePriceLoading && - ( - rewardEarnedUSD + bonusRewardEarnedUSD - ).toFixed(4)} + {(rewardEarnedUSD + bonusRewardEarnedUSD).toFixed( + 4 + )}

@@ -238,8 +235,8 @@ const ActiveFarming = ({
- + Select Position -
    +
      {availablePositions.length > 0 ? ( availablePositions.map((position) => { const currentFormattedPosition = positionsData.find( diff --git a/src/components/position/CollectFarmings/index.tsx b/src/components/position/ActiveFarmingCard/index.tsx similarity index 96% rename from src/components/position/CollectFarmings/index.tsx rename to src/components/position/ActiveFarmingCard/index.tsx index df733de..7ad46bc 100644 --- a/src/components/position/CollectFarmings/index.tsx +++ b/src/components/position/ActiveFarmingCard/index.tsx @@ -10,15 +10,15 @@ import Loader from '@/components/common/Loader'; import { Deposit } from '@/graphql/generated/graphql'; import { useRewardEarnedUSD } from '@/hooks/farming/useRewardEarnedUSD'; -interface CollectFarmingsProps { +interface ActiveFarmingCardProps { farming: Farming; selectedPosition: Deposit; } -const CollectFarmings = ({ +const ActiveFarmingCard = ({ farming, selectedPosition, -}: CollectFarmingsProps) => { +}: ActiveFarmingCardProps) => { const { address: account } = useAccount(); const [rewardEarned, setRewardEarned] = useState(0n); @@ -102,4 +102,4 @@ const CollectFarmings = ({ ); }; -export default CollectFarmings; +export default ActiveFarmingCard; diff --git a/src/components/position/ClosedFarmingCard/index.tsx b/src/components/position/ClosedFarmingCard/index.tsx new file mode 100644 index 0000000..0db6380 --- /dev/null +++ b/src/components/position/ClosedFarmingCard/index.tsx @@ -0,0 +1,38 @@ +import Loader from '@/components/common/Loader'; +import { Button } from '@/components/ui/button'; +import { EternalFarming } from '@/graphql/generated/graphql'; +import { useFarmUnstake } from '@/hooks/farming/useFarmStake'; +import { FormattedPosition } from '@/types/formatted-position'; +import { ADDRESS_ZERO } from '@cryptoalgebra/integral-sdk'; +import { useAccount } from 'wagmi'; + +interface ClosedFarmingCardProps { + positionInEndedFarming: EternalFarming; + selectedPosition: FormattedPosition; +} + +const ClosedFarmingCard = ({ + positionInEndedFarming, + selectedPosition, +}: ClosedFarmingCardProps) => { + const { address: account } = useAccount(); + + const farmingArgs = { + tokenId: BigInt(selectedPosition.id ?? 0), + rewardToken: positionInEndedFarming.rewardToken, + bonusRewardToken: positionInEndedFarming.bonusRewardToken, + pool: positionInEndedFarming.pool, + nonce: positionInEndedFarming.nonce, + account: account ?? ADDRESS_ZERO, + }; + + const { onUnstake, isLoading: isUnstaking } = useFarmUnstake(farmingArgs); + + return ( + + ); +}; + +export default ClosedFarmingCard; diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index c84412b..82c302f 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -3,11 +3,7 @@ import { usePosition, usePositionInFarming, } from '@/hooks/positions/usePositions'; -import { - ADDRESS_ZERO, - INITIAL_POOL_FEE, - Position, -} from '@cryptoalgebra/integral-sdk'; +import { INITIAL_POOL_FEE, Position } from '@cryptoalgebra/integral-sdk'; import PositionNFT from '../PositionNFT'; import { FormattedPosition } from '@/types/formatted-position'; import { formatUSD } from '@/utils/common/formatUSD'; @@ -18,12 +14,9 @@ import { useDerivedMintInfo } from '@/state/mintStore'; import CollectFees from '../CollectFees'; import RemoveLiquidityModal from '@/components/modals/RemoveLiquidityModal'; import { Farming } from '@/types/farming-info'; -import CollectFarmings from '../CollectFarmings'; import { EternalFarming } from '@/graphql/generated/graphql'; -import { Button } from '@/components/ui/button'; -import { useAccount } from 'wagmi'; -import { useFarmUnstake } from '@/hooks/farming/useFarmStake'; -import Loader from '@/components/common/Loader'; +import ActiveFarmingCard from '../ActiveFarmingCard'; +import ClosedFarmingCard from '../ClosedFarmingCard'; interface PositionCardProps { selectedPosition: FormattedPosition | undefined; @@ -36,8 +29,6 @@ const PositionCard = ({ farming, closedFarmings, }: PositionCardProps) => { - const { address: account } = useAccount(); - const { loading, position } = usePosition(selectedPosition?.id); const positionInFarming = usePositionInFarming(selectedPosition?.id); @@ -47,27 +38,6 @@ const PositionCard = ({ closedFarming.id === positionInFarming?.eternalFarming )[0]; - const farmingArgs = { - tokenId: positionInEndedFarming - ? BigInt(selectedPosition?.id ?? 0) - : 0n, - rewardToken: positionInEndedFarming - ? positionInEndedFarming.rewardToken - : ADDRESS_ZERO, - bonusRewardToken: positionInEndedFarming - ? positionInEndedFarming.bonusRewardToken - : ADDRESS_ZERO, - pool: positionInEndedFarming - ? positionInEndedFarming.pool - : ADDRESS_ZERO, - nonce: positionInEndedFarming - ? positionInEndedFarming.nonce - : ADDRESS_ZERO, - account: account ?? ADDRESS_ZERO, - }; - - const { onUnstake, isLoading: isUnstaking } = useFarmUnstake(farmingArgs); - const [, pool] = usePool(position?.pool); const positionEntity = pool && @@ -163,16 +133,17 @@ const PositionCard = ({
      - {farming && selectedPosition && positionInFarming && ( - )} {positionInEndedFarming && ( - + )}
); From b2e4c7f97583ed264a6febfba08a2c1235daa573 Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 14 Mar 2024 13:06:52 +0300 Subject: [PATCH 45/47] fix: chore fix --- src/components/farming/ActiveFarming/index.tsx | 2 +- src/components/position/ActiveFarmingCard/index.tsx | 2 +- src/hooks/farming/useRewardEarnedUSD.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index 5e7e7bb..f770d60 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -51,7 +51,7 @@ const ActiveFarming = ({ }); const bonusRewardEarnedUSD = useRewardEarnedUSD({ - token: farming.rewardToken, + token: farming.bonusRewardToken, reward: bonusRewardEarned, }); diff --git a/src/components/position/ActiveFarmingCard/index.tsx b/src/components/position/ActiveFarmingCard/index.tsx index 7ad46bc..ddf725a 100644 --- a/src/components/position/ActiveFarmingCard/index.tsx +++ b/src/components/position/ActiveFarmingCard/index.tsx @@ -30,7 +30,7 @@ const ActiveFarmingCard = ({ }); const bonusRewardEarnedUSD = useRewardEarnedUSD({ - token: farming.rewardToken, + token: farming.bonusRewardToken, reward: bonusRewardEarned, }); diff --git a/src/hooks/farming/useRewardEarnedUSD.ts b/src/hooks/farming/useRewardEarnedUSD.ts index db1de60..57efadc 100644 --- a/src/hooks/farming/useRewardEarnedUSD.ts +++ b/src/hooks/farming/useRewardEarnedUSD.ts @@ -9,18 +9,18 @@ export function useRewardEarnedUSD({ token, reward, }: { - token: TokenFieldsFragment; + token: TokenFieldsFragment | null; reward: bigint; }): number { const { data: nativePrice } = useNativePriceQuery(); return useMemo(() => { const formattedRewardEarned = Number( - formatUnits(reward, token.decimals) + formatUnits(reward, token?.decimals) ); const rewardUSD = - token.derivedMatic * + token?.derivedMatic * formattedRewardEarned * nativePrice?.bundles[0].maticPriceUSD; From 120fac54ae5dada26f985d4ea98ae0149e0e2bd9 Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 14 Mar 2024 13:36:53 +0300 Subject: [PATCH 46/47] fix: fees calculations, styles fix --- .../farming/ActiveFarming/index.tsx | 39 ++++++++++++++----- src/hooks/farming/useActiveFarming.ts | 12 +----- src/hooks/farming/useClosedFarmings.ts | 7 +--- src/pages/Pool/index.tsx | 13 ++++--- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/components/farming/ActiveFarming/index.tsx b/src/components/farming/ActiveFarming/index.tsx index f770d60..8ed41fb 100644 --- a/src/components/farming/ActiveFarming/index.tsx +++ b/src/components/farming/ActiveFarming/index.tsx @@ -156,11 +156,19 @@ const ActiveFarming = ({

- {`${rewardRatePerDay.toFixed(2)} ${ + {`${ + rewardRatePerDay.toFixed(2) === + '0.00' + ? '<0.01' + : rewardRatePerDay.toFixed( + 2 + ) + } ${ farming.rewardToken.symbol } / day`}

@@ -217,9 +232,15 @@ const ActiveFarming = ({ } />

- {`${bonusRewardRatePerDay.toFixed( - 2 - )} ${ + {`${ + bonusRewardRatePerDay.toFixed( + 2 + ) === '0.00' + ? '<0.01' + : bonusRewardRatePerDay.toFixed( + 2 + ) + } ${ farming.bonusRewardToken ?.symbol } / day`} diff --git a/src/hooks/farming/useActiveFarming.ts b/src/hooks/farming/useActiveFarming.ts index a8b560a..798a0d9 100644 --- a/src/hooks/farming/useActiveFarming.ts +++ b/src/hooks/farming/useActiveFarming.ts @@ -65,7 +65,7 @@ export function useActiveFarming({ if (!rewardToken) return; if (!bonusRewardToken) return; if (!activeFarming || !rewardToken.token) { - console.log('Active farming not found'); + console.debug('Active farming not found'); setFarmingInfo(null); return; } @@ -78,16 +78,6 @@ export function useActiveFarming({ }); }, [farmings, rewardToken, bonusRewardToken, poolInfo, activeFarming]); - useEffect(() => { - if (!farmingInfo) return; - console.log('Active Farming - ', farmingInfo); - }, [farmingInfo]); - - useEffect(() => { - if (!deposits) return; - console.log('Positions - ', deposits.deposits); - }, [deposits]); - return { farmingInfo, deposits, diff --git a/src/hooks/farming/useClosedFarmings.ts b/src/hooks/farming/useClosedFarmings.ts index b426b6e..69e55b3 100644 --- a/src/hooks/farming/useClosedFarmings.ts +++ b/src/hooks/farming/useClosedFarmings.ts @@ -3,7 +3,7 @@ import { SinglePoolQuery, useEternalFarmingsQuery, } from '@/graphql/generated/graphql'; -import { useEffect, useMemo, useState } from 'react'; +import { useMemo, useState } from 'react'; import { Address } from 'viem'; import { useClients } from '../graphql/useClients'; @@ -37,11 +37,6 @@ export function useClosedFarmings({ } }, [initialData]); - useEffect(() => { - if (!closedFarmings) return; - console.log('closedFarmings', closedFarmings); - }, [closedFarmings]); - return { closedFarmings, isLoading, diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 7b2c1b9..925e529 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -47,6 +47,7 @@ const PoolPage = () => { }); const { data: bundles } = useNativePriceQuery(); + const nativePrice = bundles?.bundles[0].maticPriceUSD; const { farmingInfo, deposits, isFarmingLoading, areDepositsLoading } = useActiveFarming({ @@ -95,7 +96,6 @@ const PoolPage = () => { useEffect(() => { async function getPositionsAPRs() { - const nativePrice = bundles?.bundles[0].maticPriceUSD; const aprs = await Promise.all( filteredPositions.map(({ position }) => getPositionAPR( @@ -120,16 +120,17 @@ const PoolPage = () => { getPositionsAPRs(); }, [filteredPositions, poolInfo, poolId, poolFeeData, bundles]); - // should be reusable const formatLiquidityUSD = (position: Position) => { if (!poolInfo?.pool) return 0; const amount0USD = Number(position.amount0.toSignificant()) * - Number(poolInfo.pool.token1Price); + (Number(poolInfo.pool.token0.derivedMatic) * + (Number(nativePrice) || 0)); const amount1USD = Number(position.amount1.toSignificant()) * - Number(poolInfo.pool.token0Price); + (Number(poolInfo.pool.token1.derivedMatic) * + (Number(nativePrice) || 0)); return amount0USD + amount1USD; }; @@ -139,11 +140,11 @@ const PoolPage = () => { const fees0USD = positionsFees[idx][0] ? Number(positionsFees[idx][0].toSignificant()) * - Number(poolInfo.pool.token0Price) + (Number(poolInfo.pool.token0.derivedMatic) * Number(nativePrice)) : 0; const fees1USD = positionsFees[idx][1] ? Number(positionsFees[idx][1].toSignificant()) * - Number(poolInfo.pool.token1Price) + (Number(poolInfo.pool.token1.derivedMatic) * Number(nativePrice)) : 0; return fees0USD + fees1USD; From 1267bff7d49f1f206a973add7cea30d6b0983b6b Mon Sep 17 00:00:00 2001 From: damnnou Date: Thu, 14 Mar 2024 14:08:25 +0300 Subject: [PATCH 47/47] chore: small fix --- src/components/position/PositionCard/index.tsx | 2 +- src/pages/Pool/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/position/PositionCard/index.tsx b/src/components/position/PositionCard/index.tsx index 82c302f..78b9787 100644 --- a/src/components/position/PositionCard/index.tsx +++ b/src/components/position/PositionCard/index.tsx @@ -133,7 +133,7 @@ const PositionCard = ({

- {positionInFarming && farming && ( + {positionInFarming && farming && !positionInEndedFarming && ( { !areDepositsLoading && (

- Farmings + Farming