From 47ed5b0ab5e92a7894741d0609312b14e841d95a Mon Sep 17 00:00:00 2001 From: Oleh-Zorin Date: Sat, 21 Sep 2024 12:45:38 +0300 Subject: [PATCH] Frontend for treasury transfer status (#137) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * cancel transfer component * mock data for status transfer * added status transfer * new treasury_abi * render live transfers * logical cancel transfer * Fix 'There are no transfers' bug * fix condition * fix * deleted unused file * added handler click token_addr or receiver * Format * Remove refetch --------- Co-authored-by: Ondřej Sojka --- frontend/src/App.tsx | 3 +- frontend/src/components/CancelTransferBtn.tsx | 41 + frontend/src/components/StatusTransfer.tsx | 122 +++ frontend/src/lib/config.ts | 3 +- frontend/src/lib/treasury_abi.json | 892 ++++++++++++++++++ 5 files changed, 1059 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/CancelTransferBtn.tsx create mode 100644 frontend/src/components/StatusTransfer.tsx create mode 100644 frontend/src/lib/treasury_abi.json diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 4283fcfd..7bfb1ca9 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -10,6 +10,7 @@ import { CONTRACT_ADDR } from "./lib/config"; import SubmitProposalModal from "./components/SubmitProposalModal"; import TreasuryStatus from "./components/TreasuryStatus"; import VotingPower from "./components/staking/VotingPower"; +import StatusTransfer from './components/StatusTransfer' function App() { const [isModalOpen, setIsModalOpen] = React.useState(false); @@ -70,7 +71,7 @@ function App() { - + {address && } ); diff --git a/frontend/src/components/CancelTransferBtn.tsx b/frontend/src/components/CancelTransferBtn.tsx new file mode 100644 index 00000000..df3764e3 --- /dev/null +++ b/frontend/src/components/CancelTransferBtn.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { useContractWrite } from "@starknet-react/core"; +import { TREASURY_ADDRESS } from "../lib/config"; +import { Contract } from "starknet"; +import TreasuryABI from "../lib/treasury_abi.json"; + +interface CancelTransferButtonProps { + transferId: number; +} + +const CancelTransferBtn: React.FC = ({ transferId }) => { + + const contract = new Contract(TreasuryABI, TREASURY_ADDRESS) + + const { writeAsync, error } = useContractWrite({ + calls: [ + contract.populateTransaction["cancel_transfer"](transferId) + ], + }); + + const handleCancelTransfer = async () => { + try { + await writeAsync(); + console.log(`Transfer ${transferId} cancelled successfully.`); + } catch (err) { + console.error(`Error cancelling transfer ${transferId}:`, err); + console.error(`Error write ${transferId}:`, error); + } + }; + + return ( + + ); +}; + +export default CancelTransferBtn; \ No newline at end of file diff --git a/frontend/src/components/StatusTransfer.tsx b/frontend/src/components/StatusTransfer.tsx new file mode 100644 index 00000000..3441e660 --- /dev/null +++ b/frontend/src/components/StatusTransfer.tsx @@ -0,0 +1,122 @@ +import React from "react"; +import { + useAccount, + useContractRead, useNetwork +} from "@starknet-react/core"; +import TreasuryABI from "../lib/treasury_abi.json"; +import CancelTransferBtn from "./CancelTransferBtn"; +import { formatBalance } from "../lib/erc20"; +import { TREASURY_ADDRESS } from "../lib/config"; + +const StatusTransfer = () => { + const { address } = useAccount() + const { data, isLoading } = useContractRead({ + functionName: 'get_live_transfers', + address: TREASURY_ADDRESS, + args: [], + abi: TreasuryABI, + watch: false, + retry: false + }) + + const renderCancelBtn = (status, transfer_id) => + getTransferStatus(status) == 'PENDING' && address && + + + const { chain: { network } } = useNetwork() + + const handleAddress = address => { + const sub_domain = network === 'sepolia' ? 'sepolia.' : '' + const url = `https://${sub_domain}starkscan.co/contract/${getAddressToHex(address)}` + window.open(`${url}`, '_blank') + } + + const renderData = () => { + if (Array.isArray(data)) { + if (data.length === 0) { + return
There are no transfers
; + } + + return data.map((transfer_item, index) => { + + return ( +
+
+
token
+
receiver
+
handleAddress(transfer_item.token_addr)}>{getFormatAddress(transfer_item.token_addr.toString())}
+
handleAddress(transfer_item.receiver)}>{getFormatAddress(transfer_item.receiver.toString())}
+
+
+
amount
+
cooldown_end
+
status
+
actions
+
{formatBalance(transfer_item.amount.toString())}
+
{getHoursLeft(transfer_item.cooldown_end.toString())}
+
{getTransferStatus(transfer_item.status)}
+
+ {renderCancelBtn(transfer_item?.status, transfer_item?.id)} +
+
+ +
+ ) + }) + } else { + return null + } + } + + return ( +
+
Transfer status
+ {isLoading ? ( +
Loading...
+ ) : ( +
+
+ +
+ {renderData()} +
+
+
+ )} +
+ ) +} + +const getHoursLeft = (target_date: number): string => { + const targetTimestamp = Number(target_date) * 1000; + const currentTimestamp = Date.now(); + + const timeLeft = targetTimestamp - currentTimestamp; + if (timeLeft > 0) { + const secondsLeft = Math.floor(timeLeft / 1000); + const minutesLeft = Math.floor(secondsLeft / 60); + const hoursLeft = Math.floor(minutesLeft / 60); + return `hours ${hoursLeft} left`; + } else { + return 'expired'; + } +}; + +const getTransferStatus = status => { + if (status?.variant?.PENDING) { + return 'PENDING' + } + if (status?.variant?.CANCELLED) { + return 'CANCELLED' + } + if (status?.variant?.FINISHED) { + return 'FINISHED' + } + +} + +const getFormatAddress = address => address.slice(0, 12) + "..." + address.slice(-4) +const getAddressToHex = address => "0x" + address.toString(16) + + +export default StatusTransfer \ No newline at end of file diff --git a/frontend/src/lib/config.ts b/frontend/src/lib/config.ts index 05e22397..469a5ce1 100644 --- a/frontend/src/lib/config.ts +++ b/frontend/src/lib/config.ts @@ -4,7 +4,8 @@ export const CONTRACT_ADDR = export const VOTING_TOKEN_CONTRACT = "0x4ff1af47bb9659aa83bbd33e13c25e8fb1b5ecf8359320251f03e1440e8890a"; export const FLOATING_TOKEN_CONTRACT = "0x31868056874ad7629055ddd00eb0931cb92167851702abf6b441cb8ea02d02b"; -export const TREASURY_ADDRESS = "0x072c5c218a1ecfdd8ba10ef9b1b55af4994f2cad2210d14270ff9824fadabd70"; +// export const TREASURY_ADDRESS = "0x072c5c218a1ecfdd8ba10ef9b1b55af4994f2cad2210d14270ff9824fadabd70"; +export const TREASURY_ADDRESS = "0x039f350d8a6b3adb8ade1ec083284c64f6d3cbaaba3dc27cbfc8ee39ffebc302" export const formatAddress = (addr: string) => addr.length === 66 diff --git a/frontend/src/lib/treasury_abi.json b/frontend/src/lib/treasury_abi.json new file mode 100644 index 00000000..413842f7 --- /dev/null +++ b/frontend/src/lib/treasury_abi.json @@ -0,0 +1,892 @@ +[ + { + "type": "impl", + "name": "Treasury", + "interface_name": "konoha::treasury::ITreasury" + }, + { + "type": "struct", + "name": "core::integer::u256", + "members": [ + { + "name": "low", + "type": "core::integer::u128" + }, + { + "name": "high", + "type": "core::integer::u128" + } + ] + }, + { + "type": "enum", + "name": "konoha::types::TransferStatus", + "variants": [ + { + "name": "PENDING", + "type": "()" + }, + { + "name": "CANCELLED", + "type": "()" + }, + { + "name": "FINISHED", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "konoha::types::Transfer", + "members": [ + { + "name": "id", + "type": "core::integer::u64" + }, + { + "name": "token_addr", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + }, + { + "name": "cooldown_end", + "type": "core::integer::u64" + }, + { + "name": "status", + "type": "konoha::types::TransferStatus" + } + ] + }, + { + "type": "enum", + "name": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "konoha::types::Transfer" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "konoha::treasury::ITreasury", + "items": [ + { + "type": "function", + "name": "add_transfer", + "inputs": [ + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + }, + { + "name": "token_addr", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "konoha::types::Transfer" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_next_pending", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "get_unprocessed_transfers", + "inputs": [], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "get_finished_transfers", + "inputs": [], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "get_live_transfers", + "inputs": [], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "get_cancelled_transfers", + "inputs": [], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "get_transfer_by_id", + "inputs": [ + { + "name": "transfer_id", + "type": "core::integer::u64" + } + ], + "outputs": [ + { + "type": "konoha::types::Transfer" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "cancel_transfer", + "inputs": [ + { + "name": "transfer_id", + "type": "core::integer::u64" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "execute_pending_by_id", + "inputs": [ + { + "name": "transfer_id", + "type": "core::integer::u64" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "add_guardian", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "remove_guardian", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "update_AMM_address", + "inputs": [ + { + "name": "new_amm_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "provide_liquidity_to_carm_AMM", + "inputs": [ + { + "name": "pooled_token_addr", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "quote_token_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "base_token_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "option_type", + "type": "core::felt252" + }, + { + "name": "amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "withdraw_liquidity", + "inputs": [ + { + "name": "pooled_token_addr", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "quote_token_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "base_token_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "option_type", + "type": "core::felt252" + }, + { + "name": "lp_token_amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_amm_address", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "deposit_to_zklend", + "inputs": [ + { + "name": "token", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "withdraw_from_zklend", + "inputs": [ + { + "name": "token", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "deposit_to_nostra_lending_pool", + "inputs": [ + { + "name": "token", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "nostraToken", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "withdraw_from_nostra_lending_pool", + "inputs": [ + { + "name": "nostraToken", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "UpgradeableImpl", + "interface_name": "openzeppelin::upgrades::interface::IUpgradeable" + }, + { + "type": "interface", + "name": "openzeppelin::upgrades::interface::IUpgradeable", + "items": [ + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "OwnableTwoStepImpl", + "interface_name": "openzeppelin::access::ownable::interface::IOwnableTwoStep" + }, + { + "type": "interface", + "name": "openzeppelin::access::ownable::interface::IOwnableTwoStep", + "items": [ + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "pending_owner", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "accept_ownership", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "transfer_ownership", + "inputs": [ + { + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "renounce_ownership", + "inputs": [], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "gov_contract_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "AMM_contract_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "zklend_market_contract_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "first_guardian", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::TokenSent", + "kind": "struct", + "members": [ + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "token_addr", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::TransferCancelled", + "kind": "struct", + "members": [ + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "token_addr", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "initial_amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::TransferPending", + "kind": "struct", + "members": [ + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "token_addr", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::GuardianAdded", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::GuardianRemoved", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::AMMAddressUpdated", + "kind": "struct", + "members": [ + { + "name": "previous_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "new_amm_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::LiquidityProvided", + "kind": "struct", + "members": [ + { + "name": "quote_token_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "base_token_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "option_type", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::LiquidityWithdrawn", + "kind": "struct", + "members": [ + { + "name": "quote_token_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "base_token_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "option_type", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "lp_token_amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::LiquidityProvidedToZklend", + "kind": "struct", + "members": [ + { + "name": "token_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::LiquidityWithdrawnFromZklend", + "kind": "struct", + "members": [ + { + "name": "token_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::LiquidityProvidedToNostraLendingPool", + "kind": "struct", + "members": [ + { + "name": "nostra_token", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::LiquidityWithdrawnFromNostraLendingPool", + "kind": "struct", + "members": [ + { + "name": "nostra_token", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred", + "kind": "struct", + "members": [ + { + "name": "previous_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted", + "kind": "struct", + "members": [ + { + "name": "previous_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "openzeppelin::access::ownable::ownable::OwnableComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "OwnershipTransferred", + "type": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred", + "kind": "nested" + }, + { + "name": "OwnershipTransferStarted", + "type": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "Upgraded", + "type": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "konoha::treasury::Treasury::Event", + "kind": "enum", + "variants": [ + { + "name": "TokenSent", + "type": "konoha::treasury::Treasury::TokenSent", + "kind": "nested" + }, + { + "name": "TransferCancelled", + "type": "konoha::treasury::Treasury::TransferCancelled", + "kind": "nested" + }, + { + "name": "TransferPending", + "type": "konoha::treasury::Treasury::TransferPending", + "kind": "nested" + }, + { + "name": "GuardianAdded", + "type": "konoha::treasury::Treasury::GuardianAdded", + "kind": "nested" + }, + { + "name": "GuardianRemoved", + "type": "konoha::treasury::Treasury::GuardianRemoved", + "kind": "nested" + }, + { + "name": "AMMAddressUpdated", + "type": "konoha::treasury::Treasury::AMMAddressUpdated", + "kind": "nested" + }, + { + "name": "LiquidityProvided", + "type": "konoha::treasury::Treasury::LiquidityProvided", + "kind": "nested" + }, + { + "name": "LiquidityWithdrawn", + "type": "konoha::treasury::Treasury::LiquidityWithdrawn", + "kind": "nested" + }, + { + "name": "LiquidityProvidedToZklend", + "type": "konoha::treasury::Treasury::LiquidityProvidedToZklend", + "kind": "nested" + }, + { + "name": "LiquidityWithdrawnFromZklend", + "type": "konoha::treasury::Treasury::LiquidityWithdrawnFromZklend", + "kind": "nested" + }, + { + "name": "LiquidityProvidedToNostraLendingPool", + "type": "konoha::treasury::Treasury::LiquidityProvidedToNostraLendingPool", + "kind": "nested" + }, + { + "name": "LiquidityWithdrawnFromNostraLendingPool", + "type": "konoha::treasury::Treasury::LiquidityWithdrawnFromNostraLendingPool", + "kind": "nested" + }, + { + "name": "OwnableEvent", + "type": "openzeppelin::access::ownable::ownable::OwnableComponent::Event", + "kind": "flat" + }, + { + "name": "UpgradeableEvent", + "type": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event", + "kind": "flat" + } + ] + } +] \ No newline at end of file