diff --git a/packages/frontend/src/abis/bullNetting.json b/packages/frontend/src/abis/bullNetting.json new file mode 100644 index 000000000..c406d98ed --- /dev/null +++ b/packages/frontend/src/abis/bullNetting.json @@ -0,0 +1,1536 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_zenBull", + "type": "address" + }, + { + "internalType": "address", + "name": "_eulerSimpleLens", + "type": "address" + }, + { + "internalType": "address", + "name": "_flashZenBull", + "type": "address" + }, + { + "internalType": "address", + "name": "_uniFactory", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "name": "CancelNonce", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "wethDeposited", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "crabAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clearingPrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oSqthAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "depositsIndex", + "type": "uint256" + } + ], + "name": "DepositAuction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "depositor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "depositorsBalance", + "type": "uint256" + } + ], + "name": "DequeueEth", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawersBalance", + "type": "uint256" + } + ], + "name": "DequeueZenBull", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "depositor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "zenBullAmount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "receiptIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "refundedETH", + "type": "uint256" + } + ], + "name": "EthDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bool", + "name": "isDeposit", + "type": "bool" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountQueuedProcessed", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountReceived", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "NetAtPrice", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "depositor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "depositorsBalance", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "receiptIndex", + "type": "uint256" + } + ], + "name": "QueueEth", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawersBalance", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "receiptIndex", + "type": "uint256" + } + ], + "name": "QueueZenBull", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "previousTwap", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newTwap", + "type": "uint32" + } + ], + "name": "SetAuctionTwapPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "bot", + "type": "address" + } + ], + "name": "SetBot", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldDepositsIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDepositsIndex", + "type": "uint256" + } + ], + "name": "SetDepositsIndex", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAmount", + "type": "uint256" + } + ], + "name": "SetMinEthAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAmount", + "type": "uint256" + } + ], + "name": "SetMinZenBullAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "previousTolerance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newOtcPriceTolerance", + "type": "uint256" + } + ], + "name": "SetOTCPriceTolerance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldWithdrawsIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWithdrawsIndex", + "type": "uint256" + } + ], + "name": "SetWithdrawsIndex", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isAuctionLive", + "type": "bool" + } + ], + "name": "ToggledAuctionLive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "quantity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oSqthRemaining", + "type": "uint256" + } + ], + "name": "TransferOsqthFromMarketMakers", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "quantity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingOsqthBalance", + "type": "uint256" + } + ], + "name": "TransferOsqthToMarketMakers", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "quantity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clearingPrice", + "type": "uint256" + } + ], + "name": "TransferWethFromMarketMakers", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "quantity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oSqthRemaining", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clearingPrice", + "type": "uint256" + } + ], + "name": "TransferWethToMarketMaker", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "zenBullWithdrawn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clearingPrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oSqthAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawsIndex", + "type": "uint256" + } + ], + "name": "WithdrawAuction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "zenBullAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethAmount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "receiptIndex", + "type": "uint256" + } + ], + "name": "ZenBullWithdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_OTC_PRICE_TOLERANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_AUCTION_TWAP", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionTwapPeriod", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bot", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "cancelNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "bidId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "internalType": "uint256", + "name": "quantity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isBuying", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct ZenBullNetting.Order", + "name": "_order", + "type": "tuple" + } + ], + "name": "checkOrder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "depositsToProcess", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "crabAmount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "bidId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "internalType": "uint256", + "name": "quantity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isBuying", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct ZenBullNetting.Order[]", + "name": "orders", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "clearingPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "flashDepositEthToCrab", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "flashDepositMinEthFromSqth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "flashDepositMinEthFromUsdc", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "flashDepositWPowerPerpPoolFee", + "type": "uint24" + }, + { + "internalType": "uint24", + "name": "wethUsdcPoolFee", + "type": "uint24" + } + ], + "internalType": "struct ZenBullNetting.DepositAuctionParams", + "name": "_params", + "type": "tuple" + } + ], + "name": "depositAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "deposits", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositsIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositsQueued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_force", + "type": "bool" + } + ], + "name": "dequeueEth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_force", + "type": "bool" + } + ], + "name": "dequeueZenBull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "ethBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getDepositReceipt", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getWithdrawReceipt", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isAuctionLive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minEthAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minZenBullAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_price", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_quantity", + "type": "uint256" + } + ], + "name": "netAtPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otcPriceTolerance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "queueEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "queueZenBull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_auctionTwapPeriod", + "type": "uint32" + } + ], + "name": "setAuctionTwapPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bot", + "type": "address" + } + ], + "name": "setBot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newDepositsIndex", + "type": "uint256" + } + ], + "name": "setDepositsIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "setMinEthAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "setMinZenBullAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_otcPriceTolerance", + "type": "uint256" + } + ], + "name": "setOTCPriceTolerance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newWithdrawsIndex", + "type": "uint256" + } + ], + "name": "setWithdrawsIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "toggleAuctionLive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "amount0Delta", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1Delta", + "type": "int256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "uniswapV3SwapCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userDepositsIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userWithdrawsIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "withdrawsToProcess", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "bidId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "internalType": "uint256", + "name": "quantity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isBuying", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct ZenBullNetting.Order[]", + "name": "orders", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "clearingPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxWethForUsdc", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "wethUsdcPoolFee", + "type": "uint24" + } + ], + "internalType": "struct ZenBullNetting.WithdrawAuctionParams", + "name": "_params", + "type": "tuple" + } + ], + "name": "withdrawAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "withdraws", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawsIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawsQueued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "zenBullBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/packages/frontend/src/components/Strategies/Bull/BullTrade/Deposit.tsx b/packages/frontend/src/components/Strategies/Bull/BullTrade/Deposit.tsx index 9c354e460..601950980 100644 --- a/packages/frontend/src/components/Strategies/Bull/BullTrade/Deposit.tsx +++ b/packages/frontend/src/components/Strategies/Bull/BullTrade/Deposit.tsx @@ -3,12 +3,15 @@ import BigNumber from 'bignumber.js' import { useAtom, useAtomValue } from 'jotai' import { useMemo, useRef, useState, useCallback } from 'react' import InfoIcon from '@material-ui/icons/Info' +import HelpOutlineIcon from '@material-ui/icons/HelpOutline' +import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined' import debounce from 'lodash/debounce' +import { useEffect } from 'react' -import { PrimaryButtonNew } from '@components/Button' +import { PrimaryButtonNew, RoundedButton } from '@components/Button' import { InputToken } from '@components/InputNew' import { LinkWrapper } from '@components/LinkWrapper' -import Metric from '@components/Metric' +import Metric, { MetricLabel } from '@components/Metric' import RestrictionInfo from '@components/RestrictionInfo' import { TradeSettings } from '@components/TradeSettings' import { @@ -19,23 +22,34 @@ import { VOL_PERCENT_SCALAR, YEAR, WETH_DECIMALS, + NETTING_PRICE_IMPACT, + AVERAGE_AUCTION_PRICE_IMPACT, } from '@constants/index' -import { useGetFlashBulldepositParams, useBullFlashDeposit } from '@state/bull/hooks' +import { useGetFlashBulldepositParams, useBullFlashDeposit, useQueueDepositEth } from '@state/bull/hooks' import { impliedVolAtom, indexAtom, normFactorAtom, osqthRefVolAtom } from '@state/controller/atoms' import { useSelectWallet, useWalletBalance } from '@state/wallet/hooks' -import { toTokenAmount } from '@utils/calculations' +import { toTokenAmount, fromTokenAmount } from '@utils/calculations' import { formatNumber } from '@utils/formatter' import ethLogo from 'public/images/eth-logo.svg' import { connectedWalletAtom, supportedNetworkAtom } from '@state/wallet/atoms' import { useRestrictUser } from '@context/restrict-user' import { crabStrategySlippageAtomV2, crabStrategyVaultAtomV2, maxCapAtomV2 } from '@state/crab/atoms' import useAppMemo from '@hooks/useAppMemo' -import { bullCapAtom, bullDepositedEthInEulerAtom } from '@state/bull/atoms' +import { + bullCapAtom, + bullDepositedEthInEulerAtom, + minEthAmountAtom, + totalEthQueuedAtom, + totalZenBullQueuedAtom, + ethQueuedAtom, +} from '@state/bull/atoms' import { BULL_EVENTS } from '@utils/amplitude' import useExecuteOnce from '@hooks/useExecuteOnce' import useAmplitude from '@hooks/useAmplitude' import { useZenBullStyles } from './styles' -import { BullTradeType, BullTransactionConfirmation } from './index' +import { OngoingTransaction, BullTradeTransactionType, BullTradeType, BullTransactionConfirmation } from './types' + +const OTC_PRICE_IMPACT_THRESHOLD = Number(process.env.NEXT_PUBLIC_OTC_PRICE_IMPACT_THRESHOLD) || 1 const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) => void }> = ({ onTxnConfirm }) => { const classes = useZenBullStyles() @@ -44,11 +58,16 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = const [depositAmount, setDepositAmount] = useState('0') const depositAmountBN = useMemo(() => new BigNumber(depositAmount), [depositAmount]) - const ongoingTransactionAmountRef = useRef(new BigNumber(0)) + const ongoingTransactionRef = useRef() const [txLoading, setTxLoading] = useState(false) const [slippage, setSlippage] = useAtom(crabStrategySlippageAtomV2) + const [ethQueued, setEthQueued] = useAtom(ethQueuedAtom) + const [quoteLoading, setQuoteLoading] = useState(false) + const [queueOptionAvailable, setQueueOptionAvailable] = useState(false) + const [useQueue, setUseQueue] = useState(false) + const [userOverrode, setUserOverrode] = useState(false) const negativeReturnsError = false const { isRestricted } = useRestrictUser() @@ -66,6 +85,9 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = const crabCap = useAtomValue(maxCapAtomV2) const crabDepositedEth = useAtomValue(crabStrategyVaultAtomV2)?.collateralAmount || BIG_ZERO const osqthRefVol = useAtomValue(osqthRefVolAtom) + const minEthAmountValue = useAtomValue(minEthAmountAtom) + const totalDepositsQueued = useAtomValue(totalEthQueuedAtom) + const totalWithdrawsQueued = useAtomValue(totalZenBullQueuedAtom) const [quote, setQuote] = useState({ ethToCrab: BIG_ZERO, @@ -86,6 +108,7 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = const getFlashBullDepositParams = useGetFlashBulldepositParams() const bullFlashDeposit = useBullFlashDeposit() + const queueDepositEth = useQueueDepositEth() const { track } = useAmplitude() const trackUserEnteredDepositAmount = useCallback( @@ -130,17 +153,27 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = const onTxnConfirmed = useCallback( (id?: string) => { - onInputChange('0') + if (!ongoingTransactionRef.current) return + + const transaction = ongoingTransactionRef.current + if (transaction.queuedTransaction) { + setEthQueued(ethQueued.plus(fromTokenAmount(transaction.amount, WETH_DECIMALS))) + } + onTxnConfirm({ status: true, - amount: ongoingTransactionAmountRef.current, + amount: transaction.amount, tradeType: BullTradeType.Deposit, + transactionType: transaction.queuedTransaction + ? BullTradeTransactionType.Queued + : BullTradeTransactionType.Instant, txId: id, }) + onInputChange('0') resetTracking() - ongoingTransactionAmountRef.current = new BigNumber(0) + ongoingTransactionRef.current = undefined }, - [onTxnConfirm, resetTracking, onInputChange], + [onTxnConfirm, resetTracking, onInputChange, ethQueued, setEthQueued], ) const depositFundingWarning = useAppMemo(() => { @@ -190,43 +223,40 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = quote.wethToLend, ]) - const onDepositClick = useCallback(async () => { + const onDepositClick = async () => { setTxLoading(true) try { - ongoingTransactionAmountRef.current = new BigNumber(depositAmountRef.current) + const amount = new BigNumber(depositAmountRef.current) + ongoingTransactionRef.current = { + amount, + queuedTransaction: useQueue, + } const dataToTrack = { + amount: amount.toNumber(), priceImpact: quote.poolFee + quote.priceImpact, isPriceImpactHigh: depositPriceImpactWarning, - amount: new BigNumber(depositAmountRef.current).toNumber(), } - await bullFlashDeposit( - quote.ethToCrab, - quote.minEthFromSqth, - quote.minEthFromUsdc, - quote.wPowerPerpPoolFee, - quote.usdcPoolFee, - new BigNumber(depositAmountRef.current), - dataToTrack, - onTxnConfirmed, - ) + + if (useQueue) { + await queueDepositEth(amount, dataToTrack, onTxnConfirmed) + } else { + await bullFlashDeposit( + quote.ethToCrab, + quote.minEthFromSqth, + quote.minEthFromUsdc, + quote.wPowerPerpPoolFee, + quote.usdcPoolFee, + amount, + dataToTrack, + onTxnConfirmed, + ) + } } catch (e) { resetTracking() console.log(e) } setTxLoading(false) - }, [ - bullFlashDeposit, - quote.ethToCrab, - quote.minEthFromSqth, - quote.minEthFromUsdc, - quote.wPowerPerpPoolFee, - quote.usdcPoolFee, - quote.poolFee, - quote.priceImpact, - onTxnConfirmed, - resetTracking, - depositPriceImpactWarning, - ]) + } const setDepositMax = () => { track(BULL_EVENTS.DEPOSIT_BULL_SET_AMOUNT_MAX, { @@ -235,6 +265,45 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = onInputChange(toTokenAmount(balance ?? BIG_ZERO, WETH_DECIMALS).toString()) } + const minEthAmount = toTokenAmount(minEthAmountValue, WETH_DECIMALS) + const isDepositAmountLessThanMin = depositAmountBN.lt(minEthAmount) + + useEffect(() => { + if (isDepositAmountLessThanMin) { + setQueueOptionAvailable(false) + setUseQueue(false) + return + } + + if (quote.priceImpact + quote.poolFee > OTC_PRICE_IMPACT_THRESHOLD) { + setQueueOptionAvailable(true) + if (userOverrode) return + setUseQueue(true) + } else { + setQueueOptionAvailable(false) + if (userOverrode) return + setUseQueue(false) + } + }, [isDepositAmountLessThanMin, quote.priceImpact, quote.poolFee, userOverrode]) + + const depositPriceImpactNumber = useAppMemo(() => { + if (!useQueue) return quote.priceImpact + + const withdrawalsLeft = totalWithdrawsQueued.minus(totalDepositsQueued) + const withdrawalsLeftAbs = withdrawalsLeft.isNegative() ? new BigNumber(0) : withdrawalsLeft + + const nettingDepositAmount = withdrawalsLeftAbs.gt(depositAmountBN) ? depositAmountBN : withdrawalsLeftAbs + const remainingDeposit = depositAmountBN.minus(nettingDepositAmount) + + const priceImpact = nettingDepositAmount + .times(NETTING_PRICE_IMPACT) + .plus(remainingDeposit.times(AVERAGE_AUCTION_PRICE_IMPACT)) + .div(depositAmountBN) + .toNumber() + + return priceImpact + }, [depositAmountBN, quote.priceImpact, totalDepositsQueued, totalWithdrawsQueued, useQueue]) + const onChangeSlippage = useCallback( (amount: BigNumber) => { track(BULL_EVENTS.DEPOSIT_BULL_CHANGE_SLIPPAGE, { percent: amount.toNumber() }) @@ -244,6 +313,8 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = [track, setSlippage, depositAmount, onInputChange], ) + const isLoading = txLoading || quoteLoading + return ( <> @@ -252,6 +323,40 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = + + { + setUseQueue(false) + setUserOverrode(true) + }} + className={!useQueue ? classes.btnActive : classes.btnDefault} + > + Instant + + { + setUseQueue(true) + setUserOverrode(true) + }} + className={useQueue ? classes.btnActive : classes.btnDefault} + > + Standard + + + + + + + +
- Zen bull premium is currently lower than usual. Consider depositing later. + Zen Bull premium is currently lower than usual. Consider depositing later. ) : null} @@ -314,31 +419,32 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = ) : null} - - + + - + + } + value={formatNumber(depositPriceImpactNumber) + '%'} + textColor={depositPriceImpactNumber > 3 ? 'error' : undefined} flexDirection="row" justifyContent="space-between" - gridGap="12px" + gridGap="8px" /> @@ -380,7 +486,25 @@ const BullDeposit: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) = onClick={onDepositClick} disabled={quoteLoading || txLoading || depositAmount === '0' || !!depositError} > - {!txLoading && !quoteLoading ? 'Deposit' : } + {isLoading ? ( + + ) : useQueue ? ( + <> + Standard deposit + + Your deposit will be submitted via auction to reduce price impact. This may take until Tuesday. + + } + style={{ marginLeft: '8' }} + > + + + + ) : ( + 'Deposit' + )} )} diff --git a/packages/frontend/src/components/Strategies/Bull/BullTrade/Withdraw.tsx b/packages/frontend/src/components/Strategies/Bull/BullTrade/Withdraw.tsx index 0980e967f..8137287c5 100644 --- a/packages/frontend/src/components/Strategies/Bull/BullTrade/Withdraw.tsx +++ b/packages/frontend/src/components/Strategies/Bull/BullTrade/Withdraw.tsx @@ -1,14 +1,17 @@ import { Box, Typography, Tooltip, CircularProgress } from '@material-ui/core' +import HelpOutlineIcon from '@material-ui/icons/HelpOutline' +import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined' import BigNumber from 'bignumber.js' import { useAtom, useAtomValue } from 'jotai' import { useCallback, useRef, useState, useMemo } from 'react' import InfoIcon from '@material-ui/icons/Info' import debounce from 'lodash/debounce' +import { useEffect } from 'react' -import { PrimaryButtonNew } from '@components/Button' +import { PrimaryButtonNew, RoundedButton } from '@components/Button' import { InputToken } from '@components/InputNew' import { LinkWrapper } from '@components/LinkWrapper' -import Metric from '@components/Metric' +import Metric, { MetricLabel } from '@components/Metric' import RestrictionInfo from '@components/RestrictionInfo' import { TradeSettings } from '@components/TradeSettings' import { @@ -20,11 +23,20 @@ import { VOL_PERCENT_SCALAR, WETH_DECIMALS, YEAR, + STRATEGY_DEPOSIT_LIMIT, + ZENBULL_TOKEN_DECIMALS, + NETTING_PRICE_IMPACT, + AVERAGE_AUCTION_PRICE_IMPACT, } from '@constants/index' -import { useGetFlashWithdrawParams, useBullFlashWithdraw } from '@state/bull/hooks' +import { + useGetFlashWithdrawParams, + useBullFlashWithdraw, + useQueueWithdrawZenBull, + useEthToBull, +} from '@state/bull/hooks' import { impliedVolAtom, indexAtom, normFactorAtom, osqthRefVolAtom } from '@state/controller/atoms' import { useSelectWallet } from '@state/wallet/hooks' -import { toTokenAmount } from '@utils/calculations' +import { toTokenAmount, fromTokenAmount } from '@utils/calculations' import { formatNumber } from '@utils/formatter' import ethLogo from 'public/images/eth-logo.svg' import { crabStrategySlippageAtomV2 } from '@state/crab/atoms' @@ -33,46 +45,71 @@ import { addressesAtom } from '@state/positions/atoms' import { useUserAllowance } from '@hooks/contracts/useAllowance' import { useRestrictUser } from '@context/restrict-user' import { connectedWalletAtom, supportedNetworkAtom } from '@state/wallet/atoms' -import { bullCurrentETHPositionAtom } from '@state/bull/atoms' +import { + bullCurrentETHPositionAtom, + isNettingAuctionLiveAtom, + minZenBullAmountAtom, + totalEthQueuedAtom, + totalZenBullQueuedAtom, + zenBullQueuedAtom, +} from '@state/bull/atoms' import useAppMemo from '@hooks/useAppMemo' import useAppCallback from '@hooks/useAppCallback' import useAmplitude from '@hooks/useAmplitude' import { BULL_EVENTS } from '@utils/amplitude' import useExecuteOnce from '@hooks/useExecuteOnce' -import { useZenBullStyles } from './styles' -import { BullTradeType, BullTransactionConfirmation } from './index' import useTrackTransactionFlow from '@hooks/useTrackTransactionFlow' +import { useZenBullStyles } from './styles' +import { OngoingTransaction, BullTradeType, BullTransactionConfirmation, BullTradeTransactionType } from './types' + +enum WithdrawSteps { + APPROVE = 'Approve ZenBull', + WITHDRAW = 'Withdraw', +} + +const OTC_PRICE_IMPACT_THRESHOLD = Number(process.env.NEXT_PUBLIC_OTC_PRICE_IMPACT_THRESHOLD) || 1 const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) => void }> = ({ onTxnConfirm }) => { const classes = useZenBullStyles() const withdrawAmountRef = useRef('0') - const ongoingTransactionAmountRef = useRef(new BigNumber(0)) + const ongoingTransactionRef = useRef() + const [withdrawAmount, setWithdrawAmount] = useState('0') const withdrawAmountBN = useMemo(() => new BigNumber(withdrawAmount), [withdrawAmount]) - const [txLoading, setTxLoading] = useState(false) const [slippage, setSlippage] = useAtom(crabStrategySlippageAtomV2) + const [zenBullQueued, setZenBullQueued] = useAtom(zenBullQueuedAtom) + + const [txLoading, setTxLoading] = useState(false) const [quoteLoading, setQuoteLoading] = useState(false) + const [withdrawStep, setWithdrawStep] = useState(WithdrawSteps.WITHDRAW) + const [queueOptionAvailable, setQueueOptionAvailable] = useState(false) + const [useQueue, setUseQueue] = useState(false) + const [userOverrode, setUserOverrode] = useState(false) const negativeReturnsError = false - const highDepositWarning = false - const { isRestricted } = useRestrictUser() const connected = useAtomValue(connectedWalletAtom) const supportedNetwork = useAtomValue(supportedNetworkAtom) const bullPositionValueInEth = useAtomValue(bullCurrentETHPositionAtom) const osqthRefVol = useAtomValue(osqthRefVolAtom) - - const selectWallet = useSelectWallet() - + const isNettingAuctionLive = useAtomValue(isNettingAuctionLiveAtom) + const minZenBullAmountValue = useAtomValue(minZenBullAmountAtom) + const totalDepositsQueued = useAtomValue(totalEthQueuedAtom) + const totalWithdrawsQueued = useAtomValue(totalZenBullQueuedAtom) const index = useAtomValue(indexAtom) const ethIndexPrice = toTokenAmount(index, 18).sqrt() const impliedVol = useAtomValue(impliedVolAtom) const normFactor = useAtomValue(normFactorAtom) - const { bullStrategy, flashBull } = useAtomValue(addressesAtom) + const selectWallet = useSelectWallet() + const { isRestricted } = useRestrictUser() + + const { bullStrategy, flashBull, bullNetting } = useAtomValue(addressesAtom) const { value: bullBalance } = useTokenBalance(bullStrategy, 15, WETH_DECIMALS) const { allowance: bullAllowance, approve: approveBull } = useUserAllowance(bullStrategy, flashBull) + const { allowance: bullQueueAllowance, approve: approveQueueBull } = useUserAllowance(bullStrategy, bullNetting) + const ethToBull = useEthToBull() const [quote, setQuote] = useState({ maxEthForWPowerPerp: BIG_ZERO, @@ -89,6 +126,7 @@ const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) const getFlashBullWithdrawParams = useGetFlashWithdrawParams() const bullFlashWithdraw = useBullFlashWithdraw() + const queueWithdrawZenBull = useQueueWithdrawZenBull() const { track } = useAmplitude() const logAndRunTransaction = useTrackTransactionFlow() @@ -98,6 +136,10 @@ const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) ) const [trackWithdrawAmountEnteredOnce, resetTracking] = useExecuteOnce(trackUserEnteredWithdrawAmount) + const withdrawZenBullAmount = useAppMemo(() => { + return ethToBull(withdrawAmountBN || BIG_ZERO) + }, [withdrawAmountBN, ethToBull]) + const showPriceImpactWarning = useAppMemo(() => { const squeethPrice = quote.ethInForSqth.div(quote.oSqthOut).times(1 - UNI_POOL_FEES / 1000_000) const scalingFactor = new BigNumber(INDEX_SCALE) @@ -157,53 +199,81 @@ const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) const onTxnConfirmed = useCallback( (id?: string) => { - onInputChange('0') + if (!ongoingTransactionRef.current) return + + const transaction = ongoingTransactionRef.current + if (transaction.queuedTransaction) { + setZenBullQueued(zenBullQueued.plus(fromTokenAmount(transaction.amount, ZENBULL_TOKEN_DECIMALS))) + } + onTxnConfirm({ status: true, - amount: ongoingTransactionAmountRef.current, + amount: transaction.amount, tradeType: BullTradeType.Withdraw, + transactionType: transaction.queuedTransaction + ? BullTradeTransactionType.Queued + : BullTradeTransactionType.Instant, txId: id, }) + onInputChange('0') resetTracking() - ongoingTransactionAmountRef.current = new BigNumber(0) + ongoingTransactionRef.current = undefined }, - [onTxnConfirm, resetTracking, onInputChange], + [onTxnConfirm, resetTracking, onInputChange, zenBullQueued, setZenBullQueued], ) - const onWithdrawClick = async () => { + const onApproveClick = async () => { setTxLoading(true) try { - ongoingTransactionAmountRef.current = new BigNumber(withdrawAmount) - const dataToTrack = { - amount: new BigNumber(withdrawAmountRef.current).toNumber(), - isPriceImpactHigh: showPriceImpactWarning, - priceImpact: quote.poolFee + quote.priceImpact, + if (useQueue) { + logAndRunTransaction(async () => { + await approveQueueBull(() => console.log('Approved Standard Bull')) + }, BULL_EVENTS.APPROVE_WITHDRAW_STN_BULL) + } else { + await logAndRunTransaction(async () => { + await approveBull(() => console.log('Approved Instant Bull')) + }, BULL_EVENTS.APPROVE_WITHDRAW_BULL) } - await bullFlashWithdraw( - new BigNumber(withdrawAmountRef.current), - quote.maxEthForWPowerPerp, - quote.maxEthForUsdc, - quote.wPowerPerpPoolFee, - quote.usdcPoolFee, - dataToTrack, - onTxnConfirmed, - ) } catch (e) { - resetTracking() console.log(e) } setTxLoading(false) } - const onApproveClick = async () => { + const onWithdrawClick = async () => { setTxLoading(true) try { - await logAndRunTransaction(async () => { - await approveBull(() => console.log('Approved')) - }, BULL_EVENTS.APPROVE_WITHDRAW_BULL) + const bullWithdrawAmount = new BigNumber(withdrawAmountRef.current) + const ethWithdrawAmount = new BigNumber(withdrawAmount) + + ongoingTransactionRef.current = { + amount: ethWithdrawAmount, + queuedTransaction: useQueue, + } + const dataToTrack = { + amount: bullWithdrawAmount, + isPriceImpactHigh: showPriceImpactWarning, + priceImpact: quote.poolFee + quote.priceImpact, + } + + if (useQueue) { + await queueWithdrawZenBull(bullWithdrawAmount, dataToTrack, onTxnConfirmed) + } else { + await bullFlashWithdraw( + bullWithdrawAmount, + quote.maxEthForWPowerPerp, + quote.maxEthForUsdc, + quote.wPowerPerpPoolFee, + quote.usdcPoolFee, + dataToTrack, + onTxnConfirmed, + ) + } } catch (e) { + resetTracking() console.log(e) } + setTxLoading(false) } @@ -220,6 +290,66 @@ const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) onInputChange(bullPositionValueInEth.toString()) } + // Update withdraw step + useEffect(() => { + if (useQueue) { + if (bullQueueAllowance.lt(withdrawZenBullAmount)) { + setWithdrawStep(WithdrawSteps.APPROVE) + } else { + setWithdrawStep(WithdrawSteps.WITHDRAW) + } + } else { + if (bullAllowance.lt(withdrawZenBullAmount)) { + setWithdrawStep(WithdrawSteps.APPROVE) + } else { + setWithdrawStep(WithdrawSteps.WITHDRAW) + } + } + }, [useQueue, bullQueueAllowance, withdrawZenBullAmount, bullAllowance]) + + const minZenBullAmount = toTokenAmount(minZenBullAmountValue, ZENBULL_TOKEN_DECIMALS) + const isWithdrawZenBullLessThanMin = withdrawZenBullAmount.lt(minZenBullAmount) + + useEffect(() => { + if (isNettingAuctionLive || isWithdrawZenBullLessThanMin) { + setQueueOptionAvailable(false) + setUseQueue(false) + return + } + + if (quote.priceImpact + quote.poolFee > OTC_PRICE_IMPACT_THRESHOLD) { + setQueueOptionAvailable(true) + if (!userOverrode) { + setUseQueue(true) + } + } else { + setQueueOptionAvailable(false) + if (!userOverrode) { + setUseQueue(false) + } + } + }, [isNettingAuctionLive, isWithdrawZenBullLessThanMin, quote.priceImpact, quote.poolFee, userOverrode]) + + const withdrawPriceImpactNumber = useAppMemo(() => { + if (!useQueue) { + return quote.priceImpact + } + + const depositsLeft = totalDepositsQueued.minus(totalWithdrawsQueued) + const depositsLeftAbs = depositsLeft.isNegative() ? new BigNumber(0) : depositsLeft + + const nettingWithdrawAmount = depositsLeftAbs.gt(withdrawAmountBN) ? withdrawAmountBN : depositsLeftAbs + const remainingWithdraw = withdrawAmountBN.minus(nettingWithdrawAmount) + + const priceImpact = nettingWithdrawAmount + .times(NETTING_PRICE_IMPACT) + .plus(remainingWithdraw.times(AVERAGE_AUCTION_PRICE_IMPACT)) + .div(withdrawAmountBN) + .toNumber() + + return priceImpact + }, [totalDepositsQueued, totalWithdrawsQueued, useQueue, withdrawAmountBN, quote.priceImpact]) + const onChangeSlippage = useCallback( (amount: BigNumber) => { track(BULL_EVENTS.WITHDRAW_BULL_CHANGE_SLIPPAGE, { percent: amount.toNumber() }) @@ -229,6 +359,8 @@ const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) [withdrawAmount, setSlippage, onInputChange, track], ) + const isLoading = txLoading || quoteLoading + return ( <> @@ -237,6 +369,40 @@ const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) + + = STRATEGY_DEPOSIT_LIMIT || !Number(withdrawAmount)} + variant="outlined" + size="small" + onClick={() => { + setUseQueue(false) + setUserOverrode(true) + }} + className={!useQueue ? classes.btnActive : classes.btnDefault} + > + Instant + + { + setUseQueue(true) + setUserOverrode(true) + }} + className={useQueue ? classes.btnActive : classes.btnDefault} + > + Standard + + + + + + + +
) : null} - - + + - + + } + value={formatNumber(quote.priceImpact) + '%'} + textColor={withdrawPriceImpactNumber > 3 ? 'error' : undefined} flexDirection="row" justifyContent="space-between" - gridGap="12px" + gridGap="8px" /> @@ -356,25 +529,44 @@ const BullWithdraw: React.FC<{ onTxnConfirm: (txn: BullTransactionConfirmation) {'Unsupported Network'} - ) : bullAllowance.lt(withdrawAmount) ? ( + ) : withdrawStep === WithdrawSteps.APPROVE ? ( - {!txLoading ? 'Approve' : } + {isLoading ? : 'Approve strategy to withdraw'} ) : ( - {!txLoading && !quoteLoading ? 'Withdraw' : } + {isLoading ? ( + + ) : useQueue ? ( + <> + Standard withdraw + + Your withdrawal will be submitted via auction to reduce price impact. This may take until + Tuesday. +
+ } + style={{ marginLeft: '8' }} + > + + + + ) : ( + 'Withdraw' + )} )}
diff --git a/packages/frontend/src/components/Strategies/Bull/BullTrade/index.tsx b/packages/frontend/src/components/Strategies/Bull/BullTrade/index.tsx index 9e1828859..c7fcc1ea1 100644 --- a/packages/frontend/src/components/Strategies/Bull/BullTrade/index.tsx +++ b/packages/frontend/src/components/Strategies/Bull/BullTrade/index.tsx @@ -1,16 +1,16 @@ import { createStyles, makeStyles } from '@material-ui/core/styles' -import BigNumber from 'bignumber.js' -import React, { useCallback, useState } from 'react' +import React, { useCallback, useState, useMemo } from 'react' +import { useAtomValue } from 'jotai' import { PrimaryButtonNew } from '@components/Button' import { SqueethTabsNew, SqueethTabNew } from '@components/Tabs' import Confirmed, { ConfirmType } from '@components/Trade/Confirmed' import { useTransactionStatus } from '@state/wallet/hooks' -import BullDeposit from './Deposit' -import BullWithdraw from './Withdraw' import { useBullPosition } from '@hooks/useBullPosition' -import { useAtomValue } from 'jotai' import { addressAtom } from '@state/wallet/atoms' +import BullDeposit from './Deposit' +import BullWithdraw from './Withdraw' +import { BullTradeType, BullTransactionConfirmation, BullTradeTransactionType } from './types' const useStyles = makeStyles((theme) => createStyles({ @@ -56,16 +56,41 @@ const useStyles = makeStyles((theme) => }), ) -export enum BullTradeType { - Deposit = 'Deposit', - Withdraw = 'Withdraw', -} +const TxConfirmation: React.FC<{ txnData: BullTransactionConfirmation; txnHash: string; onClose: () => void }> = ({ + txnData, + txnHash, + onClose, +}) => { + const isDepositTx = txnData?.tradeType === BullTradeType.Deposit + const isQueuedTx = txnData?.transactionType === BullTradeTransactionType.Queued -export interface BullTransactionConfirmation { - status: boolean - amount: BigNumber - tradeType: BullTradeType - txId?: string + const txAmount = txnData?.amount + const formattedTxAmount = txAmount.toFixed(4) + + const confirmationMessage = useMemo(() => { + if (isDepositTx) { + if (isQueuedTx) { + return `Initiated ${formattedTxAmount} ETH deposit` + } else { + return `Deposited ${formattedTxAmount} ETH` + } + } else { + if (isQueuedTx) { + return `Initiated ${formattedTxAmount} ETH withdraw` + } else { + return `Withdrawn ${formattedTxAmount} ETH` + } + } + }, [isDepositTx, isQueuedTx, formattedTxAmount]) + + return ( + <> + + + Close + + + ) } const BullTrade: React.FC = () => { @@ -99,18 +124,7 @@ const BullTrade: React.FC = () => { return ( <> {confirmed && confirmedTransactionData?.status ? ( - <> - - - Close - - + ) : ( <> tradeContainer: { display: 'flex', flexDirection: 'column', - marginTop: theme.spacing(2), + marginTop: theme.spacing(3), }, tabBackGround: { position: 'sticky', @@ -28,6 +28,10 @@ export const useZenBullStyles = makeStyles((theme) => marginRight: theme.spacing(2), color: '#F3FF6C', }, + infoIconGray: { + marginRight: theme.spacing(2), + color: theme.palette.text.hint, + }, subtitle: { fontSize: '18px', fontWeight: 700, @@ -38,10 +42,13 @@ export const useZenBullStyles = makeStyles((theme) => fontWeight: 500, fontSize: '13px', }, - slippageContainer: { - [theme.breakpoints.down('xs')]: { - flexWrap: 'wrap', - }, + btnDefault: { + color: 'rgba(255, 255, 255, 0.4)', + border: '2px solid transparent', + }, + btnActive: { + color: theme.palette.primary.main, + border: `2px solid ${theme.palette.primary.main}`, }, }), ) diff --git a/packages/frontend/src/components/Strategies/Bull/BullTrade/types.ts b/packages/frontend/src/components/Strategies/Bull/BullTrade/types.ts new file mode 100644 index 000000000..93e0f02e3 --- /dev/null +++ b/packages/frontend/src/components/Strategies/Bull/BullTrade/types.ts @@ -0,0 +1,24 @@ +import BigNumber from 'bignumber.js' + +export enum BullTradeType { + Deposit = 'Deposit', + Withdraw = 'Withdraw', +} + +export enum BullTradeTransactionType { + Instant = 'Instant', + Queued = 'Queued', +} + +export interface OngoingTransaction { + amount: BigNumber + queuedTransaction: boolean +} + +export interface BullTransactionConfirmation { + status: boolean + amount: BigNumber + tradeType: BullTradeType + transactionType: BullTradeTransactionType + txId?: string +} diff --git a/packages/frontend/src/components/Strategies/Bull/MyPosition/QueuedPosition.tsx b/packages/frontend/src/components/Strategies/Bull/MyPosition/QueuedPosition.tsx new file mode 100644 index 000000000..682b4de2f --- /dev/null +++ b/packages/frontend/src/components/Strategies/Bull/MyPosition/QueuedPosition.tsx @@ -0,0 +1,121 @@ +import React, { useState } from 'react' +import { Box, Typography, CircularProgress } from '@material-ui/core' +import { useAtom, useAtomValue } from 'jotai' +import clsx from 'clsx' + +import { formatNumber } from '@utils/formatter' +import useStyles from '@components/Strategies/styles' +import { BIG_ZERO, WETH_DECIMALS, ZENBULL_TOKEN_DECIMALS } from '@constants/index' +import { ethQueuedAtom, zenBullQueuedAtom, isNettingAuctionLiveAtom, bullEthValuePerShareAtom } from '@state/bull/atoms' +import { useDequeueDepositEth, useDequeueWithdrawZenBull } from '@state/bull/hooks' +import { useTransactionStatus } from '@state/wallet/hooks' +import { toTokenAmount } from '@utils/calculations' +import { TextButton } from '@components/Button' + +const DepositQueued: React.FC = () => { + const [ethQueued, setEthQueued] = useAtom(ethQueuedAtom) + const isNettingAuctionLive = useAtomValue(isNettingAuctionLiveAtom) + const [txLoading, setTxLoading] = useState(false) + + const dequeueEth = useDequeueDepositEth() + const { resetTransactionData } = useTransactionStatus() + + const onDequeueEth = async () => { + setTxLoading(true) + try { + await dequeueEth(ethQueued, resetTransactionData) + setEthQueued(BIG_ZERO) + } catch (e) { + console.log(e) + } + setTxLoading(false) + } + + const classes = useStyles() + + return ( + + + Initiated Deposit + + + + + {formatNumber(Number(toTokenAmount(ethQueued, WETH_DECIMALS)), 4)} ETH + + {!isNettingAuctionLive && ( + + {!txLoading ? 'Cancel' : } + + )} + + + ) +} + +const WithdrawQueued: React.FC = () => { + const [zenBullQueued, setZenBullQueued] = useAtom(zenBullQueuedAtom) + const isNettingAuctionLive = useAtomValue(isNettingAuctionLiveAtom) + const bullEthValue = useAtomValue(bullEthValuePerShareAtom) + const [txLoading, setTxLoading] = useState(false) + + const dequeueZenBull = useDequeueWithdrawZenBull() + const { resetTransactionData } = useTransactionStatus() + + const onDequeueBull = async () => { + setTxLoading(true) + try { + await dequeueZenBull(zenBullQueued, resetTransactionData) + setZenBullQueued(BIG_ZERO) + } catch (e) { + console.log(e) + } + setTxLoading(false) + } + + const classes = useStyles() + + const withdrawalValueInEth = toTokenAmount(zenBullQueued, ZENBULL_TOKEN_DECIMALS).times(bullEthValue) + + return ( + + + Initiated Withdraw + + + + + {formatNumber(Number(withdrawalValueInEth), 4)} ETH + + {!isNettingAuctionLive && ( + + {!txLoading ? 'Cancel' : } + + )} + + + ) +} + +const QueuedPosition: React.FC = () => { + const ethQueued = useAtomValue(ethQueuedAtom) + const zenBullQueued = useAtomValue(zenBullQueuedAtom) + + // ignore dust amount + // todo: come back here to see if eth's dust amount is fine + const showQueuedDeposit = ethQueued.isGreaterThan('10000000000') + const showQueuedWithdraw = zenBullQueued.isGreaterThan('10000000000') + + if (!showQueuedDeposit && !showQueuedWithdraw) { + return null + } + + return ( + + {showQueuedDeposit && } + {showQueuedWithdraw && } + + ) +} + +export default QueuedPosition diff --git a/packages/frontend/src/components/Strategies/Bull/MyPosition/ZenBullPosition.tsx b/packages/frontend/src/components/Strategies/Bull/MyPosition/ZenBullPosition.tsx new file mode 100644 index 000000000..b25b752e3 --- /dev/null +++ b/packages/frontend/src/components/Strategies/Bull/MyPosition/ZenBullPosition.tsx @@ -0,0 +1,59 @@ +import React from 'react' +import { Box, Typography } from '@material-ui/core' +import clsx from 'clsx' +import { useAtomValue } from 'jotai' + +import useStyles from '@components/Strategies/styles' +import { formatNumber, formatCurrency } from '@utils/formatter' +import SharePnl from '@components/Strategies/SharePnl' +import { + bullCurrentETHPositionAtom, + bullCurrentUSDCPositionAtom, + bullEthPnlAtom, + bullEthPnlPerctAtom, + bullFirstDepositTimestampAtom, +} from '@state/bull/atoms' +import PnL from './PnL' + +const ZenBullPosition: React.FC = () => { + const classes = useStyles() + + const bullPosition = useAtomValue(bullCurrentETHPositionAtom) + const bullUsdcPosition = useAtomValue(bullCurrentUSDCPositionAtom) + const bullEthPnL = useAtomValue(bullEthPnlAtom) + const bullEthPnlPerct = useAtomValue(bullEthPnlPerctAtom) + const firstDepositTimestamp = useAtomValue(bullFirstDepositTimestampAtom) + + const isPnlLoading = !bullEthPnL.isFinite() + + return ( + +
+ + My Zen Bull Position + + + + + {formatNumber(bullPosition.toNumber(), 4) + ' ETH'} + + + + {formatCurrency(bullUsdcPosition.toNumber())} + + + + +
+ + +
+ ) +} + +export default ZenBullPosition diff --git a/packages/frontend/src/components/Strategies/Bull/MyPosition/index.tsx b/packages/frontend/src/components/Strategies/Bull/MyPosition/index.tsx index b27cccc48..b0ad135e4 100644 --- a/packages/frontend/src/components/Strategies/Bull/MyPosition/index.tsx +++ b/packages/frontend/src/components/Strategies/Bull/MyPosition/index.tsx @@ -1,29 +1,26 @@ import { Typography, Box } from '@material-ui/core' import React, { memo } from 'react' -import clsx from 'clsx' import { useAtomValue } from 'jotai' import { Skeleton } from '@material-ui/lab' import { bullCurrentETHPositionAtom, - bullCurrentUSDCPositionAtom, - bullEthPnlAtom, - bullEthPnlPerctAtom, bullPositionLoadedAtom, isBullPositionRefetchingAtom, - bullFirstDepositTimestampAtom, + ethQueuedAtom, + zenBullQueuedAtom, + bullEthPnlAtom, } from '@state/bull/atoms' -import { formatCurrency, formatNumber } from '@utils/formatter' -import SharePnl from '@components/Strategies/SharePnl' -import PnL from './PnL' + import useStyles from '@components/Strategies/styles' +import ZenBullPosition from './ZenBullPosition' +import QueuedPosition from './QueuedPosition' const BullPosition: React.FC = () => { const bullPosition = useAtomValue(bullCurrentETHPositionAtom) - const bullUsdcPosition = useAtomValue(bullCurrentUSDCPositionAtom) + const ethQueued = useAtomValue(ethQueuedAtom) + const zenBullQueued = useAtomValue(zenBullQueuedAtom) const bullEthPnL = useAtomValue(bullEthPnlAtom) - const bullEthPnlPerct = useAtomValue(bullEthPnlPerctAtom) - const firstDepositTimestamp = useAtomValue(bullFirstDepositTimestampAtom) const classes = useStyles() @@ -31,7 +28,7 @@ const BullPosition: React.FC = () => { const isPositionRefetching = useAtomValue(isBullPositionRefetchingAtom) const isPnlLoading = !bullEthPnL.isFinite() - if (bullPosition.isZero() && !isPositionRefetching) { + if (bullPosition.isZero() && !isPositionRefetching && ethQueued.isZero() && zenBullQueued.isZero()) { return null } @@ -47,31 +44,9 @@ const BullPosition: React.FC = () => { } return ( - -
- - My Zen Bull Position - - - - - {formatNumber(bullPosition.toNumber(), 4) + ' ETH'} - - - - {formatCurrency(bullUsdcPosition.toNumber())} - - - - -
- - + + + ) } diff --git a/packages/frontend/src/components/Strategies/Crab/CrabTradeV2/Withdraw.tsx b/packages/frontend/src/components/Strategies/Crab/CrabTradeV2/Withdraw.tsx index 321688c6d..598c82a79 100644 --- a/packages/frontend/src/components/Strategies/Crab/CrabTradeV2/Withdraw.tsx +++ b/packages/frontend/src/components/Strategies/Crab/CrabTradeV2/Withdraw.tsx @@ -83,7 +83,6 @@ enum WithdrawSteps { } const OTC_PRICE_IMPACT_THRESHOLD = Number(process.env.NEXT_PUBLIC_OTC_PRICE_IMPACT_THRESHOLD) || 1 -console.log(OTC_PRICE_IMPACT_THRESHOLD) const CrabWithdraw: React.FC<{ onTxnConfirm: (txn: CrabTransactionConfirmation) => void }> = ({ onTxnConfirm }) => { const classes = useStyles() @@ -295,8 +294,10 @@ const CrabWithdraw: React.FC<{ onTxnConfirm: (txn: CrabTransactionConfirmation) (id?: string) => { if (!ongoingTransaction.current) return const transaction = ongoingTransaction.current - if (transaction.queuedTransaction) + if (transaction.queuedTransaction) { setCrabQueued(crabQueued.plus(fromTokenAmount(transaction.amount, CRAB_TOKEN_DECIMALS))) + } + onTxnConfirm({ status: true, amount: transaction.amount, @@ -597,9 +598,9 @@ const CrabWithdraw: React.FC<{ onTxnConfirm: (txn: CrabTransactionConfirmation) { - setConfirmedTransactionData(confirm) - confirm?.id ? pollForNewTx(confirm?.id) : null + (data?: CrabTransactionConfirmation) => { + setConfirmedTransactionData(data) + if (data?.id) { + pollForNewTx(data?.id) + } refetchCrabTokenBalance() }, [setConfirmedTransactionData, pollForNewTx, refetchCrabTokenBalance], diff --git a/packages/frontend/src/constants/address.ts b/packages/frontend/src/constants/address.ts index cf79ce22d..cb38a7dcc 100644 --- a/packages/frontend/src/constants/address.ts +++ b/packages/frontend/src/constants/address.ts @@ -183,6 +183,14 @@ export const BULL_STRATEGY: Address = { 31337: '', } +export const BULL_NETTING: Address = { + 1: '', + 3: '', + 5: '0xB9231F991DBE074eC943d37fAb1f73300BEA289E', + 421611: '', + 31337: '', +} + export const WETH_E_TOKEN: Address = { 1: '0x1b808F49ADD4b8C6b5117d9681cF7312Fcf0dC1D', 3: '', diff --git a/packages/frontend/src/constants/index.ts b/packages/frontend/src/constants/index.ts index 3973f66db..2f2f00f40 100644 --- a/packages/frontend/src/constants/index.ts +++ b/packages/frontend/src/constants/index.ts @@ -44,6 +44,7 @@ export const OSQUEETH_DECIMALS = 18 export const WETH_DECIMALS = 18 export const USDC_DECIMALS = 6 export const CRAB_TOKEN_DECIMALS = 18 +export const ZENBULL_TOKEN_DECIMALS = 18 export const SWAP_EVENT_TOPIC = '0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67' diff --git a/packages/frontend/src/pages/positions/BullPosition.tsx b/packages/frontend/src/pages/positions/BullPosition.tsx index 5af4f4848..2cc84b4d5 100644 --- a/packages/frontend/src/pages/positions/BullPosition.tsx +++ b/packages/frontend/src/pages/positions/BullPosition.tsx @@ -1,9 +1,9 @@ -import { Tooltip, Typography, makeStyles } from '@material-ui/core' +import { Tooltip, Typography } from '@material-ui/core' import InfoIcon from '@material-ui/icons/InfoOutlined' -import useStyles from './useStyles' -import Image from 'next/image' -import { Tooltips } from '../../constants' import { useAtomValue } from 'jotai' +import Image from 'next/image' + +import { Tooltips, WETH_DECIMALS, ZENBULL_TOKEN_DECIMALS } from '@constants/index' import { bullCurrentETHPositionAtom, bullCurrentUSDCPositionAtom, @@ -12,8 +12,14 @@ import { bullEthPnlAtom, bullEthPnlPerctAtom, bullPositionLoadedAtom, + ethQueuedAtom, + zenBullQueuedAtom, + bullEthValuePerShareAtom, } from '@state/bull/atoms' +import { toTokenAmount } from '@utils/calculations' +import { formatNumber } from '@utils/formatter' import bullStrategyImg from 'public/images/bull_strategy.png' +import useStyles from './useStyles' const BullPosition: React.FC = () => { const classes = useStyles() @@ -26,9 +32,18 @@ const BullPosition: React.FC = () => { const bullEthPnl = useAtomValue(bullEthPnlAtom) const bullEthPnlInPerct = useAtomValue(bullEthPnlPerctAtom) + const ethQueued = useAtomValue(ethQueuedAtom) + const zenBullQueued = useAtomValue(zenBullQueuedAtom) + const bullEthValue = useAtomValue(bullEthValuePerShareAtom) + const loading = !useAtomValue(bullPositionLoadedAtom) - if (bullCurrentETH.isZero()) return null + if (bullCurrentETH.isZero() && ethQueued.isZero() && zenBullQueued.isZero()) { + return null + } + + const initiatedDepositAmount = toTokenAmount(ethQueued, WETH_DECIMALS) + const initiatedWithdrawalAmount = toTokenAmount(zenBullQueued, ZENBULL_TOKEN_DECIMALS).times(bullEthValue) return (
@@ -51,7 +66,7 @@ const BullPosition: React.FC = () => { {bullDepositedETH.toFixed(6)} ETH - ${bullDepositedUSD.toFixed(2)} + ${bullDepositedUSD.toFixed(2)}
@@ -75,7 +90,7 @@ const BullPosition: React.FC = () => { {!loading ? `${bullEthPnl.toFixed(6)} ETH` : 'Loading'} @@ -84,6 +99,38 @@ const BullPosition: React.FC = () => {
+ +
+ {/* ignore dust amount */} + {ethQueued.isGreaterThan('10000000000') && ( +
+ + Initiated Deposit + + + + + + {!loading ? formatNumber(Number(initiatedDepositAmount), 4) + ' ETH' : 'Loading'} + +
+ )} + + {/* ignore dust amount */} + {zenBullQueued.isGreaterThan('10000000000') && ( +
+ + Initiated Withdrawal + + + + + + {!loading ? formatNumber(Number(initiatedWithdrawalAmount), 4) + ' ETH' : 'Loading'} + +
+ )} +
) diff --git a/packages/frontend/src/state/bull/atoms.ts b/packages/frontend/src/state/bull/atoms.ts index 19787d3b6..33f4b9bc2 100644 --- a/packages/frontend/src/state/bull/atoms.ts +++ b/packages/frontend/src/state/bull/atoms.ts @@ -70,6 +70,15 @@ export const bullTimeAtLastHedgeAtom = atom(0) export const bullStrategyFilterStartDateAtom = atom(new Date(BULL_START_DATE)) export const bullStrategyFilterEndDateAtom = atom(new Date()) +export const isNettingAuctionLiveAtom = atom(false) +export const minEthAmountAtom = atom(BIG_ZERO) +export const minZenBullAmountAtom = atom(BIG_ZERO) +export const totalEthQueuedAtom = atom(BIG_ZERO) +export const totalZenBullQueuedAtom = atom(BIG_ZERO) + +export const ethQueuedAtom = atom(BIG_ZERO) +export const zenBullQueuedAtom = atom(BIG_ZERO) + export const useBullPnLChartData = () => { const startDate = useAtomValue(bullStrategyFilterStartDateAtom) const endDate = useAtomValue(bullStrategyFilterEndDateAtom) diff --git a/packages/frontend/src/state/bull/hooks.ts b/packages/frontend/src/state/bull/hooks.ts index 4f272884d..7ef9130e2 100644 --- a/packages/frontend/src/state/bull/hooks.ts +++ b/packages/frontend/src/state/bull/hooks.ts @@ -1,4 +1,11 @@ +import BigNumber from 'bignumber.js' +import { useAtomValue, useSetAtom } from 'jotai' +import { useUpdateAtom } from 'jotai/utils' +import { useEffect, useMemo } from 'react' +import { useQueryClient } from 'react-query' +import { useMountedState } from 'react-use' import { useQuery } from '@apollo/client' + import { BIG_ONE, BIG_ZERO, @@ -6,6 +13,7 @@ import { UNI_POOL_FEES, USDC_DECIMALS, WETH_DECIMALS, + ZENBULL_TOKEN_DECIMALS, } from '@constants/index' import { useTokenBalance } from '@hooks/contracts/useTokenBalance' import useAmplitude from '@hooks/useAmplitude' @@ -22,6 +30,7 @@ import { flashBullContractAtom, quoterContractAtom, wethETokenContractAtom, + bullNettingContractAtom, } from '@state/contracts/atoms' import { indexAtom } from '@state/controller/atoms' import { crabStrategySlippageAtomV2, crabStrategyVaultAtomV2, crabTotalSupplyV2Atom } from '@state/crab/atoms' @@ -34,12 +43,6 @@ import { BULL_EVENTS } from '@utils/amplitude' import { squeethClient } from '@utils/apollo-client' import { fromTokenAmount, getUSDCPoolFee, toTokenAmount } from '@utils/calculations' import { getExactIn, getExactOut } from '@utils/quoter' -import BigNumber from 'bignumber.js' -import { useAtomValue, useSetAtom } from 'jotai' -import { useUpdateAtom } from 'jotai/utils' -import { useEffect, useMemo } from 'react' -import { useQueryClient } from 'react-query' -import { useMountedState } from 'react-use' import { bullCapAtom, bullCRAtom, @@ -57,12 +60,21 @@ import { eulerETHLendRateAtom, bullTimeAtLastHedgeAtom, bullEulerUSDCDebtAtom, + isNettingAuctionLiveAtom, + minEthAmountAtom, + minZenBullAmountAtom, + totalEthQueuedAtom, + totalZenBullQueuedAtom, + ethQueuedAtom, + zenBullQueuedAtom, } from './atoms' import { calcAssetNeededForFlashWithdraw, getEulerInterestRate, getWethToLendFromCrabEth } from './utils' export const useInitBullStrategy = () => { const setBullState = useSetBullState() const setBullUserState = useSetBullUserState() + const setQueuedBullUserState = useSetQueuedBullUserState() + const setBullTimeAtLastHedge = useSetAtom(bullTimeAtLastHedgeAtom) const { auctionBull } = useAtomValue(addressesAtom) const networkId = useAtomValue(networkIdAtom) @@ -86,6 +98,10 @@ export const useInitBullStrategy = () => { useEffect(() => { setBullUserState() }, [setBullUserState]) + + useEffect(() => { + setQueuedBullUserState() + }, [setQueuedBullUserState]) } export const useSetBullState = () => { @@ -93,6 +109,8 @@ export const useSetBullState = () => { const etokenContract = useAtomValue(wethETokenContractAtom) const auctionBullContract = useAtomValue(auctionBullContractAtom) const eulerLenseContract = useAtomValue(eulerLensContractAtom) + const { bullStrategy, weth, usdc } = useAtomValue(addressesAtom) + const setBullCrabBalance = useUpdateAtom(bullCrabBalanceAtom) const setBullSupply = useUpdateAtom(bullSupplyAtom) const setEulerWeth = useUpdateAtom(bullEulerWethCollatPerShareAtom) @@ -104,7 +122,6 @@ export const useSetBullState = () => { const setUsdcBorrowRate = useUpdateAtom(eulerUsdcBorrowRateAtom) const setEthLendRate = useUpdateAtom(eulerETHLendRateAtom) const setTotalUSDCInEuler = useUpdateAtom(bullEulerUSDCDebtAtom) - const { bullStrategy, weth, usdc } = useAtomValue(addressesAtom) const isMounted = useMountedState() @@ -193,6 +210,23 @@ export const useSetBullUserState = () => { return setBullUserState } +export const useEthToBull = () => { + const bullEthValue = useAtomValue(bullEthValuePerShareAtom) + + const getEthToBull = useAppCallback( + (ethAmount: BigNumber) => { + if (bullEthValue.isZero()) { + return BIG_ZERO + } + + return ethAmount.div(bullEthValue) + }, + [bullEthValue], + ) + + return getEthToBull +} + export const useGetFlashBulldepositParams = () => { const bullStrategyContract = useAtomValue(bullStrategyContractAtom) const crabV2Vault = useAtomValue(crabStrategyVaultAtomV2) @@ -384,7 +418,7 @@ export const useBullFlashDeposit = () => { wPowerPerpPoolFee: number, usdcPoolFee: number, ethToSend: BigNumber, - dataToTrack?: any, + dataToTrack?: Record, onTxConfirmed?: (id?: string) => void, ) => { if (!flashBullContract) return @@ -591,7 +625,7 @@ export const useBullFlashWithdraw = () => { maxEthForUsdc: BigNumber, wPowerPerpPoolFee: number, usdcPoolFee: number, - dataToTrack?: any, + dataToTrack?: Record, onTxConfirmed?: () => void, ) => { if (!flashBullContract) return @@ -654,3 +688,189 @@ export const useBullFlashWithdraw = () => { return flashWithdrawFromBull } + +export const useSetQueuedBullUserState = () => { + const bullNettingContract = useAtomValue(bullNettingContractAtom) + const address = useAtomValue(addressAtom) + + const setNettingAuctionLive = useSetAtom(isNettingAuctionLiveAtom) + const setMinEthAmount = useSetAtom(minEthAmountAtom) + const setMinZenBullAmount = useSetAtom(minZenBullAmountAtom) + const setTotalDeposits = useSetAtom(totalEthQueuedAtom) + const setTotalWithdrawals = useSetAtom(totalZenBullQueuedAtom) + const setEthQueued = useSetAtom(ethQueuedAtom) + const setZenBullQueued = useSetAtom(zenBullQueuedAtom) + + const setQueuedBullUserState = useAppCallback(async () => { + if (!bullNettingContract) return null + + const minEthAmountPromise = bullNettingContract.methods.minEthAmount().call() + const minZenBullAmountPromise = bullNettingContract.methods.minZenBullAmount().call() + const totalDepositsPromise = bullNettingContract.methods.depositsQueued().call() + const totalWithdrawalsPromise = bullNettingContract.methods.withdrawsQueued().call() + + const [minEthAmount, minZenBullAmount, totalDeposits, totalWithdrawals] = await Promise.all([ + minEthAmountPromise, + minZenBullAmountPromise, + totalDepositsPromise, + totalWithdrawalsPromise, + ]) + + setMinEthAmount(new BigNumber(minEthAmount)) + setMinZenBullAmount(new BigNumber(minZenBullAmount)) + setTotalDeposits(toTokenAmount(totalDeposits, USDC_DECIMALS)) + setTotalWithdrawals(toTokenAmount(totalWithdrawals, WETH_DECIMALS)) + + if (!address) return null + + const ethBalancePromise = bullNettingContract.methods.ethBalance(address).call() + const zenBullBalancePromise = bullNettingContract.methods.zenBullBalance(address).call() + const auctionStatusPromise = bullNettingContract.methods.isAuctionLive().call() + + const [ethQueued, zenBullQueued, auctionStatus] = await Promise.all([ + ethBalancePromise, + zenBullBalancePromise, + auctionStatusPromise, + ]) + setEthQueued(new BigNumber(ethQueued)) + setZenBullQueued(new BigNumber(zenBullQueued)) + setNettingAuctionLive(auctionStatus) + }, [address, bullNettingContract]) + + return setQueuedBullUserState +} + +export const useQueueDepositEth = () => { + const contract = useAtomValue(bullNettingContractAtom) + const handleTransaction = useHandleTransaction() + const address = useAtomValue(addressAtom) + const { track } = useAmplitude() + const { show: showErrorFeedbackPopup } = usePopup( + GenericErrorPopupConfig('Hi, I am having trouble depositing into zenbull.', 'deposit-stn-zenbull'), + ) + + const depositEth = useAppCallback( + async (amount: BigNumber, dataToTrack?: Record, onTxConfirmed?: () => void) => { + if (!contract) return + track(BULL_EVENTS.DEPOSIT_STN_BULL_CLICK, dataToTrack) + + try { + console.log('Queue:', fromTokenAmount(amount, WETH_DECIMALS).toString()) + await handleTransaction( + contract.methods.queueEth().send({ + from: address, + value: fromTokenAmount(amount, WETH_DECIMALS).toString(), + }), + onTxConfirmed, + ) + track(BULL_EVENTS.DEPOSIT_STN_BULL_SUCCESS, dataToTrack) + } catch (e: any) { + e?.code === REVERTED_TRANSACTION_CODE ? track(BULL_EVENTS.DEPOSIT_STN_BULL_REVERT, dataToTrack) : null + e?.code !== REVERTED_TRANSACTION_CODE ? showErrorFeedbackPopup() : null + track(BULL_EVENTS.DEPOSIT_STN_BULL_FAILED, { code: e?.code, ...dataToTrack }) + console.log(e) + } + }, + [contract, address, handleTransaction, showErrorFeedbackPopup, track], + ) + + return depositEth +} + +export const useQueueWithdrawZenBull = () => { + const contract = useAtomValue(bullNettingContractAtom) + const handleTransaction = useHandleTransaction() + const address = useAtomValue(addressAtom) + const { track } = useAmplitude() + const { show: showErrorFeedbackPopup } = usePopup( + GenericErrorPopupConfig('Hi, I am having trouble withdrawing from zenbull.', 'withdraw-stn-zenbull'), + ) + + const queueWithdraw = useAppCallback( + async (amount: BigNumber, dataToTrack?: Record, onTxConfirmed?: () => void) => { + if (!contract) return + + track(BULL_EVENTS.WITHDRAW_STN_BULL_CLICK, dataToTrack) + console.log('Queue: withdraw', fromTokenAmount(amount, ZENBULL_TOKEN_DECIMALS).toString()) + try { + await handleTransaction( + contract.methods.queueZenBull(fromTokenAmount(amount, ZENBULL_TOKEN_DECIMALS).toFixed(0)).send({ + from: address, + }), + onTxConfirmed, + ) + track(BULL_EVENTS.WITHDRAW_STN_BULL_SUCCESS, dataToTrack) + } catch (e: any) { + e?.code === REVERTED_TRANSACTION_CODE ? track(BULL_EVENTS.WITHDRAW_STN_BULL_REVERT, dataToTrack) : null + e?.code !== REVERTED_TRANSACTION_CODE ? showErrorFeedbackPopup() : null + track(BULL_EVENTS.WITHDRAW_STN_BULL_FAILED, { code: e?.code, ...dataToTrack }) + console.log(e) + } + }, + [contract, address, handleTransaction, showErrorFeedbackPopup, track], + ) + + return queueWithdraw +} + +export const useDequeueDepositEth = () => { + const contract = useAtomValue(bullNettingContractAtom) + const handleTransaction = useHandleTransaction() + const address = useAtomValue(addressAtom) + const { track } = useAmplitude() + + const dequeueEth = useAppCallback( + async (amount: BigNumber, onTxConfirmed?: () => void) => { + if (!contract) return + + try { + track(BULL_EVENTS.CANCEL_DEPOSIT_STN_BULL_CLICK) + await handleTransaction( + contract.methods.dequeueEth(amount.toString(), false).send({ + from: address, + }), + onTxConfirmed, + ) + track(BULL_EVENTS.CANCEL_DEPOSIT_STN_BULL_SUCCESS, { amount: amount.toNumber() }) + } catch (e: any) { + e?.code === REVERTED_TRANSACTION_CODE ? track(BULL_EVENTS.CANCEL_DEPOSIT_STN_BULL_REJECT) : null + track(BULL_EVENTS.CANCEL_DEPOSIT_STN_BULL_FAILED, { code: e?.code }) + console.log(e) + } + }, + [contract, address, handleTransaction, track], + ) + + return dequeueEth +} + +export const useDequeueWithdrawZenBull = () => { + const contract = useAtomValue(bullNettingContractAtom) + const handleTransaction = useHandleTransaction() + const address = useAtomValue(addressAtom) + const { track } = useAmplitude() + + const queueWithdraw = useAppCallback( + async (amount: BigNumber, onTxConfirmed?: () => void) => { + if (!contract) return + + try { + track(BULL_EVENTS.CANCEL_WITHDRAW_STN_BULL_CLICK) + await handleTransaction( + contract.methods.dequeueZenBull(amount.toFixed(0), false).send({ + from: address, + }), + onTxConfirmed, + ) + track(BULL_EVENTS.CANCEL_WITHDRAW_STN_BULL_SUCCESS, { amount: amount.toNumber() }) + } catch (e: any) { + e?.code === REVERTED_TRANSACTION_CODE ? track(BULL_EVENTS.CANCEL_WITHDRAW_STN_BULL_REJECT) : null + track(BULL_EVENTS.CANCEL_WITHDRAW_STN_BULL_FAILED, { code: e?.code }) + console.log(e) + } + }, + [contract, address, handleTransaction, track], + ) + + return queueWithdraw +} diff --git a/packages/frontend/src/state/contracts/atoms.ts b/packages/frontend/src/state/contracts/atoms.ts index f7cc8a5be..191198bc9 100644 --- a/packages/frontend/src/state/contracts/atoms.ts +++ b/packages/frontend/src/state/contracts/atoms.ts @@ -14,6 +14,7 @@ import crabMigrationAbi from '../../abis/crabMigration.json' import quoterAbi from '../../abis/quoter.json' import crabHelperAbi from '../../abis/crabHelper.json' import crabNettingAbi from '../../abis/crabNetting.json' +import bullNettingAbi from '../../abis/bullNetting.json' import flashBullAbi from '../../abis/flashBullStrategy.json' import bullStrategyAbi from '../../abis/bullStrategy.json' import eTokenAbi from '../../abis/eulerEToken.json' @@ -147,3 +148,10 @@ export const eulerLensContractAtom = atom((get) => { if (!web3) return null return getContract(web3, eulerSimpleLens, eulerSimpleLensAbi) }) + +export const bullNettingContractAtom = atom((get) => { + const web3 = get(web3Atom) + const { bullNetting } = get(addressesAtom) + if (!web3) return null + return getContract(web3, bullNetting, bullNettingAbi) +}) diff --git a/packages/frontend/src/state/crab/hooks.ts b/packages/frontend/src/state/crab/hooks.ts index 65842811c..89c2e7371 100644 --- a/packages/frontend/src/state/crab/hooks.ts +++ b/packages/frontend/src/state/crab/hooks.ts @@ -1148,7 +1148,7 @@ export const useQueuedCrabPositionAndStatus = () => { setMinUSDCAmount(new BigNumber(minUSDCAmount)) setMinCrabAmount(new BigNumber(minCrabAmount)) - if (!contract || !address) return + if (!address) return const usdcPromise = contract.methods.usdBalance(address).call() const crabPromise = contract.methods.crabBalance(address).call() diff --git a/packages/frontend/src/state/positions/atoms.ts b/packages/frontend/src/state/positions/atoms.ts index 31dea5dc5..594687b96 100644 --- a/packages/frontend/src/state/positions/atoms.ts +++ b/packages/frontend/src/state/positions/atoms.ts @@ -24,6 +24,7 @@ import { CRAB_NETTING, FLASH_BULL_STRATEGY, BULL_STRATEGY, + BULL_NETTING, WETH_E_TOKEN, AUCTION_BULL, EULER_SIMPLE_LENS, @@ -70,6 +71,7 @@ export const addressesAtom = atom((get) => { crabNetting: CRAB_NETTING[networkId].toLowerCase(), flashBull: FLASH_BULL_STRATEGY[networkId].toLowerCase(), bullStrategy: BULL_STRATEGY[networkId].toLowerCase(), + bullNetting: BULL_NETTING[networkId].toLowerCase(), wethEToken: WETH_E_TOKEN[networkId].toLowerCase(), auctionBull: AUCTION_BULL[networkId].toLowerCase(), eulerSimpleLens: EULER_SIMPLE_LENS[networkId].toLowerCase(), diff --git a/packages/frontend/src/utils/amplitude.ts b/packages/frontend/src/utils/amplitude.ts index b0def647c..d70315cf0 100644 --- a/packages/frontend/src/utils/amplitude.ts +++ b/packages/frontend/src/utils/amplitude.ts @@ -39,19 +39,38 @@ export enum BULL_EVENTS { DEPOSIT_BULL_AMOUNT_ENTERED = 'DEPOSIT_BULL_AMOUNT_ENTERED', DEPOSIT_BULL_CLICK = 'DEPOSIT_BULL_CLICK', DEPOSIT_BULL_SUCCESS = 'DEPOSIT_BULL_SUCCESS', - DEPOSIT_BULL_FAILED = 'DEPOSIT_BULL_FAILED', DEPOSIT_BULL_REVERT = 'DEPOSIT_BULL_REVERT', + DEPOSIT_BULL_FAILED = 'DEPOSIT_BULL_FAILED', WITHDRAW_BULL_AMOUNT_ENTERED = 'WITHDRAW_BULL_AMOUNT_ENTERED', WITHDRAW_BULL_CLICK = 'WITHDRAW_BULL_CLICK', WITHDRAW_BULL_SUCCESS = 'WITHDRAW_BULL_SUCCESS', - WITHDRAW_BULL_FAILED = 'WITHDRAW_BULL_FAILED', WITHDRAW_BULL_REVERT = 'WITHDRAW_BULL_REVERT', + WITHDRAW_BULL_FAILED = 'WITHDRAW_BULL_FAILED', + DEPOSIT_STN_BULL_CLICK = 'DEPOSIT_STN_BULL_CLICK', + DEPOSIT_STN_BULL_SUCCESS = 'DEPOSIT_STN_BULL_SUCCESS', + DEPOSIT_STN_BULL_REVERT = 'DEPOSIT_STN_BULL_REVERT', + DEPOSIT_STN_BULL_FAILED = 'DEPOSIT_STN_BULL_FAILED', + CANCEL_DEPOSIT_STN_BULL_CLICK = 'CANCEL_DEPOSIT_STN_BULL_CLICK', + CANCEL_DEPOSIT_STN_BULL_SUCCESS = 'CANCEL_DEPOSIT_STN_BULL_SUCCESS', + CANCEL_DEPOSIT_STN_BULL_REJECT = 'CANCEL_DEPOSIT_STN_BULL_REJECT', + CANCEL_DEPOSIT_STN_BULL_FAILED = 'CANCEL_DEPOSIT_STN_BULL_FAILED', + WITHDRAW_STN_BULL_CLICK = 'WITHDRAW_STN_BULL_CLICK', + WITHDRAW_STN_BULL_SUCCESS = 'WITHDRAW_STN_BULL_SUCCESS', + WITHDRAW_STN_BULL_REVERT = 'WITHDRAW_STN_BULL_REVERT', + WITHDRAW_STN_BULL_FAILED = 'WITHDRAW_STN_BULL_FAILED', + CANCEL_WITHDRAW_STN_BULL_CLICK = 'CANCEL_WITHDRAW_STN_BULL_CLICK', + CANCEL_WITHDRAW_STN_BULL_SUCCESS = 'CANCEL_WITHDRAW_STN_BULL_SUCCESS', + CANCEL_WITHDRAW_STN_BULL_REJECT = 'CANCEL_WITHDRAW_STN_BULL_REJECT', + CANCEL_WITHDRAW_STN_BULL_FAILED = 'CANCEL_WITHDRAW_STN_BULL_FAILED', + USER_FORCE_INSTANT_DEP_BULL = 'USER_FORCE_INSTANT_DEP_BULL', + USER_FORCE_INSTANT_WIT_BULL = 'USER_FORCE_INSTANT_WIT_BULL', APPROVE_WITHDRAW_BULL = 'APPROVE_WITHDRAW_BULL', + APPROVE_WITHDRAW_STN_BULL = 'APPROVE_WITHDRAW_STN_BULL', DEPOSIT_BULL_WRONG_GAS = 'DEPOSIT_BULL_WRONG_GAS', WITHDRAW_BULL_WRONG_GAS = 'WITHDRAW_BULL_WRONG_GAS', DEPOSIT_BULL_SET_AMOUNT_MAX = 'DEPOSIT_BULL_SET_AMOUNT_MAX', - WITHDRAW_BULL_SET_AMOUNT_MAX = 'WITHDRAW_BULL_SET_AMOUNT_MAX', DEPOSIT_BULL_CHANGE_SLIPPAGE = 'DEPOSIT_BULL_CHANGE_SLIPPAGE', + WITHDRAW_BULL_SET_AMOUNT_MAX = 'WITHDRAW_BULL_SET_AMOUNT_MAX', WITHDRAW_BULL_CHANGE_SLIPPAGE = 'WITHDRAW_BULL_CHANGE_SLIPPAGE', } diff --git a/packages/subgraph/config/goerli-config.json b/packages/subgraph/config/goerli-config.json index 5740579b5..aceb85347 100644 --- a/packages/subgraph/config/goerli-config.json +++ b/packages/subgraph/config/goerli-config.json @@ -51,5 +51,7 @@ "ZenEmergencyShutdown": "0x14386333EFa3354c1cF39A38a9c9E372A4bC8c36", "ZenEmergencyShutdown-start-block": 8145337, "FlashZen": "0x3876aF971560FD4c4ba3FB18632AcC0570B745b1", - "FlashZen-start-block": 8145337 + "FlashZen-start-block": 8145337, + "ZenBullNetting": "0x30ba683c45c8b14601ec32759134b7662cef7d93", + "ZenBullNetting-start-block": 8413668 } \ No newline at end of file diff --git a/packages/subgraph/src/bullStrategy.ts b/packages/subgraph/src/bullStrategy.ts index 296ee3219..5670c32a0 100644 --- a/packages/subgraph/src/bullStrategy.ts +++ b/packages/subgraph/src/bullStrategy.ts @@ -36,8 +36,8 @@ import { Strategy, FullRebalance as FullRebalanceSchema } from "../generated/schema" -import * as WETH9 from "../generated/Weth/Weth" -import { Address, BigInt, ByteArray, Bytes, ethereum, log } from "@graphprotocol/graph-ts" +import { EthDeposited, ZenBullWithdrawn } from '../generated/ZenBullNetting/ZenBullNetting' +import { BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts" import { loadOrCreateStrategy } from "./util" import { AUCTION_BULL, FLASH_BULL_ADDR, WETH } from "./constants" @@ -320,3 +320,28 @@ function findFlashBullEthDeposited(event: FlashDeposit): BigInt { return event.params.ethDeposited.minus(returnedAmount) } + +export function handleNettingDeposit(event: EthDeposited): void { + const userTx = loadOrCreateTx(`${event.transaction.hash.toHex()}-${event.logIndex.toString()}`) + + userTx.ethAmount = event.params.ethAmount + userTx.bullAmount = event.params.zenBullAmount + userTx.user = event.params.depositor + userTx.owner = event.params.depositor + userTx.type = 'OTC_DEPOSIT' + userTx.timestamp = event.block.timestamp + userTx.excessEth = event.params.refundedETH + userTx.save() +} + +export function handleNettingWithdraw(event: ZenBullWithdrawn): void { + const userTx = loadOrCreateTx(`${event.transaction.hash.toHex()}-${event.logIndex.toString()}`) + + userTx.bullAmount = event.params.zenBullAmount + userTx.ethAmount = event.params.ethAmount + userTx.user = event.params.withdrawer + userTx.owner = event.params.withdrawer + userTx.type = 'OTC_WITHDRAW' + userTx.timestamp = event.block.timestamp + userTx.save() +} diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index a68258441..230dc7791 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -309,6 +309,28 @@ dataSources: - event: Transfer(indexed address,indexed address,uint256) handler: handleTransfer file: ./src/bullStrategy.ts + - kind: ethereum/contract + name: ZenBullNetting + network: {{network}} + source: + address: "{{ZenBullNetting}}" + abi: ZenBullNetting + startBlock: {{ZenBullNetting-start-block}} + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Strategy + abis: + - name: ZenBullNetting + file: ./abis/ZenBullNetting.json + eventHandlers: + - event: EthDeposited(indexed address,uint256,uint256,indexed uint256,uint256) + handler: handleNettingDeposit + - event: ZenBullWithdrawn(indexed address,uint256,uint256,indexed uint256) + handler: handleNettingWithdraw + file: ./src/bullStrategy.ts - kind: ethereum/contract name: ZenAuction network: {{network}} diff --git a/packages/zen-bull-netting/script/GoerliDeployScript.s.sol b/packages/zen-bull-netting/script/GoerliDeployScript.s.sol index ef338baaa..5840c4b29 100644 --- a/packages/zen-bull-netting/script/GoerliDeployScript.s.sol +++ b/packages/zen-bull-netting/script/GoerliDeployScript.s.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.13; import { DeployScript } from "./DeployScript.s.sol"; contract GoerliDeployScript is DeployScript { - address public constant ownerAddress = 0xE3Dc747E5A8D8B664Dd701EE6A72AE63e740Ebc6; + address public constant ownerAddress = 0x56a847c21a4FA937c11258d94C8B1650cdbA21F7; address public constant zenBullAddress = 0x2a5AD7582a9e42944Ee32671436593D16999c70a; address public constant eulerSimpleLensAddress = 0x62626a0f051B547b3182e55D1Eba667138790D8D; address public constant flashZenAddress = 0x3876aF971560FD4c4ba3FB18632AcC0570B745b1; diff --git a/packages/zen-bull-netting/script/GoerliDeployScript.sol b/packages/zen-bull-netting/script/GoerliDeployScript.sol new file mode 100644 index 000000000..5840c4b29 --- /dev/null +++ b/packages/zen-bull-netting/script/GoerliDeployScript.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import { DeployScript } from "./DeployScript.s.sol"; + +contract GoerliDeployScript is DeployScript { + address public constant ownerAddress = 0x56a847c21a4FA937c11258d94C8B1650cdbA21F7; + address public constant zenBullAddress = 0x2a5AD7582a9e42944Ee32671436593D16999c70a; + address public constant eulerSimpleLensAddress = 0x62626a0f051B547b3182e55D1Eba667138790D8D; + address public constant flashZenAddress = 0x3876aF971560FD4c4ba3FB18632AcC0570B745b1; + address public constant uniFactoryAddress = 0x55C0ceF3cc64F511C34b18c720bCf38feC6C6fFa; + + uint256 public constant initialMinEthAmount = 1e18; + uint256 public constant initialMinZenBullAmount = 1; + + constructor() + DeployScript( + ownerAddress, + zenBullAddress, + eulerSimpleLensAddress, + flashZenAddress, + uniFactoryAddress, + initialMinEthAmount, + initialMinZenBullAmount + ) + { } +} diff --git a/yarn.lock b/yarn.lock index ba7ba7737..a99f2c154 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22317,8 +22317,6 @@ set-interval-async@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/set-interval-async/-/set-interval-async-2.0.3.tgz#8d9e4904deaf8406fd98219c67fd9ef469f5fae2" integrity sha512-8jJgvnhQYQc+XHzyKuJ2g4/0h4jPcT/q3x9VURk+AZohRKpcggcueNhPbS7wOXnamgpAn/enbGl4OnWXurVafg== - dependencies: - "@babel/runtime" "7.5.0" set-value@^2.0.0, set-value@^2.0.1: version "2.0.1"