diff --git a/src/abi/CoolerClearingHouseV3.json b/src/abi/CoolerClearingHouseV3.json new file mode 100644 index 0000000000..375b1c8002 --- /dev/null +++ b/src/abi/CoolerClearingHouseV3.json @@ -0,0 +1,780 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "ohm_", + "type": "address" + }, + { + "internalType": "address", + "name": "gohm_", + "type": "address" + }, + { + "internalType": "address", + "name": "staking_", + "type": "address" + }, + { + "internalType": "address", + "name": "sReserve_", + "type": "address" + }, + { + "internalType": "address", + "name": "coolerFactory_", + "type": "address" + }, + { + "internalType": "address", + "name": "kernel_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BadEscrow", + "type": "error" + }, + { + "inputs": [], + "name": "DurationMaximum", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "caller_", + "type": "address" + } + ], + "name": "KernelAdapter_OnlyKernel", + "type": "error" + }, + { + "inputs": [], + "name": "LengthDiscrepancy", + "type": "error" + }, + { + "inputs": [], + "name": "NotLender", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyBorrower", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyBurnable", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyFromFactory", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Keycode", + "name": "keycode_", + "type": "bytes5" + } + ], + "name": "Policy_ModuleDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "expected_", + "type": "bytes" + } + ], + "name": "Policy_WrongModuleVersion", + "type": "error" + }, + { + "inputs": [], + "name": "TooEarlyToFund", + "type": "error" + }, + { + "anonymous": false, + "inputs": [], + "name": "Activate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Deactivate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Defund", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "defund", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserveAmount", + "type": "uint256" + } + ], + "name": "Rebalance", + "type": "event" + }, + { + "inputs": [], + "name": "CHREG", + "outputs": [ + { + "internalType": "contract CHREGv1", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FUND_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FUND_CADENCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INTEREST_RATE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOAN_TO_COLLATERAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REWARD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTR", + "outputs": [ + { + "internalType": "contract MINTRv1", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ROLES", + "outputs": [ + { + "internalType": "contract ROLESv1", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TRSRY", + "outputs": [ + { + "internalType": "contract TRSRYv1", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "uint8", + "name": "major", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "minor", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "active", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Kernel", + "name": "newKernel_", + "type": "address" + } + ], + "name": "changeKernel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "coolers_", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "loans_", + "type": "uint256[]" + } + ], + "name": "claimDefaulted", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "configureDependencies", + "outputs": [ + { + "internalType": "Keycode[]", + "name": "dependencies", + "type": "bytes5[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "defund", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Cooler", + "name": "cooler_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loanID_", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "times_", + "type": "uint8" + } + ], + "name": "extendLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "contract CoolerFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fundTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "principal_", + "type": "uint256" + } + ], + "name": "getCollateralForLoan", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "collateral_", + "type": "uint256" + } + ], + "name": "getLoanForCollateral", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalReceivables", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gohm", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "principal_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "duration_", + "type": "uint256" + } + ], + "name": "interestForLoan", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "interestReceivables", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isCoolerCallback", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "kernel", + "outputs": [ + { + "internalType": "contract Kernel", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Cooler", + "name": "cooler_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "lendToCooler", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ohm", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loanID_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principle", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interest", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + } + ], + "name": "onDefault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loanID_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principlePaid_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestPaid_", + "type": "uint256" + } + ], + "name": "onRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "principalReceivables", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebalance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requestPermissions", + "outputs": [ + { + "components": [ + { + "internalType": "Keycode", + "name": "keycode", + "type": "bytes5" + }, + { + "internalType": "bytes4", + "name": "funcSelector", + "type": "bytes4" + } + ], + "internalType": "struct Permissions[]", + "name": "requests", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sReserve", + "outputs": [ + { + "internalType": "contract ERC4626", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "contract IStaking", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sweepIntoSavingsVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/src/abi/CoolerFactoryV2.json b/src/abi/CoolerFactoryV2.json index 221815ef9f..13849d98bf 100644 --- a/src/abi/CoolerFactoryV2.json +++ b/src/abi/CoolerFactoryV2.json @@ -1,434 +1,434 @@ { - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "type": "error", - "name": "CreateFail" - }, - { - "inputs": [], - "type": "error", - "name": "DecimalsNot18" - }, - { - "inputs": [], - "type": "error", - "name": "NotFromFactory" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "cooler", - "type": "address", - "indexed": true - }, - { - "internalType": "uint256", - "name": "reqID", - "type": "uint256", - "indexed": false - }, - { - "internalType": "uint256", - "name": "loanID", - "type": "uint256", - "indexed": false - } - ], - "type": "event", - "name": "ClearRequest", - "anonymous": false - }, - { - "inputs": [ - { - "internalType": "address", - "name": "cooler", - "type": "address", - "indexed": true - }, - { - "internalType": "uint256", - "name": "loanID", - "type": "uint256", - "indexed": false - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256", - "indexed": false - } - ], - "type": "event", - "name": "DefaultLoan", - "anonymous": false - }, - { - "inputs": [ - { - "internalType": "address", - "name": "cooler", - "type": "address", - "indexed": true - }, - { - "internalType": "uint256", - "name": "loanID", - "type": "uint256", - "indexed": false - }, - { - "internalType": "uint8", - "name": "times", - "type": "uint8", - "indexed": false - } - ], - "type": "event", - "name": "ExtendLoan", - "anonymous": false - }, - { - "inputs": [ - { - "internalType": "address", - "name": "cooler", - "type": "address", - "indexed": true - }, - { - "internalType": "uint256", - "name": "loanID", - "type": "uint256", - "indexed": false - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256", - "indexed": false - } - ], - "type": "event", - "name": "RepayLoan", - "anonymous": false - }, - { - "inputs": [ - { - "internalType": "address", - "name": "cooler", - "type": "address", - "indexed": true - }, - { - "internalType": "address", - "name": "collateral", - "type": "address", - "indexed": false - }, - { - "internalType": "address", - "name": "debt", - "type": "address", - "indexed": false - }, - { - "internalType": "uint256", - "name": "reqID", - "type": "uint256", - "indexed": false - } - ], - "type": "event", - "name": "RequestLoan", - "anonymous": false - }, - { - "inputs": [ - { - "internalType": "address", - "name": "cooler", - "type": "address", - "indexed": true - }, - { - "internalType": "uint256", - "name": "reqID", - "type": "uint256", - "indexed": false - } - ], - "type": "event", - "name": "RescindRequest", - "anonymous": false - }, - { - "inputs": [], - "stateMutability": "view", - "type": "function", - "name": "coolerImplementation", - "outputs": [ - { - "internalType": "contract Cooler", - "name": "", - "type": "address" - } - ] - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "", - "type": "address" - }, - { - "internalType": "contract ERC20", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function", - "name": "coolersFor", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ] - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function", - "name": "created", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ] - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "collateral_", - "type": "address" - }, - { - "internalType": "contract ERC20", - "name": "debt_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function", - "name": "generateCooler", - "outputs": [ - { - "internalType": "address", - "name": "cooler", - "type": "address" - } - ] - }, - { - "inputs": [ - { - "internalType": "address", - "name": "user_", - "type": "address" - }, - { - "internalType": "address", - "name": "collateral_", - "type": "address" - }, - { - "internalType": "address", - "name": "debt_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function", - "name": "getCoolerFor", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ] - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "reqID_", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "loanID_", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function", - "name": "logClearRequest" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "loanID_", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "collateral_", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function", - "name": "logDefaultLoan" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "loanID_", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "times_", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function", - "name": "logExtendLoan" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "loanID_", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "repayment_", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function", - "name": "logRepayLoan" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "reqID_", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function", - "name": "logRequestLoan" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "reqID_", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function", - "name": "logRescindRequest" - } - ], - "devdoc": { - "kind": "dev", - "methods": { - "generateCooler(address,address)": { - "params": { - "collateral_": "the token given as collateral.", - "debt_": "the token to be lent. Interest is denominated in debt tokens." - }, - "returns": { - "cooler": "address of the contract." - } + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "type": "error", + "name": "CreateFail" + }, + { + "inputs": [], + "type": "error", + "name": "DecimalsNot18" + }, + { + "inputs": [], + "type": "error", + "name": "NotFromFactory" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cooler", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "reqID", + "type": "uint256", + "indexed": false + }, + { + "internalType": "uint256", + "name": "loanID", + "type": "uint256", + "indexed": false } - }, - "version": 1 + ], + "type": "event", + "name": "ClearRequest", + "anonymous": false }, - "userdoc": { - "kind": "user", - "methods": { - "coolerImplementation()": { - "notice": "Cooler reference implementation (deployed on creation to clone from)." + { + "inputs": [ + { + "internalType": "address", + "name": "cooler", + "type": "address", + "indexed": true }, - "coolersFor(address,address,uint256)": { - "notice": "Mapping to query Coolers for Collateral-Debt pair." + { + "internalType": "uint256", + "name": "loanID", + "type": "uint256", + "indexed": false }, - "created(address)": { - "notice": "Mapping to validate deployed coolers." + { + "internalType": "uint256", + "name": "amount", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "DefaultLoan", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cooler", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "loanID", + "type": "uint256", + "indexed": false + }, + { + "internalType": "uint8", + "name": "times", + "type": "uint8", + "indexed": false + } + ], + "type": "event", + "name": "ExtendLoan", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cooler", + "type": "address", + "indexed": true }, - "generateCooler(address,address)": { - "notice": "creates a new Escrow contract for collateral and debt tokens." + { + "internalType": "uint256", + "name": "loanID", + "type": "uint256", + "indexed": false }, - "getCoolerFor(address,address,address)": { - "notice": "Getter function to get an existing cooler for a given user <> collateral <> debt combination." + { + "internalType": "uint256", + "name": "amount", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "RepayLoan", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cooler", + "type": "address", + "indexed": true }, - "logClearRequest(uint256,uint256)": { - "notice": "Emit a global event when a loan request is fulfilled." + { + "internalType": "address", + "name": "collateral", + "type": "address", + "indexed": false }, - "logDefaultLoan(uint256,uint256)": { - "notice": "Emit a global event when the collateral of defaulted loan is claimed." + { + "internalType": "address", + "name": "debt", + "type": "address", + "indexed": false }, - "logExtendLoan(uint256,uint8)": { - "notice": "Emit a global event when a loan is extended." + { + "internalType": "uint256", + "name": "reqID", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "RequestLoan", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cooler", + "type": "address", + "indexed": true }, - "logRepayLoan(uint256,uint256)": { - "notice": "Emit a global event when a loan is repaid." + { + "internalType": "uint256", + "name": "reqID", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "RescindRequest", + "anonymous": false + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "coolerImplementation", + "outputs": [ + { + "internalType": "contract Cooler", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" }, - "logRequestLoan(uint256)": { - "notice": "Emit a global event when a new loan request is created." + { + "internalType": "contract ERC20", + "name": "", + "type": "address" }, - "logRescindRequest(uint256)": { - "notice": "Emit a global event when a loan request is rescinded." + { + "internalType": "uint256", + "name": "", + "type": "uint256" } - }, - "version": 1 + ], + "stateMutability": "view", + "type": "function", + "name": "coolersFor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "created", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "collateral_", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "debt_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "generateCooler", + "outputs": [ + { + "internalType": "address", + "name": "cooler", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "address", + "name": "collateral_", + "type": "address" + }, + { + "internalType": "address", + "name": "debt_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getCoolerFor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reqID_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "loanID_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "logClearRequest" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loanID_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateral_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "logDefaultLoan" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loanID_", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "times_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "logExtendLoan" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loanID_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "repayment_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "logRepayLoan" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reqID_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "logRequestLoan" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reqID_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "logRescindRequest" } - } \ No newline at end of file + ], + "devdoc": { + "kind": "dev", + "methods": { + "generateCooler(address,address)": { + "params": { + "collateral_": "the token given as collateral.", + "debt_": "the token to be lent. Interest is denominated in debt tokens." + }, + "returns": { + "cooler": "address of the contract." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "coolerImplementation()": { + "notice": "Cooler reference implementation (deployed on creation to clone from)." + }, + "coolersFor(address,address,uint256)": { + "notice": "Mapping to query Coolers for Collateral-Debt pair." + }, + "created(address)": { + "notice": "Mapping to validate deployed coolers." + }, + "generateCooler(address,address)": { + "notice": "creates a new Escrow contract for collateral and debt tokens." + }, + "getCoolerFor(address,address,address)": { + "notice": "Getter function to get an existing cooler for a given user <> collateral <> debt combination." + }, + "logClearRequest(uint256,uint256)": { + "notice": "Emit a global event when a loan request is fulfilled." + }, + "logDefaultLoan(uint256,uint256)": { + "notice": "Emit a global event when the collateral of defaulted loan is claimed." + }, + "logExtendLoan(uint256,uint8)": { + "notice": "Emit a global event when a loan is extended." + }, + "logRepayLoan(uint256,uint256)": { + "notice": "Emit a global event when a loan is repaid." + }, + "logRequestLoan(uint256)": { + "notice": "Emit a global event when a new loan request is created." + }, + "logRescindRequest(uint256)": { + "notice": "Emit a global event when a loan request is rescinded." + } + }, + "version": 1 + } +} diff --git a/src/assets/tokens/usds.svg b/src/assets/tokens/usds.svg new file mode 100644 index 0000000000..6b0b3139bd --- /dev/null +++ b/src/assets/tokens/usds.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/components/Migration/MigrationModal.tsx b/src/components/Migration/MigrationModal.tsx index 19070f651e..4dbfa27d0d 100644 --- a/src/components/Migration/MigrationModal.tsx +++ b/src/components/Migration/MigrationModal.tsx @@ -112,8 +112,8 @@ function MigrationModal({ open, handleClose }: { open: boolean; handleClose: any isMigrationComplete || !oldAssetsDetected ? `Migration complete` : isAllApproved - ? `You are now ready to migrate` - : `You have assets ready to migrate to v2` + ? `You are now ready to migrate` + : `You have assets ready to migrate to v2` } > <> diff --git a/src/constants/addresses.ts b/src/constants/addresses.ts index a0cde0a4ed..e02363fa40 100644 --- a/src/constants/addresses.ts +++ b/src/constants/addresses.ts @@ -283,6 +283,11 @@ export const COOLER_CLEARING_HOUSE_V2_ADDRESSES = { [NetworkId.TESTNET_GOERLI]: "0xbfe14B5950a530A5CE572Cd2FaC6d44c718A3C47", }; +export const COOLER_CLEARING_HOUSE_V3_ADDRESSES = { + [NetworkId.MAINNET]: "0x1e094fE00E13Fd06D64EeA4FB3cD912893606fE0", + [NetworkId.TESTNET_GOERLI]: "", +}; + export const OLYMPUS_GOVERNANCE_ADDRESSES = { [NetworkId.MAINNET]: "0x0941233c964e7d7Efeb05D253176E5E634cEFfcD", [NetworkId.TESTNET_GOERLI]: "0x0941233c964e7d7Efeb05D253176E5E634cEFfcD", diff --git a/src/constants/contracts.ts b/src/constants/contracts.ts index b6557a9a9c..54d511ec3b 100644 --- a/src/constants/contracts.ts +++ b/src/constants/contracts.ts @@ -6,6 +6,7 @@ import { BOND_FIXED_TERM_TELLER_ADDRESSES, COOLER_CLEARING_HOUSE_V1_ADDRESSES, COOLER_CLEARING_HOUSE_V2_ADDRESSES, + COOLER_CLEARING_HOUSE_V3_ADDRESSES, COOLER_CONSOLIDATION_ADDRESSES, CROSS_CHAIN_BRIDGE_ADDRESSES, CROSS_CHAIN_BRIDGE_ADDRESSES_TESTNET, @@ -29,6 +30,7 @@ import { BondFixedExpiryTeller__factory, BondFixedTermTeller__factory, CoolerClearingHouse__factory, + CoolerClearingHouseV3__factory, CoolerConsolidation__factory, CrossChainBridge__factory, CrossChainBridgeTestnet__factory, @@ -167,6 +169,12 @@ export const COOLER_CLEARING_HOUSE_CONTRACT_V2 = new Contract({ addresses: COOLER_CLEARING_HOUSE_V2_ADDRESSES, }); +export const COOLER_CLEARING_HOUSE_CONTRACT_V3 = new Contract({ + factory: CoolerClearingHouseV3__factory, + name: "Cooler Clearing House Contract V3", + addresses: COOLER_CLEARING_HOUSE_V3_ADDRESSES, +}); + export const GOVERNANCE_CONTRACT = new Contract({ factory: OlympusGovernorBravo__factory, name: "Governance Contract", diff --git a/src/generated/coolerLoans.ts b/src/generated/coolerLoans.ts index 7de9ad75f5..1ecc6c669c 100644 --- a/src/generated/coolerLoans.ts +++ b/src/generated/coolerLoans.ts @@ -46,12 +46,18 @@ export type GetSnapshotsParams = { * Represents the state of the Treasury at the time of the snapshot. */ export type SnapshotTreasury = { - /** Total balance of DAI in the active treasury */ + /** Total balance of the DAI token in the active treasury */ daiBalance: number; - /** Total balance of sDAI in the active treasury */ + /** Total balance of the sDAI token in the active treasury */ sDaiBalance: number; - /** Total balance of sDAI in terms of DAI in the active treasury */ + /** Total balance of the sDAI token in terms of DAI in the active treasury */ sDaiInDaiBalance: number; + /** Total balance of the sUSDS token in the active treasury */ + sUsdsBalance: number; + /** Total balance of the sUSDS token in terms of USDS in the active treasury */ + sUsdsInUsdsBalance: number; + /** Total balance of the USDS token in the active treasury */ + usdsBalance: number; }; /** @@ -86,12 +92,18 @@ export type SnapshotExpiryBuckets = { * Totals for the Clearinghouses at the time of the snapshot. */ export type SnapshotClearinghouseTotals = { - /** Total balance of DAI across all Clearinghouses */ + /** Total balance of the DAI token across all Clearinghouses */ daiBalance: number; - /** Total balance of sDAI across all Clearinghouses */ + /** Total balance of the sDAI token across all Clearinghouses */ sDaiBalance: number; - /** Total balance of sDAI in terms of DAI across all Clearinghouses */ + /** Total balance of the sDAI token in terms of DAI across all Clearinghouses */ sDaiInDaiBalance: number; + /** Total balance of the sUSDS token across all Clearinghouses */ + sUsdsBalance: number; + /** Total balance of the sUSDS token in terms of USDS across all Clearinghouses */ + sUsdsInUsdsBalance: number; + /** Total balance of the USDS token across all Clearinghouses */ + usdsBalance: number; }; export type SnapshotClearinghousesItem = { @@ -101,18 +113,18 @@ export type SnapshotClearinghousesItem = { collateralAddress: string; /** The address of the CoolerFactory */ coolerFactoryAddress: string; - /** Balance of DAI */ - daiBalance: number; /** The address of the debt */ debtAddress: string; - /** Amount of DAI that the Clearinghouse should be funded with */ + /** Amount of the reserve token that the Clearinghouse should be funded with */ fundAmount: number; /** The cadence of the funding */ fundCadence: number; - /** Balance of sDAI */ - sDaiBalance: number; - /** Balance of sDAI in terms of DAI */ - sDaiInDaiBalance: number; + /** Balance of the reserve token */ + reserveBalance: number; + /** Balance of the sReserve token */ + sReserveBalance: number; + /** Balance of the sReserve token in terms of the reserve token */ + sReserveInReserveBalance: number; }; export type Snapshot = { diff --git a/src/helpers/index.tsx b/src/helpers/index.tsx index 9ee68b87ad..ed64c6897b 100644 --- a/src/helpers/index.tsx +++ b/src/helpers/index.tsx @@ -49,7 +49,7 @@ export function formatCurrency(c: number, precision = 0, currency = "USD") { minimumFractionDigits: precision, }).format(c); if (currency === "OHM") return `${formatted} Ω`; - if (currency === "DAI") return `${formatted} DAI`; + if (currency) return `${formatted} ${currency}`; return formatted; } diff --git a/src/hooks/useScreenSize.ts b/src/hooks/useScreenSize.ts index cec601193d..c99985ee35 100644 --- a/src/hooks/useScreenSize.ts +++ b/src/hooks/useScreenSize.ts @@ -5,14 +5,14 @@ export const useScreenSize = (size: "xs" | "sm" | "md" | "lg" | "xl") => { size === "xs" ? "(max-width: 0px)" : size === "sm" - ? "(max-width: 600px)" - : size === "md" - ? "(max-width: 900px)" - : size === "lg" - ? "(max-width: 1200px)" - : size === "xl" - ? "(max-width: 153600px)" - : ""; + ? "(max-width: 600px)" + : size === "md" + ? "(max-width: 900px)" + : size === "lg" + ? "(max-width: 1200px)" + : size === "xl" + ? "(max-width: 153600px)" + : ""; return useMediaQuery(breakpoint); }; diff --git a/src/hooks/useTheme.ts b/src/hooks/useTheme.ts index 5193887e60..d182270f82 100644 --- a/src/hooks/useTheme.ts +++ b/src/hooks/useTheme.ts @@ -26,8 +26,8 @@ const useTheme = (): [string, (e: KeyboardEvent) => void, boolean] => { window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches && !localTheme ? setMode("dark") : localTheme - ? setTheme(localTheme) - : setMode("dark"); + ? setTheme(localTheme) + : setMode("dark"); setMounted(true); }, []); diff --git a/src/views/Bond/components/BondModal/BondModal.tsx b/src/views/Bond/components/BondModal/BondModal.tsx index f9a2a126cb..738c466abb 100644 --- a/src/views/Bond/components/BondModal/BondModal.tsx +++ b/src/views/Bond/components/BondModal/BondModal.tsx @@ -159,8 +159,8 @@ const TokenPrice: React.VFC<{ token: Token; isInverseBond?: boolean; baseSymbol: const price = sameToken ? formatNumber(1, 2) : isInverseBond - ? formatNumber(ohmPrice, 2) - : `${formatNumber(Number(priceToken.toString({ decimals: 2, format: true, trim: false })), 2)}`; + ? formatNumber(ohmPrice, 2) + : `${formatNumber(Number(priceToken.toString({ decimals: 2, format: true, trim: false })), 2)}`; return price ? ( <> {price} {isInverseBond ? baseSymbol : quoteSymbol} diff --git a/src/views/Bond/components/BondModal/components/BondInputArea/BondInputArea.tsx b/src/views/Bond/components/BondModal/components/BondInputArea/BondInputArea.tsx index 5d38d42a6b..eed5abc2d0 100644 --- a/src/views/Bond/components/BondModal/components/BondInputArea/BondInputArea.tsx +++ b/src/views/Bond/components/BondModal/components/BondInputArea/BondInputArea.tsx @@ -195,8 +195,8 @@ export const BondInputArea: React.VFC<{ {isInverseBond ? `${quoteTokenString} (≈${baseTokenString})` : props.bond.baseToken === props.bond.quoteToken - ? `${baseTokenString}` - : `${baseTokenString} (≈${quoteTokenString})`} + ? `${baseTokenString}` + : `${baseTokenString} (≈${quoteTokenString})`} } /> diff --git a/src/views/Bridge/components/BridgeConfirmModal.tsx b/src/views/Bridge/components/BridgeConfirmModal.tsx index dec91af54c..b4f0efcc9b 100644 --- a/src/views/Bridge/components/BridgeConfirmModal.tsx +++ b/src/views/Bridge/components/BridgeConfirmModal.tsx @@ -118,12 +118,14 @@ export const BridgeConfirmModal = (props: { {props.amountExceedsBalance ? "Amount exceeds balance" : !props.amount || parseFloat(props.amount) === 0 - ? "Enter an amount" - : !isValidAddress - ? `Invalid recipient address: ${shorten(props.recipientAddress)}` - : props.bridgeMutation.isLoading - ? "Confirming Bridging in your wallet" - : `Bridge OHM to ${BRIDGE_CHAINS[props.destinationChainId as keyof typeof BRIDGE_CHAINS].name}`} + ? "Enter an amount" + : !isValidAddress + ? `Invalid recipient address: ${shorten(props.recipientAddress)}` + : props.bridgeMutation.isLoading + ? "Confirming Bridging in your wallet" + : `Bridge OHM to ${ + BRIDGE_CHAINS[props.destinationChainId as keyof typeof BRIDGE_CHAINS].name + }`} diff --git a/src/views/Governance/Components/Status.tsx b/src/views/Governance/Components/Status.tsx index ddebf01b36..b74c20226e 100644 --- a/src/views/Governance/Components/Status.tsx +++ b/src/views/Governance/Components/Status.tsx @@ -55,10 +55,12 @@ export const Status = ({ proposalId }: { proposalId: number }) => { Queued for Execution )} -
- {proposalDetails.etaDate.toLocaleString()} - Estimated Execution Time -
+ {proposalDetails.etaDate && ( +
+ {proposalDetails.etaDate.toLocaleString()} + Estimated Execution Time +
+ )} )} {proposalDetails?.status === "Expired" && ( @@ -69,10 +71,12 @@ export const Status = ({ proposalId }: { proposalId: number }) => { Queued for Execution )} -
- {proposalDetails.etaDate.toLocaleString()} - Execution Expired -
+ {proposalDetails.etaDate && ( +
+ {proposalDetails.etaDate.toLocaleString()} + Execution Expired +
+ )} )} {proposalDetails?.status === "Executed" && ( diff --git a/src/views/Governance/Components/VoteModal.tsx b/src/views/Governance/Components/VoteModal.tsx index 4d95b48a3b..8b883a8cd6 100644 --- a/src/views/Governance/Components/VoteModal.tsx +++ b/src/views/Governance/Components/VoteModal.tsx @@ -91,7 +91,7 @@ This behavior is intended to prevent users from changing the outcome of a vote i ) } > - {Number(votingWeight) > 0 ? "Cast Vote" : "No Voting Power"} + {Number(votingWeight) > 0 ? (castVote.isLoading ? "Casting Vote" : "Cast Vote") : "No Voting Power"} diff --git a/src/views/Governance/Proposals/index.tsx b/src/views/Governance/Proposals/index.tsx index 663e1af6ca..58954bbe53 100644 --- a/src/views/Governance/Proposals/index.tsx +++ b/src/views/Governance/Proposals/index.tsx @@ -51,7 +51,9 @@ export const ProposalPage = () => { const currentBlockTime = currentBlock?.timestamp ? new Date(currentBlock?.timestamp * 1000) : new Date(); const pending = !pendingActivation && proposalDetails.status === "Pending"; - const pendingExecution = Boolean(proposalDetails.status === "Queued" && currentBlockTime >= proposalDetails.etaDate); + const pendingExecution = Boolean( + proposalDetails.status === "Queued" && proposalDetails.etaDate && currentBlockTime >= proposalDetails.etaDate, + ); return (
diff --git a/src/views/Governance/hooks/useGetProposalDetails.tsx b/src/views/Governance/hooks/useGetProposalDetails.tsx index c4f61cd32f..471ce8e0d6 100644 --- a/src/views/Governance/hooks/useGetProposalDetails.tsx +++ b/src/views/Governance/hooks/useGetProposalDetails.tsx @@ -28,7 +28,7 @@ export const useGetProposalDetails = ({ proposalId }: { proposalId: number }) => startBlock: proposalDetails.startBlock.toNumber(), endBlock: proposalDetails.endBlock.toNumber(), eta: proposalDetails.eta.toNumber(), - etaDate: new Date(Number(proposalDetails?.eta) * 1000), + etaDate: proposalDetails?.eta ? new Date(Number(proposalDetails.eta) * 1000) : undefined, quorumVotes: Number(formatEther(proposalDetails.quorumVotes)), proposalThreshold: Number(formatEther(proposalDetails.proposalThreshold)), startDate: startDateBlockTimestamp?.timestamp ? new Date(startDateBlockTimestamp.timestamp * 1000) : startDate, diff --git a/src/views/Governance/hooks/useGovernanceDelegationCheck.tsx b/src/views/Governance/hooks/useGovernanceDelegationCheck.tsx index c8d206cb0d..feac5342c0 100644 --- a/src/views/Governance/hooks/useGovernanceDelegationCheck.tsx +++ b/src/views/Governance/hooks/useGovernanceDelegationCheck.tsx @@ -11,6 +11,7 @@ export const useGovernanceDelegationCheck = () => { const { data: clearingHouseV1 } = useGetClearingHouse({ clearingHouse: "clearingHouseV1" }); const { data: clearingHouseV2 } = useGetClearingHouse({ clearingHouse: "clearingHouseV2" }); + const { data: clearingHouseV3 } = useGetClearingHouse({ clearingHouse: "clearingHouseV3" }); const { data: coolerAddressV1 } = useGetCoolerForWallet({ walletAddress: address, factoryAddress: clearingHouseV1?.factory, @@ -25,9 +26,17 @@ export const useGovernanceDelegationCheck = () => { debtAddress: clearingHouseV2?.debtAddress, clearingHouseVersion: "clearingHouseV2", }); + const { data: coolerAddressV3 } = useGetCoolerForWallet({ + walletAddress: address, + factoryAddress: clearingHouseV3?.factory, + collateralAddress: clearingHouseV3?.collateralAddress, + debtAddress: clearingHouseV3?.debtAddress, + clearingHouseVersion: "clearingHouseV3", + }); const { data: gOHMDelegationAddress } = useCheckDelegation({ address }); const { data: coolerV1DelegationAddress } = useCheckDelegation({ address: coolerAddressV1 }); const { data: coolerV2DelegationAddress } = useCheckDelegation({ address: coolerAddressV2 }); + const { data: coolerV3DelegationAddress } = useCheckDelegation({ address: coolerAddressV3 }); const { data: gohmCoolerV2Balance } = useBalance({ address: coolerAddressV2 as `0x${string}`, @@ -45,10 +54,12 @@ export const useGovernanceDelegationCheck = () => { gOHMDelegationAddress, coolerV1DelegationAddress, coolerV2DelegationAddress, + coolerV3DelegationAddress, gohmBalance, gohmCoolerV1Balance, gohmCoolerV2Balance, coolerAddressV1, coolerAddressV2, + coolerAddressV3, }; }; diff --git a/src/views/Lending/Cooler/dashboard/Metrics.tsx b/src/views/Lending/Cooler/dashboard/Metrics.tsx index 1beb0428b0..de28c7e61f 100644 --- a/src/views/Lending/Cooler/dashboard/Metrics.tsx +++ b/src/views/Lending/Cooler/dashboard/Metrics.tsx @@ -90,11 +90,23 @@ export const OutstandingPrincipal = () => { ); }; -export const WeeklyCapacityRemaining = ({ capacity }: { capacity?: BigNumber }) => { +export const WeeklyCapacityRemaining = ({ + capacity, + reserveAsset, +}: { + capacity?: BigNumber; + reserveAsset?: string; +}) => { return ( } + metric={ + capacity && reserveAsset ? ( + formatCurrency(Number(ethers.utils.formatUnits(capacity.toString())), 0, reserveAsset) + ) : ( + + ) + } isLoading={capacity === undefined} /> ); @@ -108,15 +120,19 @@ export const TotalCapacityRemaining = () => { label="Total Capacity Remaining" metric={formatCurrency(getTotalCapacity(latestSnapshot), 0, "DAI")} isLoading={latestSnapshot === undefined} - tooltip={`The capacity remaining is the sum of the DAI and sDAI in the clearinghouse and treasury. As of the latest snapshot, the values (in DAI) are: + tooltip={`The capacity remaining is the sum of the DAI/sDAI and USDS/sUSDS in the clearinghouse and treasury. As of the latest snapshot, the values are: Clearinghouse: DAI: ${formatCurrency(latestSnapshot?.clearinghouseTotals.daiBalance || 0, 0, "DAI")} sDAI: ${formatCurrency(latestSnapshot?.clearinghouseTotals.sDaiInDaiBalance || 0, 0, "DAI")} +USDS: ${formatCurrency(latestSnapshot?.clearinghouseTotals.usdsBalance || 0, 0, "USDS")} +sUSDS: ${formatCurrency(latestSnapshot?.clearinghouseTotals.sUsdsInUsdsBalance || 0, 0, "USDS")} Treasury: DAI: ${formatCurrency(latestSnapshot?.treasury?.daiBalance || 0, 0, "DAI")} -sDAI: ${formatCurrency(latestSnapshot?.treasury?.sDaiInDaiBalance || 0, 0, "DAI")}`} +sDAI: ${formatCurrency(latestSnapshot?.treasury?.sDaiInDaiBalance || 0, 0, "DAI")} +USDS: ${formatCurrency(latestSnapshot?.treasury?.usdsBalance || 0, 0, "USDS")} +sUSDS: ${formatCurrency(latestSnapshot?.treasury?.sUsdsInUsdsBalance || 0, 0, "USDS")}`} /> ); }; diff --git a/src/views/Lending/Cooler/hooks/useGetClearingHouse.tsx b/src/views/Lending/Cooler/hooks/useGetClearingHouse.tsx index 0a07015ff9..671cacda27 100644 --- a/src/views/Lending/Cooler/hooks/useGetClearingHouse.tsx +++ b/src/views/Lending/Cooler/hooks/useGetClearingHouse.tsx @@ -1,15 +1,28 @@ import { useQuery } from "@tanstack/react-query"; import { ethers } from "ethers"; -import { COOLER_CLEARING_HOUSE_CONTRACT_V1, COOLER_CLEARING_HOUSE_CONTRACT_V2 } from "src/constants/contracts"; +import { + COOLER_CLEARING_HOUSE_CONTRACT_V1, + COOLER_CLEARING_HOUSE_CONTRACT_V2, + COOLER_CLEARING_HOUSE_CONTRACT_V3, +} from "src/constants/contracts"; +import { Providers } from "src/helpers/providers/Providers/Providers"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; -import { ERC4626__factory } from "src/typechain"; +import { CoolerClearingHouse, CoolerClearingHouseV3, ERC4626__factory, IERC20__factory } from "src/typechain"; import { useProvider } from "wagmi"; -export const useGetClearingHouse = ({ clearingHouse }: { clearingHouse: "clearingHouseV1" | "clearingHouseV2" }) => { +export const useGetClearingHouse = ({ + clearingHouse, +}: { + clearingHouse: "clearingHouseV1" | "clearingHouseV2" | "clearingHouseV3"; +}) => { const networks = useTestableNetworks(); const provider = useProvider(); const clearingHouseContract = - clearingHouse === "clearingHouseV1" ? COOLER_CLEARING_HOUSE_CONTRACT_V1 : COOLER_CLEARING_HOUSE_CONTRACT_V2; + clearingHouse === "clearingHouseV1" + ? COOLER_CLEARING_HOUSE_CONTRACT_V1 + : clearingHouse === "clearingHouseV2" + ? COOLER_CLEARING_HOUSE_CONTRACT_V2 + : COOLER_CLEARING_HOUSE_CONTRACT_V3; const contract = clearingHouseContract.getEthersContract(networks.MAINNET); const { data, isFetched, isLoading } = useQuery(["getClearingHouse", networks.MAINNET, clearingHouse], async () => { const factory = await contract.factory(); @@ -17,16 +30,22 @@ export const useGetClearingHouse = ({ clearingHouse }: { clearingHouse: "clearin const duration = (await contract.DURATION()).div(86400).toString(); // 86400 seconds in a day const loanToCollateral = ethers.utils.formatUnits((await contract.LOAN_TO_COLLATERAL()).toString()); // 1.5 = 150% LTV (Loan to Value Ratio const collateralAddress = await contract.gohm(); - const debtAddress = await contract.dai(); - const sdai = await contract.sdai(); - const sdaiContract = ERC4626__factory.connect(sdai, provider); - const sdaiBalanceClearingHouse = await sdaiContract.balanceOf(contract.address); //shares held by clearinghouse - // const sdaiBalanceTreasury = await sdaiContract.balanceOf(treasury); //shares held by treasury - const daiBalanceClearingHouse = await sdaiContract.convertToAssets(sdaiBalanceClearingHouse); - // const daiBalanceTreasury = await sdaiContract.convertToAssets(sdaiBalanceTreasury); - - // const daiBalance = daiBalanceClearingHouse.add(daiBalanceTreasury); + let debtAddress: string; + let sReserveAddress: string; + if (clearingHouse === "clearingHouseV3") { + debtAddress = await (contract as CoolerClearingHouseV3).reserve(); + sReserveAddress = await (contract as CoolerClearingHouseV3).sReserve(); + } else { + debtAddress = await (contract as CoolerClearingHouse).dai(); + sReserveAddress = await (contract as CoolerClearingHouse).sdai(); + } + const debtContract = IERC20__factory.connect(debtAddress, Providers.getStaticProvider(networks.MAINNET)); + const debtAssetName = await debtContract.symbol(); + const sReserveContract = ERC4626__factory.connect(sReserveAddress, provider); + const sReserveBalanceClearingHouse = await sReserveContract.balanceOf(contract.address); //shares held by clearinghouse + const reserveBalanceClearingHouse = await sReserveContract.convertToAssets(sReserveBalanceClearingHouse); const clearingHouseAddress = contract.address; + const isActive = await contract.isActive(); return { interestRate, @@ -35,8 +54,10 @@ export const useGetClearingHouse = ({ clearingHouse }: { clearingHouse: "clearin factory, collateralAddress, debtAddress, - capacity: daiBalanceClearingHouse, + capacity: reserveBalanceClearingHouse, clearingHouseAddress, + debtAssetName, + isActive, }; }); return { data, isFetched, isLoading }; diff --git a/src/views/Lending/Cooler/hooks/useGetCoolerLoans.tsx b/src/views/Lending/Cooler/hooks/useGetCoolerLoans.tsx index 725f5511e7..a497e2e493 100644 --- a/src/views/Lending/Cooler/hooks/useGetCoolerLoans.tsx +++ b/src/views/Lending/Cooler/hooks/useGetCoolerLoans.tsx @@ -1,7 +1,7 @@ import { useQuery } from "@tanstack/react-query"; import { Providers } from "src/helpers/providers/Providers/Providers"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; -import { Cooler__factory, CoolerFactory__factory } from "src/typechain"; +import { Cooler__factory, CoolerFactory__factory, IERC20__factory } from "src/typechain"; import { useSigner } from "wagmi"; export const useGetCoolerLoans = ({ @@ -24,7 +24,8 @@ export const useGetCoolerLoans = ({ try { if (!walletAddress || !factoryAddress || !collateralAddress || !debtAddress || !signer) return []; const contract = CoolerFactory__factory.connect(factoryAddress, signer); - + const debtContract = IERC20__factory.connect(debtAddress, Providers.getStaticProvider(networks.MAINNET)); + const debtAssetName = await debtContract.symbol(); const coolerAddress = await contract.callStatic.generateCooler(collateralAddress, debtAddress); const coolerContract = Cooler__factory.connect(coolerAddress, Providers.getStaticProvider(networks.MAINNET)); @@ -34,7 +35,7 @@ export const useGetCoolerLoans = ({ try { const loanData = await coolerContract.loans(loanId); // const newCollateralAmount = await coolerContract.newCollateralFor(loanId); - loans.push({ ...loanData, loanId }); + loans.push({ ...loanData, loanId, debtAssetName }); loanId++; } catch (e) { break; diff --git a/src/views/Lending/Cooler/hooks/useSnapshot.tsx b/src/views/Lending/Cooler/hooks/useSnapshot.tsx index ec86d16e01..09e3f6fac0 100644 --- a/src/views/Lending/Cooler/hooks/useSnapshot.tsx +++ b/src/views/Lending/Cooler/hooks/useSnapshot.tsx @@ -104,9 +104,22 @@ export const getTotalCapacity = (snapshot: Snapshot | undefined): number => { const treasuryDaiBalance = snapshot.treasury?.daiBalance || 0; const treasurySDaiInDaiBalance = snapshot.treasury?.sDaiInDaiBalance || 0; + const treasuryUsdsBalance = snapshot.treasury?.usdsBalance || 0; + const treasurySUsdsInUsdsBalance = snapshot.treasury?.sUsdsInUsdsBalance || 0; const clearinghouseDaiBalance = snapshot.clearinghouseTotals.daiBalance || 0; const clearinghouseSDaiInDaiBalance = snapshot.clearinghouseTotals.sDaiInDaiBalance || 0; - - return treasuryDaiBalance + treasurySDaiInDaiBalance + clearinghouseDaiBalance + clearinghouseSDaiInDaiBalance; + const clearinghouseUsdsBalance = snapshot.clearinghouseTotals.usdsBalance || 0; + const clearinghouseSUsdsInUsdsBalance = snapshot.clearinghouseTotals.sUsdsInUsdsBalance || 0; + + return ( + treasuryDaiBalance + + treasurySDaiInDaiBalance + + treasuryUsdsBalance + + treasurySUsdsInUsdsBalance + + clearinghouseDaiBalance + + clearinghouseSDaiInDaiBalance + + clearinghouseUsdsBalance + + clearinghouseSUsdsInUsdsBalance + ); }; diff --git a/src/views/Lending/Cooler/index.tsx b/src/views/Lending/Cooler/index.tsx index 2455a40fa8..797cde6012 100644 --- a/src/views/Lending/Cooler/index.tsx +++ b/src/views/Lending/Cooler/index.tsx @@ -33,7 +33,7 @@ export const Cooler = () => { name="Cooler Loans" subtitle={ - Borrow DAI against your gOHM collateral.{" "} + Borrow against your gOHM collateral.{" "} - - ); + return <>; }; diff --git a/src/views/Lending/Cooler/positions/CreateOrRepayLoan.tsx b/src/views/Lending/Cooler/positions/CreateOrRepayLoan.tsx index 56f6f0fe95..3cdcd61197 100644 --- a/src/views/Lending/Cooler/positions/CreateOrRepayLoan.tsx +++ b/src/views/Lending/Cooler/positions/CreateOrRepayLoan.tsx @@ -1,8 +1,9 @@ import { Box, Divider, SvgIcon } from "@mui/material"; import { Modal, OHMSwapCardProps, PrimaryButton, SwapCard, SwapCollection } from "@olympusdao/component-library"; import { BigNumber, ethers } from "ethers"; -import { useState } from "react"; +import { ReactElement, useState } from "react"; import lendAndBorrowIcon from "src/assets/icons/lendAndBorrow.svg?react"; +import usdsIcon from "src/assets/tokens/usds.svg?react"; import { TokenAllowanceGuard } from "src/components/TokenAllowanceGuard/TokenAllowanceGuard"; import { WalletConnectedGuard } from "src/components/WalletConnectedGuard"; import { formatNumber } from "src/helpers"; @@ -27,6 +28,7 @@ export const CreateOrRepayLoan = ({ modalOpen, loan, clearingHouseAddress, + debtAssetName, }: { collateralAddress: string; debtAddress: string; @@ -50,6 +52,7 @@ export const CreateOrRepayLoan = ({ loanId: number; }; clearingHouseAddress: string; + debtAssetName: string; }) => { const createCooler = useCreateCooler(); const createLoan = useCreateLoan(); @@ -76,10 +79,18 @@ export const CreateOrRepayLoan = ({ : Math.min(Number(capacity), collateralValue); const interestRepaid = loan?.collateral.isZero() || false; //if collateral minus principal is greater than interest... then calculate on collateral amount. - const daiCard = ( + const debtCard = ( + + {debtAssetName} + + ) : undefined + } value={paymentAmount.toString()} onChange={(e: { target: { value: DecimalBigNumber | string } }) => { const value = typeof e.target.value === "string" ? new DecimalBigNumber(e.target.value) : e.target.value; @@ -119,16 +130,21 @@ export const CreateOrRepayLoan = ({ open={modalOpen} headerContent={ - {loan ? "Repay" : "Borrow"} DAI + {" "} + + {loan ? "Repay" : "Borrow"} {debtAssetName} + } onClose={() => setModalOpen(false)} > <> - + Max you Can {loan ? "Repay" : "Borrow"} - {formatNumber(maxYouCanBorrow, 2)} DAI + + {formatNumber(maxYouCanBorrow, 2)} {debtAssetName} + @@ -153,17 +169,23 @@ export const CreateOrRepayLoan = ({ Loan To Value per gOHM - {formatNumber(Number(loanToCollateral), 2)} DAI + + {formatNumber(Number(loanToCollateral), 2)} {debtAssetName} + {loan && ( <> Principal - {formatNumber(Number(ethers.utils.formatUnits(loan.principal)), 2)} DAI + + {formatNumber(Number(ethers.utils.formatUnits(loan.principal)), 2)} {debtAssetName} + Interest Due - {formatNumber(Number(ethers.utils.formatUnits(loan.interestDue)), 2)} DAI + + {formatNumber(Number(ethers.utils.formatUnits(loan.interestDue)), 2)} {debtAssetName} + )} @@ -197,8 +219,8 @@ export const CreateOrRepayLoan = ({ isVertical message={ <> - First time {loan ? "repaying" : "borrowing"} with {loan ? "DAI" : "gOHM"}?
Please - approve Olympus DAO to use your {loan ? "DAI" : "gOHM"} for borrowing. + First time {loan ? "repaying" : "borrowing"} with {loan ? debtAssetName : "gOHM"}?
{" "} + Please approve Olympus DAO to use your {loan ? debtAssetName : "gOHM"} for borrowing. } spendAmount={ @@ -257,7 +279,7 @@ export const CreateOrRepayLoan = ({ : `Repay Loan` : Number(paymentAmount.toString()) > maxYouCanBorrow ? `Amount requested exceeds capacity` - : `Borrow DAI & Open Position`} + : `Borrow ${debtAssetName} & Open Position`} )} @@ -271,12 +293,14 @@ export const CreateOrRepayLoan = ({ const AssetSwapCard = ({ assetAddress, tokenName, + tokenIcon, value, onChange, loanBalance, }: { assetAddress: string; tokenName: OHMSwapCardProps["token"]; + tokenIcon?: ReactElement; value: number | string; onChange: any; loanBalance?: BigNumber; @@ -288,7 +312,7 @@ const AssetSwapCard = ({ return ( { const extendLoan = useExtendLoan(); const networks = useTestableNetworks(); @@ -140,11 +142,11 @@ export const ExtendLoan = ({ )} - DAI Balance + {debtAssetName} Balance {" "} - {!daiBalance ? : daiBalance.toString({ decimals: 2 })} DAI + {!daiBalance ? : daiBalance.toString({ decimals: 2 })} {debtAssetName} @@ -153,7 +155,7 @@ export const ExtendLoan = ({ Interest Due on Extension - {formatNumber(interestDue > 0 ? interestDue : 0, 2)} DAI + {formatNumber(interestDue > 0 ? interestDue : 0, 2)} {debtAssetName} @@ -165,8 +167,8 @@ export const ExtendLoan = ({ isVertical message={ <> - First time repaying with DAI?
Please approve Olympus DAO to use your DAI for - payment. + First time repaying with {debtAssetName}?
Please approve Olympus DAO to use your{" "} + {debtAssetName} for payment. } spendAmount={new DecimalBigNumber(interestDue.toString(), 18)} @@ -186,7 +188,7 @@ export const ExtendLoan = ({ }} loading={extendLoan.isLoading} > - {insufficientCollateral ? "Insufficient DAI Balance" : "Extend Loan"} + {insufficientCollateral ? `Insufficient ${debtAssetName} Balance` : "Extend Loan"} diff --git a/src/views/Lending/Cooler/positions/Positions.tsx b/src/views/Lending/Cooler/positions/Positions.tsx index 236d0646fc..76e9245c1c 100644 --- a/src/views/Lending/Cooler/positions/Positions.tsx +++ b/src/views/Lending/Cooler/positions/Positions.tsx @@ -14,71 +14,113 @@ import { Typography, useTheme, } from "@mui/material"; -import { PrimaryButton, SecondaryButton, Token } from "@olympusdao/component-library"; +import { OHMTokenProps, PrimaryButton, SecondaryButton, Token } from "@olympusdao/component-library"; import { ethers } from "ethers"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { BorrowRate, OutstandingPrincipal, WeeklyCapacityRemaining } from "src/views/Lending/Cooler/dashboard/Metrics"; import { useGetClearingHouse } from "src/views/Lending/Cooler/hooks/useGetClearingHouse"; import { useGetCoolerForWallet } from "src/views/Lending/Cooler/hooks/useGetCoolerForWallet"; import { useGetCoolerLoans } from "src/views/Lending/Cooler/hooks/useGetCoolerLoans"; -import { ConsolidateLoans } from "src/views/Lending/Cooler/positions/ConsolidateLoan"; import { CreateOrRepayLoan } from "src/views/Lending/Cooler/positions/CreateOrRepayLoan"; import { ExtendLoan } from "src/views/Lending/Cooler/positions/ExtendLoan"; import { useAccount } from "wagmi"; export const CoolerPositions = () => { const { address } = useAccount(); - const [currentClearingHouse, setCurrentClearingHouse] = useState<"clearingHouseV1" | "clearingHouseV2">( - "clearingHouseV2", - ); - const { data: clearingHouseV1 } = useGetClearingHouse({ clearingHouse: "clearingHouseV1" }); - const { data: clearingHouseV2 } = useGetClearingHouse({ clearingHouse: "clearingHouseV2" }); + const [currentClearingHouse, setCurrentClearingHouse] = useState<"v1" | "v2" | "v3">("v3"); + // Get clearing house data for all versions + const clearingHouses = { + v1: useGetClearingHouse({ clearingHouse: "clearingHouseV1" }).data, + v2: useGetClearingHouse({ clearingHouse: "clearingHouseV2" }).data, + v3: useGetClearingHouse({ clearingHouse: "clearingHouseV3" }).data, + }; const [createLoanModalOpen, setCreateLoanModalOpen] = useState(false); const { data: loansV1, isFetched: isFetchedLoansV1 } = useGetCoolerLoans({ walletAddress: address, - factoryAddress: clearingHouseV1?.factory, - collateralAddress: clearingHouseV1?.collateralAddress, - debtAddress: clearingHouseV1?.debtAddress, + factoryAddress: clearingHouses.v1?.factory, + collateralAddress: clearingHouses.v1?.collateralAddress, + debtAddress: clearingHouses.v1?.debtAddress, }); const { data: coolerAddressV1 } = useGetCoolerForWallet({ walletAddress: address, - factoryAddress: clearingHouseV1?.factory, - collateralAddress: clearingHouseV1?.collateralAddress, - debtAddress: clearingHouseV1?.debtAddress, + factoryAddress: clearingHouses.v1?.factory, + collateralAddress: clearingHouses.v1?.collateralAddress, + debtAddress: clearingHouses.v1?.debtAddress, clearingHouseVersion: "clearingHouseV1", }); const { data: loansV2, isFetched: isFetchedLoansV2 } = useGetCoolerLoans({ walletAddress: address, - factoryAddress: clearingHouseV2?.factory, - collateralAddress: clearingHouseV2?.collateralAddress, - debtAddress: clearingHouseV2?.debtAddress, + factoryAddress: clearingHouses.v2?.factory, + collateralAddress: clearingHouses.v2?.collateralAddress, + debtAddress: clearingHouses.v2?.debtAddress, }); const { data: coolerAddressV2 } = useGetCoolerForWallet({ walletAddress: address, - factoryAddress: clearingHouseV2?.factory, - collateralAddress: clearingHouseV2?.collateralAddress, - debtAddress: clearingHouseV2?.debtAddress, + factoryAddress: clearingHouses.v2?.factory, + collateralAddress: clearingHouses.v2?.collateralAddress, + debtAddress: clearingHouses.v2?.debtAddress, clearingHouseVersion: "clearingHouseV2", }); - const coolerAddress = currentClearingHouse === "clearingHouseV1" ? coolerAddressV1 : coolerAddressV2; - const clearingHouse = currentClearingHouse === "clearingHouseV1" ? clearingHouseV1 : clearingHouseV2; - const loans = currentClearingHouse === "clearingHouseV1" ? loansV1 : loansV2; - const isFetchedLoans = currentClearingHouse === "clearingHouseV1" ? isFetchedLoansV1 : isFetchedLoansV2; + const { data: loansV3, isFetched: isFetchedLoansV3 } = useGetCoolerLoans({ + walletAddress: address, + factoryAddress: clearingHouses.v3?.factory, + collateralAddress: clearingHouses.v3?.collateralAddress, + debtAddress: clearingHouses.v3?.debtAddress, + }); + + const { data: coolerAddressV3 } = useGetCoolerForWallet({ + walletAddress: address, + factoryAddress: clearingHouses.v3?.factory, + collateralAddress: clearingHouses.v3?.collateralAddress, + debtAddress: clearingHouses.v3?.debtAddress, + clearingHouseVersion: "clearingHouseV3", + }); + + // Organize version data + const versionData = { + v1: { + loans: { data: loansV1, isFetched: isFetchedLoansV1 }, + coolerAddress: { data: coolerAddressV1 }, + }, + v2: { + loans: { data: loansV2, isFetched: isFetchedLoansV2 }, + coolerAddress: { data: coolerAddressV2 }, + }, + v3: { + loans: { data: loansV3, isFetched: isFetchedLoansV3 }, + coolerAddress: { data: coolerAddressV3 }, + }, + }; + + const currentData = versionData[currentClearingHouse]; + const coolerAddress = currentData.coolerAddress.data; + const clearingHouse = clearingHouses[currentClearingHouse]; + const loans = currentData.loans.data; + const isFetchedLoans = currentData.loans.isFetched; const [extendLoan, setExtendLoan] = useState(null); const [repayLoan, setRepayLoan] = useState(null); const theme = useTheme(); + // Update the clearing house version when the data is available + useEffect(() => { + if (clearingHouses.v3?.isActive && clearingHouses.v3?.capacity.gt(0)) { + setCurrentClearingHouse("v3"); + } else if (clearingHouses.v2?.isActive && clearingHouses.v2?.capacity.gt(0)) { + setCurrentClearingHouse("v2"); + } + }, [clearingHouses.v2, clearingHouses.v3]); + return (
- + @@ -87,13 +129,17 @@ export const CoolerPositions = () => { - {clearingHouseV1 && loansV1 && loansV1.length > 0 && ( + {([(loansV1 || []).length > 0, (loansV2 || []).length > 0, (loansV3 || []).length > 0].filter(Boolean).length > + 1 || + (clearingHouses.v3?.isActive && + clearingHouses.v3?.capacity.gt(0) && + ((loansV1 && loansV1.length > 0) || (loansV2 && loansV2.length > 0)))) && ( )} Your Positions -
Borrow DAI from the Olympus Treasury against your gOHM
+
Borrow from the Olympus Treasury against your gOHM
{!address && ( @@ -142,17 +195,21 @@ export const CoolerPositions = () => { You currently have no Cooler loans - Borrow DAI against gOHM at a fixed rate and maturity - - { - setRepayLoan(undefined); - setCreateLoanModalOpen(true); - }} - > - Borrow DAI & Open Position - - + {clearingHouse?.isActive && clearingHouse.capacity.gt(0) && ( + <> + Borrow against gOHM at a fixed rate and maturity + + { + setRepayLoan(undefined); + setCreateLoanModalOpen(true); + }} + > + Borrow {clearingHouse?.debtAssetName} & Open Position + + + + )} )} @@ -198,8 +255,12 @@ export const CoolerPositions = () => { {principalAndInterest && ( - {Number(ethers.utils.formatUnits(principalAndInterest.toString())).toFixed(2)} DAI{" "} - + {Number(ethers.utils.formatUnits(principalAndInterest.toString())).toFixed(2)}{" "} + {loan.debtAssetName}{" "} + )} @@ -233,16 +294,18 @@ export const CoolerPositions = () => { - - { - setRepayLoan(undefined); - setCreateLoanModalOpen(true); - }} - > - Borrow DAI & Open Position - - + {clearingHouse?.isActive && clearingHouse.capacity.gt(0) && ( + + { + setRepayLoan(undefined); + setCreateLoanModalOpen(true); + }} + > + Borrow {clearingHouse.debtAssetName} & Open Position + + + )} )} @@ -260,6 +323,7 @@ export const CoolerPositions = () => { coolerAddress={coolerAddress} debtAddress={clearingHouse.debtAddress} clearingHouseAddress={clearingHouse.clearingHouseAddress} + debtAssetName={clearingHouse.debtAssetName} /> )} { modalOpen={createLoanModalOpen} loan={repayLoan} clearingHouseAddress={clearingHouse.clearingHouseAddress} + debtAssetName={clearingHouse.debtAssetName} /> )} diff --git a/src/views/Lending/LendingMarkets.tsx b/src/views/Lending/LendingMarkets.tsx index 4671905a35..fbdab8230a 100644 --- a/src/views/Lending/LendingMarkets.tsx +++ b/src/views/Lending/LendingMarkets.tsx @@ -81,12 +81,12 @@ export const LendingMarkets = () => { poolFilter === "stable" ? stablePools : poolFilter === "volatile" - ? volatilePools - : poolFilter === "gohm" - ? gOHMPools - : poolFilter === "ohm" - ? ohmPools - : defiLlamaPools; + ? volatilePools + : poolFilter === "gohm" + ? gOHMPools + : poolFilter === "ohm" + ? ohmPools + : defiLlamaPools; const poolListByNetwork = networkFilter ? poolList?.filter(pool => pool.chain === networkFilter) : poolList; const PoolChip = ({ label }: { label: string }) => ( diff --git a/src/views/Liquidity/ExternalStakePools/ExternalStakePools.tsx b/src/views/Liquidity/ExternalStakePools/ExternalStakePools.tsx index 3275586787..b3ebbd8f63 100644 --- a/src/views/Liquidity/ExternalStakePools/ExternalStakePools.tsx +++ b/src/views/Liquidity/ExternalStakePools/ExternalStakePools.tsx @@ -79,10 +79,10 @@ export const ExternalStakePools = () => { poolFilter === "stable" ? stablePools : poolFilter === "volatile" - ? volatilePools - : poolFilter === "gohm" - ? gOHMPools - : defiLlamaPools; + ? volatilePools + : poolFilter === "gohm" + ? gOHMPools + : defiLlamaPools; const poolListByNetwork = networkFilter ? poolList?.filter(pool => pool.chain === networkFilter) : poolList; const PoolChip = ({ label }: { label: string }) => ( diff --git a/src/views/MyBalances/MyCoolerLoans.tsx b/src/views/MyBalances/MyCoolerLoans.tsx index 49523888fd..4c41776aa5 100644 --- a/src/views/MyBalances/MyCoolerLoans.tsx +++ b/src/views/MyBalances/MyCoolerLoans.tsx @@ -20,6 +20,7 @@ export const MyCoolerLoans = ({ balance, balanceUSD }: { balance: string; balanc const { data: clearingHouseV1 } = useGetClearingHouse({ clearingHouse: "clearingHouseV1" }); const { data: clearingHouseV2 } = useGetClearingHouse({ clearingHouse: "clearingHouseV2" }); + const { data: clearingHouseV3 } = useGetClearingHouse({ clearingHouse: "clearingHouseV3" }); const { data: v1Loans, isFetched: isFetchedLoansV1 } = useGetCoolerLoans({ walletAddress: address, @@ -34,8 +35,14 @@ export const MyCoolerLoans = ({ balance, balanceUSD }: { balance: string; balanc collateralAddress: clearingHouseV2?.collateralAddress, debtAddress: clearingHouseV2?.debtAddress, }); + const { data: v3Loans, isFetched: isFetchedLoansV3 } = useGetCoolerLoans({ + walletAddress: address, + factoryAddress: clearingHouseV3?.factory, + collateralAddress: clearingHouseV3?.collateralAddress, + debtAddress: clearingHouseV3?.debtAddress, + }); - const loans = [...(v1Loans || []), ...(v2Loans || [])]; + const loans = [...(v1Loans || []), ...(v2Loans || []), ...(v3Loans || [])]; const sortedLoans = loans .slice() diff --git a/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx b/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx index 615100940b..a40101a45e 100644 --- a/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx +++ b/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx @@ -170,14 +170,14 @@ const StakeConfirmationModal = (props: { {props.amountExceedsBalance ? "Amount exceeds balance" : !props.amount || parseFloat(props.amount) === 0 - ? "Enter an amount" - : props.currentAction === "STAKE" - ? props.isMutating - ? "Confirming Wrapping in your wallet" - : "Wrap" - : props.isMutating - ? "Confirming Unwrapping in your wallet " - : "Unwrap"} + ? "Enter an amount" + : props.currentAction === "STAKE" + ? props.isMutating + ? "Confirming Wrapping in your wallet" + : "Wrap" + : props.isMutating + ? "Confirming Unwrapping in your wallet " + : "Unwrap"} )} @@ -195,14 +195,14 @@ const StakeConfirmationModal = (props: { {props.amountExceedsBalance ? "Amount exceeds balance" : !props.amount || parseFloat(props.amount) === 0 - ? "Enter an amount" - : props.currentAction === "STAKE" - ? props.isMutating - ? "Confirming Wrapping in your wallet" - : "Wrap to gOHM" - : props.isMutating - ? "Confirming Unwrapping in your wallet " - : "Unwrap"} + ? "Enter an amount" + : props.currentAction === "STAKE" + ? props.isMutating + ? "Confirming Wrapping in your wallet" + : "Wrap to gOHM" + : props.isMutating + ? "Confirming Unwrapping in your wallet " + : "Unwrap"} )}