diff --git a/abi/ICorkHook.json b/abi/cork/ICorkHook.json similarity index 91% rename from abi/ICorkHook.json rename to abi/cork/ICorkHook.json index efab0bf..ed8b74d 100644 --- a/abi/ICorkHook.json +++ b/abi/cork/ICorkHook.json @@ -247,6 +247,21 @@ "name": "liquidityToken", "type": "address", "internalType": "address" + }, + { + "name": "startTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "endTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "treasuryFeePercentage", + "type": "uint256", + "internalType": "uint256" } ] } @@ -441,13 +456,13 @@ { "name": "ra", "type": "address", - "indexed": false, + "indexed": true, "internalType": "address" }, { "name": "ct", "type": "address", - "indexed": false, + "indexed": true, "internalType": "address" }, { @@ -479,19 +494,44 @@ }, { "type": "event", - "name": "RemovedLiquidity", + "name": "Initialized", "inputs": [ { "name": "ra", "type": "address", - "indexed": false, + "indexed": true, "internalType": "address" }, { "name": "ct", "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "liquidityToken", + "type": "address", "indexed": false, "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RemovedLiquidity", + "inputs": [ + { + "name": "ra", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "ct", + "type": "address", + "indexed": true, + "internalType": "address" }, { "name": "raAmount", @@ -527,7 +567,7 @@ { "name": "output", "type": "address", - "indexed": false, + "indexed": true, "internalType": "address" }, { @@ -545,7 +585,7 @@ { "name": "who", "type": "address", - "indexed": false, + "indexed": true, "internalType": "address" }, { @@ -559,6 +599,12 @@ "type": "uint256", "indexed": false, "internalType": "uint256" + }, + { + "name": "realizedFeeAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" } ], "anonymous": false diff --git a/abi/cork/ModuleCore.json b/abi/cork/ModuleCore.json new file mode 100644 index 0000000..58ca467 --- /dev/null +++ b/abi/cork/ModuleCore.json @@ -0,0 +1,3264 @@ +[ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "UPGRADE_INTERFACE_VERSION", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "availableForRepurchase", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "pa", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ds", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "baseRedemptionFee", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claimAutoSellProfit", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "profit", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsReceived", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositLv", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "raTolerance", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ctTolerance", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositPsm", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_exchangeRate", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "exchangeRate", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "rates", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "expiry", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "factory", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "forceUpdateNavCircuitBreakerReferenceValue", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getAmmRouter", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICorkHook" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getId", + "inputs": [ + { + "name": "pa", + "type": "address", + "internalType": "address" + }, + { + "name": "ra", + "type": "address", + "internalType": "address" + }, + { + "name": "initialArp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exchangeRateProvider", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Id" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getRouterCore", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract RouterState" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getTreasuryAddress", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getWithdrawalContract", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract Withdrawal" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_swapAssetFactory", + "type": "address", + "internalType": "address" + }, + { + "name": "_ammHook", + "type": "address", + "internalType": "address" + }, + { + "name": "_flashSwapRouter", + "type": "address", + "internalType": "address" + }, + { + "name": "_config", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "initializeModuleCore", + "inputs": [ + { + "name": "pa", + "type": "address", + "internalType": "address" + }, + { + "name": "ra", + "type": "address", + "internalType": "address" + }, + { + "name": "initialArp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "expiryInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exchangeRateProvider", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "issueNewDs", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "decayDiscountRateInDays", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rolloverPeriodInblocks", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ammLiquidationDeadline", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "lastDsId", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "liquidationFundsAvailable", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lvAcceptRolloverProfit", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "lvAsset", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "lv", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "markets", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "pa", + "type": "address", + "internalType": "address" + }, + { + "name": "ra", + "type": "address", + "internalType": "address" + }, + { + "name": "initialArp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "expiryInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exchangeRateProvider", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "provideLiquidityWithFlashSwapFee", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "proxiableUUID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "psmAcceptFlashSwapProfit", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "profit", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "psmAutoSellStatus", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "receiveLeftoverFunds", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "receiveTradeExecuctionResultFunds", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "redeemEarlyLv", + "inputs": [ + { + "name": "redeemParams", + "type": "tuple", + "internalType": "struct IVault.RedeemEarlyParams", + "components": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amountOutMin", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ammDeadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ctAmountOutMin", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsAmountOutMin", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paAmountOutMin", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "result", + "type": "tuple", + "internalType": "struct IVault.RedeemEarlyResult", + "components": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "receiver", + "type": "address", + "internalType": "address" + }, + { + "name": "raReceivedFromAmm", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "raIdleReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ctReceivedFromAmm", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ctReceivedFromVault", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "withdrawalId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "redeemEarlyLv", + "inputs": [ + { + "name": "redeemParams", + "type": "tuple", + "internalType": "struct IVault.RedeemEarlyParams", + "components": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amountOutMin", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ammDeadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ctAmountOutMin", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsAmountOutMin", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paAmountOutMin", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "permitParams", + "type": "tuple", + "internalType": "struct IVault.PermitParams", + "components": [ + { + "name": "rawLvPermitSig", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "result", + "type": "tuple", + "internalType": "struct IVault.RedeemEarlyResult", + "components": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "receiver", + "type": "address", + "internalType": "address" + }, + { + "name": "raReceivedFromAmm", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "raIdleReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ctReceivedFromAmm", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ctReceivedFromVault", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "withdrawalId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "redeemRaWithDsPa", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_exchangeRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsUsed", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "redeemRaWithDsPa", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "redeemer", + "type": "address", + "internalType": "address" + }, + { + "name": "rawDsPermitSig", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_exchangeRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsUsed", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "redeemWithExpiredCt", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "accruedPa", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "accruedRa", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "redeemWithExpiredCt", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "redeemer", + "type": "address", + "internalType": "address" + }, + { + "name": "rawCtPermitSig", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "accruedPa", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "accruedRa", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "repurchase", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "receivedPa", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "receivedDs", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "feePercentage", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exchangeRates", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "repurchaseFee", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "repurchaseRates", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "rates", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "requestLiquidationFunds", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "returnRaWithCtDs", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "ra", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "returnRaWithCtDs", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "redeemer", + "type": "address", + "internalType": "address" + }, + { + "name": "rawDsPermitSig", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "dsDeadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rawCtPermitSig", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "ctDeadline", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "ra", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rolloverExpiredCt", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "ctReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paReceived", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rolloverExpiredCt", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rawCtPermitSig", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "ctDeadline", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "ctReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dsReceived", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paReceived", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rolloverProfitRemaining", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setWithdrawalContract", + "inputs": [ + { + "name": "_withdrawalContract", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "swapAsset", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "ct", + "type": "address", + "internalType": "address" + }, + { + "name": "ds", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalRaAt", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "tradeExecutionFundsAvailable", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "underlyingAsset", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "ra", + "type": "address", + "internalType": "address" + }, + { + "name": "pa", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "updateCtHeldPercentage", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "ctHeldPercentage", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateLvDepositsStatus", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "isLVDepositPaused", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateLvWithdrawalsStatus", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "isLVWithdrawalPaused", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePsmAutoSellStatus", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "status", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePsmBaseRedemptionFeePercentage", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "newPsmBaseRedemptionFeePercentage", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePsmBaseRedemptionFeeTreasurySplitPercentage", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "percentage", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePsmDepositsStatus", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "isPSMDepositPaused", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePsmRepurchaseFeeTreasurySplitPercentage", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "percentage", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePsmRepurchasesStatus", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "isPSMRepurchasePaused", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePsmWithdrawalsStatus", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "isPSMWithdrawalPaused", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateRepurchaseFeeRate", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "newRepurchaseFeePercentage", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateVaultNavThreshold", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "newNavThreshold", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "upgradeToAndCall", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "useTradeExecutionResultFunds", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "valueLocked", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + }, + { + "name": "ra", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "vaultLp", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "Id" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "Cancelled", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "redeemer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "raAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "swapAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "CtRedeemed", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "redeemer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "paReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "raReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DsRedeemed", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "redeemer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "paUsed", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "dsUsed", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "raReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "dsExchangeRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "feePercentage", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "fee", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EarlyRedemptionFeeRateUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "earlyRedemptionFeeRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "InitializedModuleCore", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "pa", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "ra", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "lv", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "expiry", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "initialArp", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "exchangeRateProvider", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Issued", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "expiry", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "ds", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "ct", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "raCtUniPairId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LiquidationFundsRequested", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "who", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LvDeposited", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "depositor", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "received", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "deposited", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LvDepositsStatusUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "isLVDepositPaused", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LvRedeemEarly", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "redeemer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "receiver", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "lvBurned", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "ctReceivedFromAmm", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "ctReceivedFromVault", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "dsReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "paReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "raReceivedFromAmm", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "raIdleReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "withdrawalId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LvWithdrawalsStatusUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "isLVWithdrawalPaused", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ProfitReceived", + "inputs": [ + { + "name": "router", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PsmBaseRedemptionFeePercentageUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "psmBaseRedemptionFeePercentage", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PsmDeposited", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "depositor", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "received", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "exchangeRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PsmDepositsStatusUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "isPSMDepositPaused", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PsmRepurchasesStatusUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "isPSMRepurchasePaused", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PsmWithdrawalsStatusUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "isPSMWithdrawalPaused", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RateUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "newRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "previousRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RepurchaseFeeRateUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "repurchaseFeeRate", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Repurchased", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "buyer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "dsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "raUsed", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "receivedPa", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "receivedDs", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "feePercentage", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "fee", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "exchangeRates", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RolledOver", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "currentDsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "prevDsId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "amountCtRolledOver", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "dsReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "ctReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "paReceived", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RolloverProfitClaimed", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "dsId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "profit", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "remainingDs", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SnapshotUpdated", + "inputs": [ + { + "name": "snapshotIndex", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newValue", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TradeExecutionResultFundsReceived", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "who", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TradeExecutionResultFundsUsed", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "who", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "VaultNavThresholdUpdated", + "inputs": [ + { + "name": "id", + "type": "bytes32", + "indexed": true, + "internalType": "Id" + }, + { + "name": "navThreshold", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "AlreadyInitialized", + "inputs": [] + }, + { + "type": "error", + "name": "ApproxExhausted", + "inputs": [] + }, + { + "type": "error", + "name": "CallerNotFactory", + "inputs": [] + }, + { + "type": "error", + "name": "DisableNativeLiquidityModification", + "inputs": [] + }, + { + "type": "error", + "name": "ERC1967InvalidImplementation", + "inputs": [ + { + "name": "implementation", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1967NonPayable", + "inputs": [] + }, + { + "type": "error", + "name": "Expired", + "inputs": [] + }, + { + "type": "error", + "name": "FailedCall", + "inputs": [] + }, + { + "type": "error", + "name": "InalidRefId", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientBalance", + "inputs": [ + { + "name": "caller", + "type": "address", + "internalType": "address" + }, + { + "name": "requested", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "balance", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InsufficientDsAmount", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientFunds", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientInputAmount", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientLiquidity", + "inputs": [ + { + "name": "available", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "requested", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InsufficientLiquidityForSwap", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientOutputAmount", + "inputs": [ + { + "name": "amountOutMin", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InsufficientOutputAmountForSwap", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientPaAmount", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidAddress", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidAmount", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidAsset", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "InvalidExpiry", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidFee", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidFees", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInput", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidPairId", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidParam", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidParams", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidRate", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidS", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidSignature", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidToken", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidValue", + "inputs": [] + }, + { + "type": "error", + "name": "LVDepositPaused", + "inputs": [] + }, + { + "type": "error", + "name": "LVWithdrawalPaused", + "inputs": [] + }, + { + "type": "error", + "name": "LimitTooLong", + "inputs": [ + { + "name": "max", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "MintCapExceeded", + "inputs": [] + }, + { + "type": "error", + "name": "NavBelowThreshold", + "inputs": [ + { + "name": "referenceNav", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "delta", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "currentNav", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "NoConverge", + "inputs": [] + }, + { + "type": "error", + "name": "NoLowerBound", + "inputs": [] + }, + { + "type": "error", + "name": "NoSender", + "inputs": [] + }, + { + "type": "error", + "name": "NoSignChange", + "inputs": [] + }, + { + "type": "error", + "name": "NoValidDSExist", + "inputs": [] + }, + { + "type": "error", + "name": "NotConfig", + "inputs": [] + }, + { + "type": "error", + "name": "NotDefaultAdmin", + "inputs": [] + }, + { + "type": "error", + "name": "NotEnoughLiquidity", + "inputs": [] + }, + { + "type": "error", + "name": "NotExist", + "inputs": [ + { + "name": "ra", + "type": "address", + "internalType": "address" + }, + { + "name": "pa", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "NotExpired", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitialized", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "NotModuleCore", + "inputs": [] + }, + { + "type": "error", + "name": "NotOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "msgSender", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "NotYetClaimable", + "inputs": [ + { + "name": "claimableAt", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "blockTimestamp", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "OnlyConfigAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyDissolverOrHURouterAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyFlashSwapRouterAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyLiquidator", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyLiquidatorOrOwner", + "inputs": [] + }, + { + "type": "error", + "name": "OnlySelfCall", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyTrampoline", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyVault", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyWhiteListed", + "inputs": [] + }, + { + "type": "error", + "name": "OwnableInvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "OwnableUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "PRBMath_MulDiv_Overflow", + "inputs": [ + { + "name": "x", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "y", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "denominator", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "PRBMath_UD60x18_Convert_Overflow", + "inputs": [ + { + "name": "x", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "PSMDepositPaused", + "inputs": [] + }, + { + "type": "error", + "name": "PSMRepurchasePaused", + "inputs": [] + }, + { + "type": "error", + "name": "PSMWithdrawalPaused", + "inputs": [] + }, + { + "type": "error", + "name": "PermitNotSupported", + "inputs": [] + }, + { + "type": "error", + "name": "ProtectedUnitExists", + "inputs": [] + }, + { + "type": "error", + "name": "ProtectedUnitNotExists", + "inputs": [] + }, + { + "type": "error", + "name": "ReentrancyGuardReentrantCall", + "inputs": [] + }, + { + "type": "error", + "name": "RolloverNotActive", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "StateLocked", + "inputs": [] + }, + { + "type": "error", + "name": "TooBig", + "inputs": [] + }, + { + "type": "error", + "name": "UUPSUnauthorizedCallContext", + "inputs": [] + }, + { + "type": "error", + "name": "UUPSUnsupportedProxiableUUID", + "inputs": [ + { + "name": "slot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "Unauthorized", + "inputs": [ + { + "name": "caller", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "Uninitialized", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroDeposit", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroReserve", + "inputs": [] + } +] \ No newline at end of file diff --git a/abi/cork_module_core.json b/abi/cork_module_core.json deleted file mode 100644 index d2c20a5..0000000 --- a/abi/cork_module_core.json +++ /dev/null @@ -1,2251 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "address", - "name": "target", - "type": "address" - } - ], - "name": "AddressEmptyCode", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyInitialized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "ERC1967InvalidImplementation", - "type": "error" - }, - { - "inputs": [], - "name": "ERC1967NonPayable", - "type": "error" - }, - { - "inputs": [], - "name": "FailedInnerCall", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "available", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "requested", - "type": "uint256" - } - ], - "name": "InsufficientLiquidity", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - } - ], - "name": "InvalidAsset", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidFees", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidInitialization", - "type": "error" - }, - { - "inputs": [], - "name": "LVDepositPaused", - "type": "error" - }, - { - "inputs": [], - "name": "LVWithdrawalPaused", - "type": "error" - }, - { - "inputs": [], - "name": "NotExpired", - "type": "error" - }, - { - "inputs": [], - "name": "NotInitializing", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyConfigAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyFlashSwapRouterAllowed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnableInvalidOwner", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "OwnableUnauthorizedAccount", - "type": "error" - }, - { - "inputs": [], - "name": "PSMDepositPaused", - "type": "error" - }, - { - "inputs": [], - "name": "PSMWithdrawalPaused", - "type": "error" - }, - { - "inputs": [], - "name": "StateLocked", - "type": "error" - }, - { - "inputs": [], - "name": "UUPSUnauthorizedCallContext", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "slot", - "type": "bytes32" - } - ], - "name": "UUPSUnsupportedProxiableUUID", - "type": "error" - }, - { - "inputs": [], - "name": "Uinitialized", - "type": "error" - }, - { - "inputs": [], - "name": "Uinitialized", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroDeposit", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "redeemer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "raAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dSexchangeRates", - "type": "uint256" - } - ], - "name": "Cancelled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "redeemer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "paReceived", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "raReceived", - "type": "uint256" - } - ], - "name": "CtRedeemed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "redeemer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dsExchangeRate", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "DsRedeemed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "earlyRedemptionFeeRate", - "type": "uint256" - } - ], - "name": "EarlyRedemptionFeeRateUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "newEarlyRedemptionFee", - "type": "uint256" - } - ], - "name": "EarlyRedemptionFeeUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "version", - "type": "uint64" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "pa", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "ra", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "lv", - "type": "address" - } - ], - "name": "InitializedModuleCore", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "expiry", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "ds", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "ct", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "raCtUniPair", - "type": "address" - } - ], - "name": "Issued", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "depositor", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "LvDeposited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "redeemer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - } - ], - "name": "LvRedeemEarly", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "isPSMDepositPaused", - "type": "bool" - }, - { - "indexed": false, - "internalType": "bool", - "name": "isPSMWithdrawalPaused", - "type": "bool" - }, - { - "indexed": false, - "internalType": "bool", - "name": "isLVDepositPaused", - "type": "bool" - }, - { - "indexed": false, - "internalType": "bool", - "name": "isLVWithdrawalPaused", - "type": "bool" - } - ], - "name": "PoolsStatusUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "depositor", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "exchangeRate", - "type": "uint256" - } - ], - "name": "PsmDeposited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "repurchaseFeeRate", - "type": "uint256" - } - ], - "name": "RepurchaseFeeRateUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "buyer", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "raUsed", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "exchangeRates", - "type": "uint256" - } - ], - "name": "Repurchased", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "currentDsId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "prevDsId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountCtRolledOver", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dsReceived", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "ctReceived", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "paReceived", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "exchangeRate", - "type": "uint256" - } - ], - "name": "RolledOver", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "Id", - "name": "Id", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "profit", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "remainingDs", - "type": "uint256" - } - ], - "name": "RolloverProfitClaimed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "inputs": [], - "name": "UPGRADE_INTERFACE_VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "availableForRepurchase", - "outputs": [ - { - "internalType": "uint256", - "name": "pa", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "ds", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseRedemptionFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "claimAutoSellProfit", - "outputs": [ - { - "internalType": "uint256", - "name": "profit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsReceived", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "depositLv", - "outputs": [ - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "depositPsm", - "outputs": [ - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_exchangeRate", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "earlyRedemptionFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "exchangeRate", - "outputs": [ - { - "internalType": "uint256", - "name": "rates", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pa", - "type": "address" - }, - { - "internalType": "address", - "name": "ra", - "type": "address" - } - ], - "name": "getId", - "outputs": [ - { - "internalType": "Id", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_swapAssetFactory", - "type": "address" - }, - { - "internalType": "address", - "name": "_ammFactory", - "type": "address" - }, - { - "internalType": "address", - "name": "_flashSwapRouter", - "type": "address" - }, - { - "internalType": "address", - "name": "_ammRouter", - "type": "address" - }, - { - "internalType": "address", - "name": "_config", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_psmBaseRedemptionFeePrecentage", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pa", - "type": "address" - }, - { - "internalType": "address", - "name": "ra", - "type": "address" - }, - { - "internalType": "uint256", - "name": "lvFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "initialDsPrice", - "type": "uint256" - } - ], - "name": "initializeModuleCore", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "expiry", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "exchangeRates", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "repurchaseFeePrecentage", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "decayDiscountRateInDays", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rolloverPeriodInblocks", - "type": "uint256" - } - ], - "name": "issueNewDs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "lastDsId", - "outputs": [ - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "lvAcceptRolloverProfit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "previewDepositPsm", - "outputs": [ - { - "internalType": "uint256", - "name": "ctReceived", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsReceived", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "previewLvDeposit", - "outputs": [ - { - "internalType": "uint256", - "name": "lv", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "previewRedeemEarlyLv", - "outputs": [ - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "previewRedeemRaWithCtDs", - "outputs": [ - { - "internalType": "uint256", - "name": "ra", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rates", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "previewRedeemRaWithDs", - "outputs": [ - { - "internalType": "uint256", - "name": "assets", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "previewRedeemWithCt", - "outputs": [ - { - "internalType": "uint256", - "name": "paReceived", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "raReceived", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "previewRepurchase", - "outputs": [ - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "exchangeRates", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "provideLiquidityWithFlashSwapFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "proxiableUUID", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "profit", - "type": "uint256" - } - ], - "name": "psmAcceptFlashSwapProfit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "rawLvPermitSig", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - } - ], - "name": "redeemEarlyLv", - "outputs": [ - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - } - ], - "name": "redeemEarlyLv", - "outputs": [ - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "redeemRaWithCtDs", - "outputs": [ - { - "internalType": "uint256", - "name": "ra", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rates", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "rawDsPermitSig", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "dsDeadline", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "rawCtPermitSig", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "ctDeadline", - "type": "uint256" - } - ], - "name": "redeemRaWithCtDs", - "outputs": [ - { - "internalType": "uint256", - "name": "ra", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rates", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "redeemRaWithDs", - "outputs": [ - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_exchangeRate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "rawDsPermitSig", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "redeemRaWithDs", - "outputs": [ - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_exchangeRate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "redeemWithCT", - "outputs": [ - { - "internalType": "uint256", - "name": "accruedPa", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "accruedRa", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "rawCtPermitSig", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "redeemWithCT", - "outputs": [ - { - "internalType": "uint256", - "name": "accruedPa", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "accruedRa", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "repurchase", - "outputs": [ - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feePrecentage", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "exchangeRates", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "repurchaseFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "repurchaseRates", - "outputs": [ - { - "internalType": "uint256", - "name": "rates", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - } - ], - "name": "rolloverCt", - "outputs": [ - { - "internalType": "uint256", - "name": "ctReceived", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsReceived", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_exchangeRate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "paReceived", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "rawCtPermitSig", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "ctDeadline", - "type": "uint256" - } - ], - "name": "rolloverCt", - "outputs": [ - { - "internalType": "uint256", - "name": "ctReceived", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dsReceived", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_exchangeRate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "paReceived", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - } - ], - "name": "rolloverProfitRemaining", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dsId", - "type": "uint256" - } - ], - "name": "swapAsset", - "outputs": [ - { - "internalType": "address", - "name": "ct", - "type": "address" - }, - { - "internalType": "address", - "name": "ds", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "underlyingAsset", - "outputs": [ - { - "internalType": "address", - "name": "ra", - "type": "address" - }, - { - "internalType": "address", - "name": "pa", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "newEarlyRedemptionFeeRate", - "type": "uint256" - } - ], - "name": "updateEarlyRedemptionFeeRate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "bool", - "name": "isPSMDepositPaused", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isPSMWithdrawalPaused", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isLVDepositPaused", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isLVWithdrawalPaused", - "type": "bool" - } - ], - "name": "updatePoolsStatus", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "internalType": "bool", - "name": "status", - "type": "bool" - } - ], - "name": "updatePsmAutoSellStatus", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "newPsmBaseRedemptionFeePrecentage", - "type": "uint256" - } - ], - "name": "updatePsmBaseRedemptionFeePrecentage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "newRepurchaseFeePrecentage", - "type": "uint256" - } - ], - "name": "updateRepurchaseFeeRate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "valueLocked", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "Id", - "name": "id", - "type": "bytes32" - } - ], - "name": "vaultLp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file diff --git a/constants/cork.py b/constants/cork.py index 830e704..014340e 100644 --- a/constants/cork.py +++ b/constants/cork.py @@ -13,27 +13,27 @@ class TokenType(Enum): RA = 1 PA = 2 -PAGINATION_SIZE = 2000 +PAGINATION_SIZE = 5000 ZERO_ADDRESS = Web3.to_checksum_address("0x0000000000000000000000000000000000000000") ABI_PATH = pathlib.Path(__file__).parent.parent / "abi" with open(ABI_PATH / "ERC20_abi.json") as f: ERC20_ABI = json.load(f) -with open(ABI_PATH / "cork_module_core.json") as f: +with open(ABI_PATH / "cork" / "ModuleCore.json") as f: MODULE_CORE_ABI = json.load(f) -with open(ABI_PATH / "ICorkHook.json") as f: +with open(ABI_PATH / "cork" / "ICorkHook.json") as f: ICORK_HOOK_ABI = json.load(f) PSM_ADDRESS_BY_CHAIN = { - Chain.ETHEREUM: Web3.to_checksum_address("0xF6a5b7319DfBc84EB94872478be98462aA9Aab99"), + Chain.ETHEREUM: Web3.to_checksum_address("0xCCd90F6435dd78C4ECCED1FA4db0D7242548a2a9"), Chain.SEPOLIA: Web3.to_checksum_address("0xF6a5b7319DfBc84EB94872478be98462aA9Aab99"), } LV_ADDRESS_BY_CHAIN = PSM_ADDRESS_BY_CHAIN AMM_ADDRESS_BY_CHAIN = { - Chain.ETHEREUM: Web3.to_checksum_address("0xf190c07670Db093962814393daCbF833CE02ea88"), + Chain.ETHEREUM: Web3.to_checksum_address("0x5287E8915445aee78e10190559D8Dd21E0E9Ea88"), Chain.SEPOLIA: Web3.to_checksum_address("0xf190c07670Db093962814393daCbF833CE02ea88"), } @@ -60,15 +60,15 @@ class TokenType(Enum): } # block height of first deployment of contract or pair -PSM_USDE_START_BLOCK_BY_CHAIN = { - Chain.ETHEREUM: 21725765, - Chain.SEPOLIA: 7414863, +USDE_START_BLOCK_BY_CHAIN = { + Chain.ETHEREUM: 21843727, + Chain.SEPOLIA: 7214863, } # block height of first deployment of contract or pair -PSM_SUSDE_START_BLOCK_BY_CHAIN = { - Chain.ETHEREUM: 21725765, - Chain.SEPOLIA: 7414863, +SUSDE_START_BLOCK_BY_CHAIN = { + Chain.ETHEREUM: 21843728, + Chain.SEPOLIA: 7214863, } # See: https://docs.ethena.fi/solution-design/key-addresses @@ -81,5 +81,5 @@ class TokenType(Enum): SUSDE_TOKEN_ADDRESS_FOR_L2 = Web3.to_checksum_address("0x211Cc4DD073734dA055fbF44a2b4667d5E5fE5d2") SUSDE_TOKEN_ADDRESS_BY_CHAIN = defaultdict(lambda: SUSDE_TOKEN_ADDRESS_FOR_L2, { - Chain.ETHEREUM: Web3.to_checksum_address("0x9d39a5de30e57443bff2a8307a4256c8797a3497"), + Chain.ETHEREUM: Web3.to_checksum_address("0x9D39A5DE30e57443BfF2A8307A4256c8797A3497"), }) diff --git a/integrations/cork_susde.py b/integrations/cork_susde.py index f01e20f..09de2e1 100644 --- a/integrations/cork_susde.py +++ b/integrations/cork_susde.py @@ -2,7 +2,7 @@ from copy import deepcopy from decimal import Decimal from dataclasses import dataclass, field -from typing import Callable, Dict, List, NewType, Optional, Set, NamedTuple +from typing import Callable, Dict, List, NewType, Optional, Set, NamedTuple, Tuple, Union from web3 import Web3 from eth_typing import ChecksumAddress @@ -10,11 +10,9 @@ from constants.chains import Chain from constants.summary_columns import SummaryColumn from constants.cork import ( - # AMM_ADDRESS_BY_CHAIN, - AMM_ADDRESS_BY_CHAIN, AMM_CONTRACT_BY_CHAIN, SUSDE_TOKEN_ADDRESS_BY_CHAIN, - PSM_SUSDE_START_BLOCK_BY_CHAIN, + SUSDE_START_BLOCK_BY_CHAIN, PSM_CONTRACT_BY_CHAIN, LV_ADDRESS_BY_CHAIN, PAGINATION_SIZE, @@ -28,7 +26,6 @@ from utils.web3_utils import ( MULTICALL_ADDRESS_BY_CHAIN, fetch_events_logs_with_retry, - multicall, W3_BY_CHAIN, multicall_by_address, ) @@ -53,7 +50,7 @@ class TermConfig(NamedTuple): share_token_addr: PsmShareTokenAddress - amm_lp_token_addr: LpTokenAddress + amm_lp_token_addr: Optional[LpTokenAddress] amm_pool_addr: ChecksumAddress start_block: int @@ -80,8 +77,8 @@ class PooledBalance: pair_config: PairConfig term_config: Optional[TermConfig] = None - total_assets: int = 0 - # total_assets_by_token: Dict[ChecksumAddress, int | Decimal] = {} + total_assets: Union[int, Tuple[int, ...]] = 0 + # total_assets_by_token: Dict[ChecksumAddress, int] = {} total_supply: int = 0 shares_by_account: Dict[ChecksumAddress, int] = field(default_factory=dict) @@ -90,6 +87,7 @@ class CorkIntegration(CachedBalancesIntegration): def __init__( self, integration_id: IntegrationID, + eligible_token_addr: ChecksumAddress, start_block: int, chain: Chain = Chain.SEPOLIA, summary_cols: Optional[List[SummaryColumn]] = None, @@ -114,7 +112,7 @@ def __init__( ) self.w3 = W3_BY_CHAIN[self.chain]["w3"] - self.eligible_token_addr = SUSDE_TOKEN_ADDRESS_BY_CHAIN[self.chain] + self.eligible_token_addr = eligible_token_addr self.pair_config_by_id: Dict[bytes, PairConfig] = None self.psm_contract = PSM_CONTRACT_BY_CHAIN[self.chain] @@ -123,8 +121,10 @@ def __init__( ) self.amm_contract = AMM_CONTRACT_BY_CHAIN[self.chain] + self.amm_pool_addr: Optional[ChecksumAddress] = None self.amm_balances_by_lp_token: Dict[LpTokenAddress, PooledBalance] = None + self.vault_contract = PSM_CONTRACT_BY_CHAIN[self.chain] self.vault_balances_by_vault_share_token: Dict[ VaultShareTokenAddress, PooledBalance ] = None @@ -132,26 +132,25 @@ def __init__( def update_pair_config( self, pair_config_by_id: Dict[bytes, PairConfig], - from_block: Optional[int] = None, + from_block: int, to_block: int | str = "latest", ) -> Dict[bytes, PairConfig]: # Fetch events that indicates new pair was created - print("from_block", from_block) - print("self.start_block", self.start_block) - print("to_block", to_block) + print("from_block\t", from_block) + print("to_block\t", to_block) new_pair_events_with_eligible_pa = fetch_events_logs_with_retry( - "Pairs initialized with USDe as PA", + "Pair Initialized with USDe as PA", self.psm_contract.events.InitializedModuleCore(), - from_block or self.start_block, + from_block, to_block, filter={ "pa": self.eligible_token_addr, }, ) new_pair_events_with_eligible_ra = fetch_events_logs_with_retry( - "Pairs initialized with USDe as RA", + "Pair Initialized with USDe as RA", self.psm_contract.events.InitializedModuleCore(), - from_block or self.start_block, + from_block, to_block, filter={ "ra": self.eligible_token_addr, @@ -200,33 +199,57 @@ def update_pair_config( } ) + # Uniswap v4 Native Liquidity Modification is disabled on Cork AMM pools, + # which also prevents the creation of LP tokens (NFT) by the Uniswap V4 Position Manager. + # Fetch events emitted by Cork's custom UniV4 Hook, + # that indicates new LP token (ERC20) was created. + # event Initialized(address indexed ra, address indexed ct, address liquidityToken); + new_lpt_events = fetch_events_logs_with_retry( + "LPT Initialized on pairs with USDe", + self.amm_contract.events.Initialized(), + from_block, + to_block, + filter = { + "ra": [ + pair_config.amm_quote_token_addr + for pair_config in pair_config_by_id.values() + ], + }, + ) + # For each pair, update term config... for pair_id, pair_config in pair_config_by_id.items(): + start_block = max(from_block, pair_config.start_block) + if len(new_lpt_events) > 0: + # print(f"Found {len(new_lpt_events)} new LPT events") + # Update the LP token address for each term + for term_id, term_config in pair_config.terms.items(): + if term_config.amm_lp_token_addr is None: + # Find the LP token address for the given CT token + amm_lp_token_addr = next(( + Web3.to_checksum_address(lpt_event["args"]["liquidityToken"]) + for lpt_event in new_lpt_events + if lpt_event["args"]["ct"] == term_config.share_token_addr + ), None) + + if amm_lp_token_addr is not None: + pair_config.terms[term_id] = term_config._replace( + amm_lp_token_addr=amm_lp_token_addr + ) + # Fetch events that indicate a new term was issued/started new_term_events_of_pair = fetch_events_logs_with_retry( - "Issuance on pairs with USDe", + "Term Initialized on pairs with USDe", self.psm_contract.events.Issued(), - pair_config.start_block or self.start_block, + start_block, to_block, filter={ "id": pair_id, }, ) - # Get LP token address - # WORKAROUND: until LP token address is available from Issued event - amm_contract_function = self.amm_contract.functions.getLiquidityToken - amm_calls = [ - ( - self.amm_contract, - amm_contract_function.fn_name, - [pair_config.amm_quote_token_addr, event["args"]["ct"]], - ) - for event in new_term_events_of_pair - ] - multicall_results = multicall(self.w3, amm_calls, to_block) - for event, result in zip(new_term_events_of_pair, multicall_results): - event["args"]["lpt"] = result[0] + # if len(new_term_events_of_pair) > 0: + # print(f"Found {len(new_term_events_of_pair)} new Term events") # For each term, update config... for event in new_term_events_of_pair: @@ -246,12 +269,24 @@ def update_pair_config( # the `ds_id` identifies each term, but is not unique globally (across pairs) term_id: TermId = TermId(event["args"]["dsId"]) + # Find the LP token address for the given CT token + # event Initialized(address indexed ra, address indexed ct, address liquidityToken); + amm_lp_token_addr = next(( + Web3.to_checksum_address(lpt_event["args"]["liquidityToken"]) + for lpt_event in new_lpt_events + if lpt_event["args"]["ct"] == event["args"]["ct"] + ), None) + + # In Uniswap v4, the Pool Manager contract address holds the reserves of the pool + if self.amm_pool_addr is None: + self.amm_pool_addr = self.amm_contract.functions.getPoolManager().call() + # the `share_token_addr` is unique and only valid for each term (or issuance) # the `lp_token_addr` is also unique and only valid for each term (or issuance) term_config = TermConfig( share_token_addr=Web3.to_checksum_address(event["args"]["ct"]), - amm_lp_token_addr=Web3.to_checksum_address(event["args"]["lpt"]), - amm_pool_addr=self.amm_contract.address, + amm_lp_token_addr=amm_lp_token_addr, + amm_pool_addr=self.amm_pool_addr, start_block=event["blockNumber"], ) @@ -262,7 +297,7 @@ def update_pair_config( def update_psm_pool_balances( self, pool_balances: Dict[PsmShareTokenAddress, PooledBalance], - from_block: int = 0, + from_block: int, to_block: int | str = "latest", ) -> Dict[PsmShareTokenAddress, PooledBalance]: # For each pair... @@ -286,7 +321,25 @@ def update_psm_pool_balances( "id": pair_id, "dsId": int(term_id), }, - ) + ) if pair_config.eligible_asset == TokenType.RA else [] + # for e in deposit_events: + # print("PsmDeposited", e["args"]["amount"], e["blockNumber"]) + + # event Cancelled(Id indexed id, uint256 indexed dsId, address indexed redeemer, uint256 raAmount, uint256 swapAmount) + # IN: CT + DS + # OUT: RA + early_withdraw_events = fetch_events_logs_with_retry( + "Early Withdraw using CT + DS on pairs with USDe", + self.psm_contract.events.Cancelled(), + start_block, + to_block, + filter={ + "id": pair_id, + "dsId": int(term_id), + }, + ) if pair_config.eligible_asset == TokenType.RA else [] + # for e in early_withdraw_events: + # print("Cancelled", e["args"]["raAmount"], e["blockNumber"]) # event CtRedeemed(Id indexed id, uint256 indexed dsId, address indexed redeemer, uint256 amount, uint256 paReceived, uint256 raReceived) # IN: CT @@ -301,10 +354,12 @@ def update_psm_pool_balances( "dsId": int(term_id), }, ) + # for e in withdraw_events: + # print("CtRedeemed", -e["args"]["raReceived"], e["blockNumber"]) # event DsRedeemed(Id indexed id, uint256 indexed dsId, address indexed redeemer, uint256 paUsed, uint256 dsUsed, uint256 raReceived, uint256 dsExchangeRate, uint256 feePercentage, uint256 fee) # IN: DS + PA - # OUT: RA + # OUT: RA + fee redeem_events = fetch_events_logs_with_retry( "Redeem using DS on pairs with USDe", self.psm_contract.events.DsRedeemed(), @@ -315,9 +370,11 @@ def update_psm_pool_balances( "dsId": int(term_id), }, ) + # for e in redeem_events: + # print("DsRedeemed", -(e["args"]["raReceived"] + e["args"]["fee"]), e["blockNumber"]) # event Repurchased(Id indexed id, address indexed buyer, uint256 indexed dsId, uint256 raUsed, uint256 receivedPa, uint256 receivedDs, uint256 feePercentage, uint256 fee, uint256 exchangeRates) - # IN: RA + # IN: RA (raUsed includes fee) # OUT: PA + DS repurchase_events = fetch_events_logs_with_retry( "Repurchase on pairs with USDe", @@ -329,36 +386,44 @@ def update_psm_pool_balances( "dsId": int(term_id), }, ) + # for e in repurchase_events: + # print("Repurchased", e["args"]["raUsed"] - e["args"]["fee"], e["blockNumber"]) # pylint: enable=line-too-long + + # Includes Rollover Events if pair_config.eligible_asset == TokenType.RA: balance_in = sum( - [event["args"]["amount"] for event in deposit_events] - + [event["args"]["raUsed"] for event in repurchase_events] + [e["args"]["amount"] for e in deposit_events] + + [e["args"]["raUsed"] - e["args"]["fee"] for e in repurchase_events] ) balance_out = sum( - [event["args"]["raReceived"] for event in withdraw_events] - + [event["args"]["raReceived"] for event in redeem_events] + [e["args"]["raAmount"] for e in early_withdraw_events] + + [e["args"]["raReceived"] for e in withdraw_events] + + [e["args"]["raReceived"] + e["args"]["fee"] for e in redeem_events] ) elif pair_config.eligible_asset == TokenType.PA: balance_in = sum( - [event["args"]["paUsed"] for event in redeem_events] + [e["args"]["paUsed"] for e in redeem_events] ) balance_out = sum( - [event["args"]["paReceived"] for event in withdraw_events] - + [event["args"]["receivedPa"] for event in repurchase_events] + [e["args"]["paReceived"] for e in withdraw_events] + + [e["args"]["receivedPa"] for e in repurchase_events] ) else: raise NotImplementedError("Token type not yet implemented") # Get pooled balances of each PSM share_token_addr = term_config.share_token_addr - pool_balances.setdefault( + pool = pool_balances.setdefault( share_token_addr, PooledBalance(pair_config, term_config) ) - pool = pool_balances[share_token_addr] # Update asset balance of PSM pool pool.total_assets += balance_in - balance_out + # if balance_in or balance_out: + # print("balance_in\t", balance_in) + # print("balance_out\t", balance_out) + # print("psm_pool.total_assets", pool.total_assets, to_block) # For each token, accumulate all balance changes from Transfer events... token_contract = self.w3.eth.contract( @@ -379,40 +444,41 @@ def update_psm_pool_balances( value = int(transfer["args"]["value"]) sender = Web3.to_checksum_address(transfer["args"]["from"]) - if sender not in self.excluded_addresses: - pool.shares_by_account.setdefault(sender, 0) - pool.shares_by_account[sender] -= value - elif sender == ZERO_ADDRESS: + if sender == ZERO_ADDRESS: # token was minted, update total supply pool.total_supply += value + elif sender not in self.excluded_addresses: + pool.shares_by_account.setdefault(sender, 0) + pool.shares_by_account[sender] -= value recipient = Web3.to_checksum_address(transfer["args"]["to"]) - if recipient not in self.excluded_addresses: - pool.shares_by_account.setdefault(recipient, 0) - pool.shares_by_account[recipient] += value - elif sender == ZERO_ADDRESS: + if recipient == ZERO_ADDRESS: # token was burned, update total supply pool.total_supply -= value + elif recipient not in self.excluded_addresses: + pool.shares_by_account.setdefault(recipient, 0) + pool.shares_by_account[recipient] += value return pool_balances def update_amm_pool_balances( self, pool_balances: Dict[LpTokenAddress, PooledBalance], - from_block: int = 0, + from_block, to_block: int | str = "latest", ) -> Dict[LpTokenAddress, PooledBalance]: # For each pair... for _pair_id, pair_config in self.pair_config_by_id.items(): # For each term... - for _term_id, term_config in pair_config.terms.items(): + for term_config in ( + v for v in pair_config.terms.values() if v.amm_lp_token_addr is not None + ): start_block = max(from_block, term_config.start_block) # Get pooled balances of each AMM pair lp_token_addr = term_config.amm_lp_token_addr - pool_balances.setdefault( + pool = pool_balances.setdefault( lp_token_addr, PooledBalance(pair_config, term_config) ) - pool = pool_balances[lp_token_addr] # For each token, accumulate all balance changes from Transfer events... token_contract = self.w3.eth.contract( @@ -433,26 +499,26 @@ def update_amm_pool_balances( value = int(transfer["args"]["value"]) sender = Web3.to_checksum_address(transfer["args"]["from"]) - if sender not in self.excluded_addresses: - pool.shares_by_account.setdefault(sender, 0) - pool.shares_by_account[sender] -= value - elif sender == ZERO_ADDRESS: + if sender == ZERO_ADDRESS: # token was minted, update total supply pool.total_supply += value + elif sender not in self.excluded_addresses: + pool.shares_by_account.setdefault(sender, 0) + pool.shares_by_account[sender] -= value recipient = Web3.to_checksum_address(transfer["args"]["to"]) - if recipient not in self.excluded_addresses: - pool.shares_by_account.setdefault(recipient, 0) - pool.shares_by_account[recipient] += value - elif sender == ZERO_ADDRESS: + if recipient == ZERO_ADDRESS: # token was burned, update total supply pool.total_supply -= value + elif recipient not in self.excluded_addresses: + pool.shares_by_account.setdefault(recipient, 0) + pool.shares_by_account[recipient] += value return pool_balances def update_vault_pool_balances( self, pool_balances: Dict[VaultShareTokenAddress, PooledBalance], - from_block: int = 0, + from_block: int, to_block: int | str = "latest", ) -> Dict[VaultShareTokenAddress, PooledBalance]: # For each pair... @@ -460,8 +526,7 @@ def update_vault_pool_balances( start_block = max(from_block, pair_config.start_block) vault_share_token_addr = pair_config.vault_share_token_addr - pool_balances.setdefault(vault_share_token_addr, PooledBalance(pair_config)) - pool = pool_balances[pool_balances] + pool = pool_balances.setdefault(vault_share_token_addr, PooledBalance(pair_config)) # For each token, accumulate all balance changes from Transfer events... token_contract = self.w3.eth.contract( @@ -482,20 +547,20 @@ def update_vault_pool_balances( value = int(transfer["args"]["value"]) sender = Web3.to_checksum_address(transfer["args"]["from"]) - if sender not in self.excluded_addresses: - pool.shares_by_account.setdefault(sender, 0) - pool.shares_by_account[sender] -= value - elif sender == ZERO_ADDRESS: + if sender == ZERO_ADDRESS: # token was minted, update total supply pool.total_supply += value + elif sender not in self.excluded_addresses: + pool.shares_by_account.setdefault(sender, 0) + pool.shares_by_account[sender] -= value recipient = Web3.to_checksum_address(transfer["args"]["to"]) - if recipient not in self.excluded_addresses: - pool.shares_by_account.setdefault(recipient, 0) - pool.shares_by_account[recipient] += value - elif sender == ZERO_ADDRESS: + if recipient == ZERO_ADDRESS: # token was burned, update total supply pool.total_supply -= value + elif recipient not in self.excluded_addresses: + pool.shares_by_account.setdefault(recipient, 0) + pool.shares_by_account[recipient] += value return pool_balances def get_block_balances( @@ -536,7 +601,7 @@ def get_block_balances( ) # loop through the sorted blocks and find the closest previous block - prev_block = self.start_block - 1 + prev_block = self.start_block start = prev_block + 1 account_bals: Dict[ChecksumAddress, Decimal | float] = {} @@ -547,29 +612,29 @@ def get_block_balances( account_bals = deepcopy(cache_copy_of_account_bals[prev_block]) break - # Fetch pair config at prev_block if not already done + # Fetch pair config from self.start_block if not already done if self.pair_config_by_id is None: self.pair_config_by_id = self.update_pair_config( - {}, from_block=prev_block, to_block=start + {}, from_block=self.start_block, to_block=prev_block ) - # Fetch Peg Stability term balances at prev_block if not already done + # Fetch Peg Stability term balances from self.start_block if not already done if self.psm_balances_by_share_token is None: self.psm_balances_by_share_token = self.update_psm_pool_balances( - {}, from_block=prev_block, to_block=start + {}, from_block=self.start_block, to_block=prev_block ) - # Fetch AMM Liquidity Pool term balances at prev_block if not already done + # Fetch AMM Liquidity Pool term balances from self.start_block if not already done if self.amm_balances_by_lp_token is None: self.amm_balances_by_lp_token = self.update_amm_pool_balances( - {}, from_block=prev_block, to_block=start + {}, from_block=self.start_block, to_block=prev_block ) - # Fetch Vault term balances at prev_block if not already done + # Fetch Vault term balances from self.start_block if not already done if self.vault_balances_by_vault_share_token is None: self.vault_balances_by_vault_share_token = ( self.update_vault_pool_balances( - {}, from_block=prev_block, to_block=start + {}, from_block=self.start_block, to_block=prev_block ) ) @@ -600,17 +665,53 @@ def get_block_balances( # continue pagination # finished pagination loop, block height reached... - # Filter out non-eligible AMM pools - eligible_amm_balances = { - lp_token_addr: amm_pool - for lp_token_addr, amm_pool in self.amm_balances_by_lp_token.items() - if amm_pool.pair_config.amm_quote_token_addr == self.eligible_token_addr - } - # Fetch the reserve asset balances of each eligible AMM pool + # Fetch the idle asset balance of each eligible Vault pool + vault_contract_function = self.vault_contract.functions.tradeExecutionFundsAvailable + pair_ids = [ + pair_id + for pair_id, pair_config in self.pair_config_by_id.items() + if pair_config.eligible_asset == TokenType.RA + ] + vault_calls = [ + ( + self.vault_contract, + vault_contract_function.fn_name, + [ + pair_id, + ], + ) + for pair_id in pair_ids + ] + multicall_results = multicall_by_address( + w3=self.w3, + multical_address=MULTICALL_ADDRESS_BY_CHAIN[self.chain], + calls=vault_calls, + block_identifier=block, + ) + + # The results contain the following: + # - The `result[0]` is the total balance of the asset token in the vault pool + for pair_id, result in zip( + pair_ids, multicall_results + ): + # Update the total idle asset balance of each vault pool + pair_config = self.pair_config_by_id[pair_id] + vault_pool = self.vault_balances_by_vault_share_token[ + pair_config.vault_share_token_addr + ] + vault_pool.total_assets = result[0] + print("vault_pool.total_assets", vault_pool.total_assets, block) + + # Uniswap V4 doesn’t store reserves explicitly in storage. + # Instead, reserves are inferred from the pool’s liquidity and price data, + # necessitating off-chain computation of contract events for precise reserve values. + # Instead, use the `getReserves()` function on Cork's custom UniV4 Hook to, + # Fetch the reserve asset balance of each eligible AMM pool # Note: We cannot assume that all LP token holders have withdrawn # remaining reserves after end of epoch/term. amm_contract_function = self.amm_contract.functions.getReserves + amm_pools = self.amm_balances_by_lp_token.values() amm_calls = [ ( self.amm_contract, @@ -620,7 +721,7 @@ def get_block_balances( amm_pool.term_config.share_token_addr, ], ) - for amm_pool in eligible_amm_balances.values() + for amm_pool in amm_pools ] multicall_results = multicall_by_address( w3=self.w3, @@ -633,47 +734,129 @@ def get_block_balances( # - The `result[0]` is the total balance of the asset token in the AMM pool # - The `result[1]` is the total balance of the share token in the AMM pool for amm_pool, result in zip( - eligible_amm_balances.values(), multicall_results + amm_pools, multicall_results + ): + # Update the total Ethena-asset and PSM-shares balance of each AMM pool + amm_pool.total_assets = (result[0], result[1]) + print("amm_pool.total_assets", amm_pool.total_assets, block) + + # Fetch the asset balance of each eligible PSM pool + psm_contract_function = self.psm_contract.functions.valueLocked + psm_calls = [ + ( + self.psm_contract, + psm_contract_function.fn_name, + [ + pair_id, + pair_config.eligible_asset == TokenType.RA, + ] + if term_id == max(pair_config.terms) else + [ + pair_id, + term_id, + pair_config.eligible_asset == TokenType.RA, + ], + ) + for pair_id, pair_config in self.pair_config_by_id.items() + for term_id in pair_config.terms + ] + multicall_results = multicall_by_address( + w3=self.w3, + multical_address=MULTICALL_ADDRESS_BY_CHAIN[self.chain], + calls=psm_calls, + block_identifier=block, + ) + + # The results contain the following: + # - The `result[0]` is the total balance of the asset token in the psm pool + for (pair_id, term_id), result in zip( + ( + (pair_id, term_id) + for pair_id, pair_config in self.pair_config_by_id.items() + for term_id in pair_config.terms + ), + multicall_results ): - # Update the total asset balance of each AMM pool - amm_pool.total_assets = result[0] + # Update the total asset balance of each psm pool + pair_config = self.pair_config_by_id[pair_id] + term_config = pair_config.terms[term_id] + share_token_addr = term_config.share_token_addr + psm_pool = self.psm_balances_by_share_token[share_token_addr] - # Update the total shares of PSM pool of each AMM pool - # amm_pool.total_assets_by_token[amm_pool.term_config.share_token_addr] = result[1] + if int(term_id) > 1: + assert ( + psm_pool.total_assets == result[0] + ), f"psm_pool.total_assets != psm_contract.valueLocked for {pair_id}:{term_id}" + else: + psm_pool.total_assets = result[0] + print("psm_pool.total_assets", psm_pool.total_assets, block) + + # Attribute Ethena asset balances on Vault pools to their respective LV token holders + for lv_token_addr, vault_pool in ( + (lv_token_addr, vault_pool) + for lv_token_addr, vault_pool in self.vault_balances_by_vault_share_token.items() + if vault_pool.pair_config.eligible_asset == TokenType.RA + ): + print("======== LVT:", lv_token_addr, "========") + for account_addr, account_shares in vault_pool.shares_by_account.items(): + amount = ( + Decimal(vault_pool.total_assets) + * Decimal(account_shares) + / Decimal(vault_pool.total_supply) + ) + bal = account_bals.setdefault(account_addr, Decimal(0)) + account_bals[account_addr] = Decimal(bal) + amount + print( + "LVT-holder:", account_addr, + "start:", bal, + "in:", amount, + "end:", account_bals[account_addr] + ) # Attribute Ethena asset balances on AMM pools to their respective LP token holders - for amm_pool in self.amm_balances_by_lp_token.values(): + for lp_token_addr, amm_pool in ( + (lp_token_addr, amm_pool) + for lp_token_addr, amm_pool in self.amm_balances_by_lp_token.items() + if amm_pool.pair_config.amm_quote_token_addr == self.eligible_token_addr + ): + print("======== LPT:", lp_token_addr, "========") for account_addr, account_shares in amm_pool.shares_by_account.items(): amount = ( - Decimal(amm_pool.total_assets) + Decimal(amm_pool.total_assets[0]) * Decimal(account_shares) / Decimal(amm_pool.total_supply) ) # If the account_addr is the vault_addr, then we need to attribute the # Ethena asset balances to the respective LV token holders - if account_addr == amm_pool.pair_config.vault_addr: - vault_share_token_addr = ( - amm_pool.pair_config.vault_share_token_addr - ) + if account_addr == amm_pool.pair_config.vault_addr and amount: + vault_share_token_addr = amm_pool.pair_config.vault_share_token_addr vault = self.vault_balances_by_vault_share_token[ vault_share_token_addr ] for ( - account_addr, - account_shares, + account_addr, account_shares ) in vault.shares_by_account.items(): - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = Decimal( - account_bals[account_addr] - ) + ( + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( amount * Decimal(account_shares) / Decimal(vault.total_supply) ) + account_bals[account_addr] = Decimal(bal) + qty + print( + "LVT-holder:", vault_share_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) else: - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = ( - Decimal(account_bals[account_addr]) + amount + bal = account_bals.setdefault(account_addr, Decimal(0)) + account_bals[account_addr] = Decimal(bal) + amount + print( + "LPT-holder:", account_addr, + "start:", bal, + "in:", amount, + "end:", account_bals[account_addr] ) # # Attribute PSM share token balances to their respective LP token holders @@ -682,69 +865,120 @@ def get_block_balances( # psm_pool = self.psm_balances_by_share_token[share_token_addr] # account_share_token_bals = psm_pool.shares_by_account # share_amount = ( - # Decimal(amm_pool.total_assets_by_token[share_token_addr]) + # Decimal(amm_pool.total_assets[1]) # * Decimal(account_shares) # / Decimal(amm_pool.total_supply) # ) - # account_share_token_bals.setdefault(account_addr, Decimal(0)) - # bal = Decimal(account_share_token_bals[account_addr]) - # account_share_token_bals[account_addr] = bal + share_amount + # bal = account_share_token_bals.setdefault(account_addr, Decimal(0)) + # account_share_token_bals[account_addr] = Decimal(bal) + share_amount # Attribute Ethena asset balances on PSM pools to their respective CT token holders - for psm_pool in self.psm_balances_by_share_token.values(): + for share_token_addr, psm_pool in self.psm_balances_by_share_token.items(): + print("======== CT:", share_token_addr, "========") for account_addr, account_shares in psm_pool.shares_by_account.items(): amount = ( Decimal(psm_pool.total_assets) * Decimal(account_shares) / Decimal(psm_pool.total_supply) ) - # If the account_addr is the vault_addr, then we need to attribute the + # If the account_addr is the Cork Vault address, then we need to attribute the # Ethena asset balances to the respective LV token holders - if account_addr == psm_pool.pair_config.vault_addr: - vault_share_token_addr = ( - psm_pool.pair_config.vault_share_token_addr - ) + if account_addr == psm_pool.pair_config.vault_addr and amount: + vault_share_token_addr = psm_pool.pair_config.vault_share_token_addr vault = self.vault_balances_by_vault_share_token[ vault_share_token_addr ] for ( - account_addr, - account_shares, + account_addr, account_shares ) in vault.shares_by_account.items(): - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = Decimal( - account_bals[account_addr] - ) + ( + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( amount * Decimal(account_shares) / Decimal(vault.total_supply) ) - # If the account_addr is the amm_contract, then we need to attribute the - # Ethena asset balances to the respective LP token holders - elif account_addr == psm_pool.term_config.amm_pool_addr: + account_bals[account_addr] = Decimal(bal) + qty + print( + "LVT-holder:", vault_share_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) + # If the account_addr is the UniV4 PoolManager address, then we need to + # attribute the Ethena asset balances to the respective LP token holders + elif account_addr == psm_pool.term_config.amm_pool_addr and amount: lp_token_addr = psm_pool.term_config.amm_lp_token_addr amm_pool = self.amm_balances_by_lp_token[lp_token_addr] + + # If there are other Uniswap V4 pools which manage PSM-shares, + # the total amount of PSM-shares at the UniV4 PoolManager address + # will exceed the amount present in the Cork AMM pool, + # so we need to correct the attributed amount. + if account_shares > amm_pool.total_assets[1]: + amount = ( + Decimal(psm_pool.total_assets) + * Decimal(amm_pool.total_assets[1]) + / Decimal(psm_pool.total_supply) + ) for ( - account_addr, - account_shares, + account_addr, account_shares ) in amm_pool.shares_by_account.items(): - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = Decimal( - account_bals[account_addr] - ) + ( - amount - * Decimal(account_shares) - / Decimal(amm_pool.total_supply) - ) + # If the account_addr is the vault_addr, then we need to attribute the + # Ethena asset balances to the respective LV token holders + if account_addr == amm_pool.pair_config.vault_addr and amount: + vault_share_token_addr = amm_pool.pair_config.vault_share_token_addr + vault = self.vault_balances_by_vault_share_token[ + vault_share_token_addr + ] + amount = ( + amount + * Decimal(account_shares) + / Decimal(amm_pool.total_supply) + ) + for ( + account_addr, account_shares + ) in vault.shares_by_account.items(): + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( + amount + * Decimal(account_shares) + / Decimal(vault.total_supply) + ) + account_bals[account_addr] = Decimal(bal) + qty + print( + "LPT-LVT-holder:", + lp_token_addr, vault_share_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) + else: + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( + amount + * Decimal(account_shares) + / Decimal(amm_pool.total_supply) + ) + account_bals[account_addr] = Decimal(bal) + qty + print( + "LPT-holder:", lp_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) else: - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = ( - Decimal(account_bals[account_addr]) + amount + bal = account_bals.setdefault(account_addr, Decimal(0)) + account_bals[account_addr] = Decimal(bal) + amount + print( + "CT-holder:", account_addr, + "start:", bal, + "in:", amount, + "end:", account_bals[account_addr] ) # Round off to 4 decimals for account_addr, account_bal in account_bals.items(): - account_bals[account_addr] = round(account_bal / Decimal(1e18), 4) + account_bals[account_addr] = float(round(Decimal(account_bal) / Decimal(1e18), 4)) new_block_data[block] = account_bals cache_copy_of_account_bals[block] = account_bals @@ -755,13 +989,13 @@ def get_block_balances( # simple tests for the integration cork_integration = CorkIntegration( integration_id=IntegrationID.CORK_SUSDE, - start_block=PSM_SUSDE_START_BLOCK_BY_CHAIN[Chain.SEPOLIA], + eligible_token_addr=SUSDE_TOKEN_ADDRESS_BY_CHAIN[Chain.ETHEREUM], + start_block=SUSDE_START_BLOCK_BY_CHAIN[Chain.ETHEREUM], summary_cols=[SummaryColumn.CORK_PSM_PTS], - chain=Chain.SEPOLIA, + chain=Chain.ETHEREUM, reward_multiplier=50, excluded_addresses={ - Web3.to_checksum_address("0x0000000000000000000000000000000000000000"), - AMM_ADDRESS_BY_CHAIN[Chain.SEPOLIA], # exclude Cork AMMs from being counted + ZERO_ADDRESS, }, ) @@ -769,8 +1003,8 @@ def get_block_balances( print( "Run without cached data", cork_integration.get_block_balances( - cached_data={}, blocks=[7686000, 7686001, 7686002] - ), + cached_data={}, blocks=[21929053, 21929054, 21929055] + ) ) # Example output: # { @@ -784,16 +1018,16 @@ def get_block_balances( "Run with cached data", cork_integration.get_block_balances( cached_data={ - 7686000: { + 21929053: { Web3.to_checksum_address("0x0000000000000000000000000000000000000000"): 100, Web3.to_checksum_address("0x0000000000000000000000000000000000000001"): 200, }, - 7686001: { + 21929054: { Web3.to_checksum_address("0x0000000000000000000000000000000000000000"): 101, Web3.to_checksum_address("0x0000000000000000000000000000000000000001"): 201, }, }, - blocks=[7686002], + blocks=[21929055], ), ) print("=" * 120) diff --git a/integrations/cork_usde.py b/integrations/cork_usde.py index c599db5..a2b204a 100644 --- a/integrations/cork_usde.py +++ b/integrations/cork_usde.py @@ -2,7 +2,7 @@ from copy import deepcopy from decimal import Decimal from dataclasses import dataclass, field -from typing import Callable, Dict, List, NewType, Optional, Set, NamedTuple +from typing import Callable, Dict, List, NewType, Optional, Set, NamedTuple, Tuple, Union from web3 import Web3 from eth_typing import ChecksumAddress @@ -10,10 +10,9 @@ from constants.chains import Chain from constants.summary_columns import SummaryColumn from constants.cork import ( - # AMM_ADDRESS_BY_CHAIN, AMM_CONTRACT_BY_CHAIN, USDE_TOKEN_ADDRESS_BY_CHAIN, - PSM_USDE_START_BLOCK_BY_CHAIN, + USDE_START_BLOCK_BY_CHAIN, PSM_CONTRACT_BY_CHAIN, LV_ADDRESS_BY_CHAIN, PAGINATION_SIZE, @@ -24,7 +23,12 @@ from integrations.cached_balances_integration import CachedBalancesIntegration from integrations.integration_ids import IntegrationID -from utils.web3_utils import fetch_events_logs_with_retry, multicall, W3_BY_CHAIN +from utils.web3_utils import ( + MULTICALL_ADDRESS_BY_CHAIN, + fetch_events_logs_with_retry, + W3_BY_CHAIN, + multicall_by_address, +) ######################################################################## # Terminologies @@ -46,7 +50,7 @@ class TermConfig(NamedTuple): share_token_addr: PsmShareTokenAddress - amm_lp_token_addr: LpTokenAddress + amm_lp_token_addr: Optional[LpTokenAddress] amm_pool_addr: ChecksumAddress start_block: int @@ -73,8 +77,8 @@ class PooledBalance: pair_config: PairConfig term_config: Optional[TermConfig] = None - total_assets: int = 0 - # total_assets_by_token: Dict[ChecksumAddress, int | Decimal] = {} + total_assets: Union[int, Tuple[int, ...]] = 0 + # total_assets_by_token: Dict[ChecksumAddress, int] = {} total_supply: int = 0 shares_by_account: Dict[ChecksumAddress, int] = field(default_factory=dict) @@ -83,6 +87,7 @@ class CorkIntegration(CachedBalancesIntegration): def __init__( self, integration_id: IntegrationID, + eligible_token_addr: ChecksumAddress, start_block: int, chain: Chain = Chain.SEPOLIA, summary_cols: Optional[List[SummaryColumn]] = None, @@ -94,20 +99,20 @@ def __init__( ethereal_multiplier_func: Optional[Callable[[int, str], int]] = None, ): super().__init__( - integration_id=integration_id, - start_block=start_block, - chain=chain, - summary_cols=summary_cols, - reward_multiplier=reward_multiplier, - balance_multiplier=balance_multiplier, - excluded_addresses=excluded_addresses, - end_block=end_block, - ethereal_multiplier=ethereal_multiplier, - ethereal_multiplier_func=ethereal_multiplier_func, + integration_id, + start_block, + chain, + summary_cols, + reward_multiplier, + balance_multiplier, + excluded_addresses, + end_block, + ethereal_multiplier, + ethereal_multiplier_func, ) self.w3 = W3_BY_CHAIN[self.chain]["w3"] - self.eligible_token_addr = USDE_TOKEN_ADDRESS_BY_CHAIN[self.chain] + self.eligible_token_addr = eligible_token_addr self.pair_config_by_id: Dict[bytes, PairConfig] = None self.psm_contract = PSM_CONTRACT_BY_CHAIN[self.chain] @@ -116,8 +121,10 @@ def __init__( ) self.amm_contract = AMM_CONTRACT_BY_CHAIN[self.chain] + self.amm_pool_addr: Optional[ChecksumAddress] = None self.amm_balances_by_lp_token: Dict[LpTokenAddress, PooledBalance] = None + self.vault_contract = PSM_CONTRACT_BY_CHAIN[self.chain] self.vault_balances_by_vault_share_token: Dict[ VaultShareTokenAddress, PooledBalance ] = None @@ -125,23 +132,25 @@ def __init__( def update_pair_config( self, pair_config_by_id: Dict[bytes, PairConfig], - from_block: int = 0, + from_block: int, to_block: int | str = "latest", ) -> Dict[bytes, PairConfig]: # Fetch events that indicates new pair was created + print("from_block\t", from_block) + print("to_block\t", to_block) new_pair_events_with_eligible_pa = fetch_events_logs_with_retry( - "Pairs initialized with USDe as PA", + "Pair Initialized with USDe as PA", self.psm_contract.events.InitializedModuleCore(), - from_block or self.start_block, + from_block, to_block, filter={ "pa": self.eligible_token_addr, }, ) new_pair_events_with_eligible_ra = fetch_events_logs_with_retry( - "Pairs initialized with USDe as RA", + "Pair Initialized with USDe as RA", self.psm_contract.events.InitializedModuleCore(), - from_block or self.start_block, + from_block, to_block, filter={ "ra": self.eligible_token_addr, @@ -190,33 +199,57 @@ def update_pair_config( } ) + # Uniswap v4 Native Liquidity Modification is disabled on Cork AMM pools, + # which also prevents the creation of LP tokens (NFT) by the Uniswap V4 Position Manager. + # Fetch events emitted by Cork's custom UniV4 Hook, + # that indicates new LP token (ERC20) was created. + # event Initialized(address indexed ra, address indexed ct, address liquidityToken); + new_lpt_events = fetch_events_logs_with_retry( + "LPT Initialized on pairs with USDe", + self.amm_contract.events.Initialized(), + from_block, + to_block, + filter = { + "ra": [ + pair_config.amm_quote_token_addr + for pair_config in pair_config_by_id.values() + ], + }, + ) + # For each pair, update term config... for pair_id, pair_config in pair_config_by_id.items(): + start_block = max(from_block, pair_config.start_block) + if len(new_lpt_events) > 0: + # print(f"Found {len(new_lpt_events)} new LPT events") + # Update the LP token address for each term + for term_id, term_config in pair_config.terms.items(): + if term_config.amm_lp_token_addr is None: + # Find the LP token address for the given CT token + amm_lp_token_addr = next(( + Web3.to_checksum_address(lpt_event["args"]["liquidityToken"]) + for lpt_event in new_lpt_events + if lpt_event["args"]["ct"] == term_config.share_token_addr + ), None) + + if amm_lp_token_addr is not None: + pair_config.terms[term_id] = term_config._replace( + amm_lp_token_addr=amm_lp_token_addr + ) + # Fetch events that indicate a new term was issued/started new_term_events_of_pair = fetch_events_logs_with_retry( - "Issuance on pairs with USDe", + "Term Initialized on pairs with USDe", self.psm_contract.events.Issued(), - pair_config.start_block or self.start_block, + start_block, to_block, filter={ "id": pair_id, }, ) - # Get LP token address - # WORKAROUND: until LP token address is available from Issued event - amm_contract_function = self.amm_contract.functions.getLiquidityToken - amm_calls = [ - ( - self.amm_contract, - amm_contract_function.fn_name, - [pair_config.amm_quote_token_addr, event["args"]["ct"]], - ) - for event in new_term_events_of_pair - ] - multicall_results = multicall(self.w3, amm_calls, to_block) - for event, result in zip(new_term_events_of_pair, multicall_results): - event["args"]["lpt"] = result[0] + # if len(new_term_events_of_pair) > 0: + # print(f"Found {len(new_term_events_of_pair)} new Term events") # For each term, update config... for event in new_term_events_of_pair: @@ -236,12 +269,24 @@ def update_pair_config( # the `ds_id` identifies each term, but is not unique globally (across pairs) term_id: TermId = TermId(event["args"]["dsId"]) + # Find the LP token address for the given CT token + # event Initialized(address indexed ra, address indexed ct, address liquidityToken); + amm_lp_token_addr = next(( + Web3.to_checksum_address(lpt_event["args"]["liquidityToken"]) + for lpt_event in new_lpt_events + if lpt_event["args"]["ct"] == event["args"]["ct"] + ), None) + + # In Uniswap v4, the Pool Manager contract address holds the reserves of the pool + if self.amm_pool_addr is None: + self.amm_pool_addr = self.amm_contract.functions.getPoolManager().call() + # the `share_token_addr` is unique and only valid for each term (or issuance) # the `lp_token_addr` is also unique and only valid for each term (or issuance) term_config = TermConfig( share_token_addr=Web3.to_checksum_address(event["args"]["ct"]), - amm_lp_token_addr=Web3.to_checksum_address(event["args"]["lpt"]), - amm_pool_addr=self.amm_contract.address, + amm_lp_token_addr=amm_lp_token_addr, + amm_pool_addr=self.amm_pool_addr, start_block=event["blockNumber"], ) @@ -252,7 +297,7 @@ def update_pair_config( def update_psm_pool_balances( self, pool_balances: Dict[PsmShareTokenAddress, PooledBalance], - from_block: int = 0, + from_block: int, to_block: int | str = "latest", ) -> Dict[PsmShareTokenAddress, PooledBalance]: # For each pair... @@ -276,7 +321,25 @@ def update_psm_pool_balances( "id": pair_id, "dsId": int(term_id), }, - ) + ) if pair_config.eligible_asset == TokenType.RA else [] + # for e in deposit_events: + # print("PsmDeposited", e["args"]["amount"], e["blockNumber"]) + + # event Cancelled(Id indexed id, uint256 indexed dsId, address indexed redeemer, uint256 raAmount, uint256 swapAmount) + # IN: CT + DS + # OUT: RA + early_withdraw_events = fetch_events_logs_with_retry( + "Early Withdraw using CT + DS on pairs with USDe", + self.psm_contract.events.Cancelled(), + start_block, + to_block, + filter={ + "id": pair_id, + "dsId": int(term_id), + }, + ) if pair_config.eligible_asset == TokenType.RA else [] + # for e in early_withdraw_events: + # print("Cancelled", e["args"]["raAmount"], e["blockNumber"]) # event CtRedeemed(Id indexed id, uint256 indexed dsId, address indexed redeemer, uint256 amount, uint256 paReceived, uint256 raReceived) # IN: CT @@ -291,10 +354,12 @@ def update_psm_pool_balances( "dsId": int(term_id), }, ) + # for e in withdraw_events: + # print("CtRedeemed", -e["args"]["raReceived"], e["blockNumber"]) # event DsRedeemed(Id indexed id, uint256 indexed dsId, address indexed redeemer, uint256 paUsed, uint256 dsUsed, uint256 raReceived, uint256 dsExchangeRate, uint256 feePercentage, uint256 fee) # IN: DS + PA - # OUT: RA + # OUT: RA + fee redeem_events = fetch_events_logs_with_retry( "Redeem using DS on pairs with USDe", self.psm_contract.events.DsRedeemed(), @@ -305,9 +370,11 @@ def update_psm_pool_balances( "dsId": int(term_id), }, ) + # for e in redeem_events: + # print("DsRedeemed", -(e["args"]["raReceived"] + e["args"]["fee"]), e["blockNumber"]) # event Repurchased(Id indexed id, address indexed buyer, uint256 indexed dsId, uint256 raUsed, uint256 receivedPa, uint256 receivedDs, uint256 feePercentage, uint256 fee, uint256 exchangeRates) - # IN: RA + # IN: RA (raUsed includes fee) # OUT: PA + DS repurchase_events = fetch_events_logs_with_retry( "Repurchase on pairs with USDe", @@ -319,36 +386,44 @@ def update_psm_pool_balances( "dsId": int(term_id), }, ) + # for e in repurchase_events: + # print("Repurchased", e["args"]["raUsed"] - e["args"]["fee"], e["blockNumber"]) # pylint: enable=line-too-long + + # Includes Rollover Events if pair_config.eligible_asset == TokenType.RA: balance_in = sum( - [event["args"]["amount"] for event in deposit_events] - + [event["args"]["raUsed"] for event in repurchase_events] + [e["args"]["amount"] for e in deposit_events] + + [e["args"]["raUsed"] - e["args"]["fee"] for e in repurchase_events] ) balance_out = sum( - [event["args"]["raReceived"] for event in withdraw_events] - + [event["args"]["raReceived"] for event in redeem_events] + [e["args"]["raAmount"] for e in early_withdraw_events] + + [e["args"]["raReceived"] for e in withdraw_events] + + [e["args"]["raReceived"] + e["args"]["fee"] for e in redeem_events] ) elif pair_config.eligible_asset == TokenType.PA: balance_in = sum( - [event["args"]["paUsed"] for event in redeem_events] + [e["args"]["paUsed"] for e in redeem_events] ) balance_out = sum( - [event["args"]["paReceived"] for event in withdraw_events] - + [event["args"]["receivedPa"] for event in repurchase_events] + [e["args"]["paReceived"] for e in withdraw_events] + + [e["args"]["receivedPa"] for e in repurchase_events] ) else: raise NotImplementedError("Token type not yet implemented") # Get pooled balances of each PSM share_token_addr = term_config.share_token_addr - pool_balances.setdefault( + pool = pool_balances.setdefault( share_token_addr, PooledBalance(pair_config, term_config) ) - pool = pool_balances[share_token_addr] # Update asset balance of PSM pool pool.total_assets += balance_in - balance_out + # if balance_in or balance_out: + # print("balance_in\t", balance_in) + # print("balance_out\t", balance_out) + # print("psm_pool.total_assets", pool.total_assets, to_block) # For each token, accumulate all balance changes from Transfer events... token_contract = self.w3.eth.contract( @@ -369,40 +444,41 @@ def update_psm_pool_balances( value = int(transfer["args"]["value"]) sender = Web3.to_checksum_address(transfer["args"]["from"]) - if sender not in self.excluded_addresses: - pool.shares_by_account.setdefault(sender, 0) - pool.shares_by_account[sender] -= value - elif sender == ZERO_ADDRESS: + if sender == ZERO_ADDRESS: # token was minted, update total supply pool.total_supply += value + elif sender not in self.excluded_addresses: + pool.shares_by_account.setdefault(sender, 0) + pool.shares_by_account[sender] -= value recipient = Web3.to_checksum_address(transfer["args"]["to"]) - if recipient not in self.excluded_addresses: - pool.shares_by_account.setdefault(recipient, 0) - pool.shares_by_account[recipient] += value - elif sender == ZERO_ADDRESS: + if recipient == ZERO_ADDRESS: # token was burned, update total supply pool.total_supply -= value + elif recipient not in self.excluded_addresses: + pool.shares_by_account.setdefault(recipient, 0) + pool.shares_by_account[recipient] += value return pool_balances def update_amm_pool_balances( self, pool_balances: Dict[LpTokenAddress, PooledBalance], - from_block: int = 0, + from_block, to_block: int | str = "latest", ) -> Dict[LpTokenAddress, PooledBalance]: # For each pair... for _pair_id, pair_config in self.pair_config_by_id.items(): # For each term... - for _term_id, term_config in pair_config.terms.items(): + for term_config in ( + v for v in pair_config.terms.values() if v.amm_lp_token_addr is not None + ): start_block = max(from_block, term_config.start_block) # Get pooled balances of each AMM pair lp_token_addr = term_config.amm_lp_token_addr - pool_balances.setdefault( + pool = pool_balances.setdefault( lp_token_addr, PooledBalance(pair_config, term_config) ) - pool = pool_balances[lp_token_addr] # For each token, accumulate all balance changes from Transfer events... token_contract = self.w3.eth.contract( @@ -423,26 +499,26 @@ def update_amm_pool_balances( value = int(transfer["args"]["value"]) sender = Web3.to_checksum_address(transfer["args"]["from"]) - if sender not in self.excluded_addresses: - pool.shares_by_account.setdefault(sender, 0) - pool.shares_by_account[sender] -= value - elif sender == ZERO_ADDRESS: + if sender == ZERO_ADDRESS: # token was minted, update total supply pool.total_supply += value + elif sender not in self.excluded_addresses: + pool.shares_by_account.setdefault(sender, 0) + pool.shares_by_account[sender] -= value recipient = Web3.to_checksum_address(transfer["args"]["to"]) - if recipient not in self.excluded_addresses: - pool.shares_by_account.setdefault(recipient, 0) - pool.shares_by_account[recipient] += value - elif sender == ZERO_ADDRESS: + if recipient == ZERO_ADDRESS: # token was burned, update total supply pool.total_supply -= value + elif recipient not in self.excluded_addresses: + pool.shares_by_account.setdefault(recipient, 0) + pool.shares_by_account[recipient] += value return pool_balances def update_vault_pool_balances( self, pool_balances: Dict[VaultShareTokenAddress, PooledBalance], - from_block: int = 0, + from_block: int, to_block: int | str = "latest", ) -> Dict[VaultShareTokenAddress, PooledBalance]: # For each pair... @@ -450,8 +526,7 @@ def update_vault_pool_balances( start_block = max(from_block, pair_config.start_block) vault_share_token_addr = pair_config.vault_share_token_addr - pool_balances.setdefault(vault_share_token_addr, PooledBalance(pair_config)) - pool = pool_balances[pool_balances] + pool = pool_balances.setdefault(vault_share_token_addr, PooledBalance(pair_config)) # For each token, accumulate all balance changes from Transfer events... token_contract = self.w3.eth.contract( @@ -472,20 +547,20 @@ def update_vault_pool_balances( value = int(transfer["args"]["value"]) sender = Web3.to_checksum_address(transfer["args"]["from"]) - if sender not in self.excluded_addresses: - pool.shares_by_account.setdefault(sender, 0) - pool.shares_by_account[sender] -= value - elif sender == ZERO_ADDRESS: + if sender == ZERO_ADDRESS: # token was minted, update total supply pool.total_supply += value + elif sender not in self.excluded_addresses: + pool.shares_by_account.setdefault(sender, 0) + pool.shares_by_account[sender] -= value recipient = Web3.to_checksum_address(transfer["args"]["to"]) - if recipient not in self.excluded_addresses: - pool.shares_by_account.setdefault(recipient, 0) - pool.shares_by_account[recipient] += value - elif sender == ZERO_ADDRESS: + if recipient == ZERO_ADDRESS: # token was burned, update total supply pool.total_supply -= value + elif recipient not in self.excluded_addresses: + pool.shares_by_account.setdefault(recipient, 0) + pool.shares_by_account[recipient] += value return pool_balances def get_block_balances( @@ -526,7 +601,7 @@ def get_block_balances( ) # loop through the sorted blocks and find the closest previous block - prev_block = self.start_block - 1 + prev_block = self.start_block start = prev_block + 1 account_bals: Dict[ChecksumAddress, Decimal | float] = {} @@ -537,28 +612,30 @@ def get_block_balances( account_bals = deepcopy(cache_copy_of_account_bals[prev_block]) break - # Fetch pair config at prev_block if not already done + # Fetch pair config from self.start_block if not already done if self.pair_config_by_id is None: self.pair_config_by_id = self.update_pair_config( - {}, to_block=prev_block + {}, from_block=self.start_block, to_block=prev_block ) - # Fetch Peg Stability term balances at prev_block if not already done + # Fetch Peg Stability term balances from self.start_block if not already done if self.psm_balances_by_share_token is None: self.psm_balances_by_share_token = self.update_psm_pool_balances( - {}, to_block=prev_block + {}, from_block=self.start_block, to_block=prev_block ) - # Fetch AMM Liquidity Pool term balances at prev_block if not already done + # Fetch AMM Liquidity Pool term balances from self.start_block if not already done if self.amm_balances_by_lp_token is None: self.amm_balances_by_lp_token = self.update_amm_pool_balances( - {}, to_block=prev_block + {}, from_block=self.start_block, to_block=prev_block ) - # Fetch Vault term balances at prev_block if not already done + # Fetch Vault term balances from self.start_block if not already done if self.vault_balances_by_vault_share_token is None: self.vault_balances_by_vault_share_token = ( - self.update_vault_pool_balances({}, to_block=prev_block) + self.update_vault_pool_balances( + {}, from_block=self.start_block, to_block=prev_block + ) ) # parse events since and update bals @@ -588,17 +665,53 @@ def get_block_balances( # continue pagination # finished pagination loop, block height reached... - # Filter out non-eligible AMM pools - eligible_amm_balances = { - lp_token_addr: amm_pool - for lp_token_addr, amm_pool in self.amm_balances_by_lp_token.items() - if amm_pool.pair_config.amm_quote_token_addr == self.eligible_token_addr - } - # Fetch the reserve asset balances of each eligible AMM pool + # Fetch the idle asset balance of each eligible Vault pool + vault_contract_function = self.vault_contract.functions.tradeExecutionFundsAvailable + pair_ids = [ + pair_id + for pair_id, pair_config in self.pair_config_by_id.items() + if pair_config.eligible_asset == TokenType.RA + ] + vault_calls = [ + ( + self.vault_contract, + vault_contract_function.fn_name, + [ + pair_id, + ], + ) + for pair_id in pair_ids + ] + multicall_results = multicall_by_address( + w3=self.w3, + multical_address=MULTICALL_ADDRESS_BY_CHAIN[self.chain], + calls=vault_calls, + block_identifier=block, + ) + + # The results contain the following: + # - The `result[0]` is the total balance of the asset token in the vault pool + for pair_id, result in zip( + pair_ids, multicall_results + ): + # Update the total idle asset balance of each vault pool + pair_config = self.pair_config_by_id[pair_id] + vault_pool = self.vault_balances_by_vault_share_token[ + pair_config.vault_share_token_addr + ] + vault_pool.total_assets = result[0] + print("vault_pool.total_assets", vault_pool.total_assets, block) + + # Uniswap V4 doesn’t store reserves explicitly in storage. + # Instead, reserves are inferred from the pool’s liquidity and price data, + # necessitating off-chain computation of contract events for precise reserve values. + # Instead, use the `getReserves()` function on Cork's custom UniV4 Hook to, + # Fetch the reserve asset balance of each eligible AMM pool # Note: We cannot assume that all LP token holders have withdrawn # remaining reserves after end of epoch/term. amm_contract_function = self.amm_contract.functions.getReserves + amm_pools = self.amm_balances_by_lp_token.values() amm_calls = [ ( self.amm_contract, @@ -608,55 +721,142 @@ def get_block_balances( amm_pool.term_config.share_token_addr, ], ) - for amm_pool in eligible_amm_balances.values() + for amm_pool in amm_pools ] - multicall_results = multicall(self.w3, amm_calls, block) + multicall_results = multicall_by_address( + w3=self.w3, + multical_address=MULTICALL_ADDRESS_BY_CHAIN[self.chain], + calls=amm_calls, + block_identifier=block, + ) # The results contain the following: # - The `result[0]` is the total balance of the asset token in the AMM pool # - The `result[1]` is the total balance of the share token in the AMM pool for amm_pool, result in zip( - eligible_amm_balances.values(), multicall_results + amm_pools, multicall_results ): - # Update the total asset balance of each AMM pool - amm_pool.total_assets = result[0] + # Update the total Ethena-asset and PSM-shares balance of each AMM pool + amm_pool.total_assets = (result[0], result[1]) + print("amm_pool.total_assets", amm_pool.total_assets, block) - # Update the total shares of PSM pool of each AMM pool - # amm_pool.total_assets_by_token[amm_pool.term_config.share_token_addr] = result[1] + # Fetch the asset balance of each eligible PSM pool + psm_contract_function = self.psm_contract.functions.valueLocked + psm_calls = [ + ( + self.psm_contract, + psm_contract_function.fn_name, + [ + pair_id, + pair_config.eligible_asset == TokenType.RA, + ] + if term_id == max(pair_config.terms) else + [ + pair_id, + term_id, + pair_config.eligible_asset == TokenType.RA, + ], + ) + for pair_id, pair_config in self.pair_config_by_id.items() + for term_id in pair_config.terms + ] + multicall_results = multicall_by_address( + w3=self.w3, + multical_address=MULTICALL_ADDRESS_BY_CHAIN[self.chain], + calls=psm_calls, + block_identifier=block, + ) + + # The results contain the following: + # - The `result[0]` is the total balance of the asset token in the psm pool + for (pair_id, term_id), result in zip( + ( + (pair_id, term_id) + for pair_id, pair_config in self.pair_config_by_id.items() + for term_id in pair_config.terms + ), + multicall_results + ): + # Update the total asset balance of each psm pool + pair_config = self.pair_config_by_id[pair_id] + term_config = pair_config.terms[term_id] + share_token_addr = term_config.share_token_addr + psm_pool = self.psm_balances_by_share_token[share_token_addr] + + if int(term_id) > 1: + assert ( + psm_pool.total_assets == result[0] + ), f"psm_pool.total_assets != psm_contract.valueLocked for {pair_id}:{term_id}" + else: + psm_pool.total_assets = result[0] + print("psm_pool.total_assets", psm_pool.total_assets, block) + + # Attribute Ethena asset balances on Vault pools to their respective LV token holders + for lv_token_addr, vault_pool in ( + (lv_token_addr, vault_pool) + for lv_token_addr, vault_pool in self.vault_balances_by_vault_share_token.items() + if vault_pool.pair_config.eligible_asset == TokenType.RA + ): + print("======== LVT:", lv_token_addr, "========") + for account_addr, account_shares in vault_pool.shares_by_account.items(): + amount = ( + Decimal(vault_pool.total_assets) + * Decimal(account_shares) + / Decimal(vault_pool.total_supply) + ) + bal = account_bals.setdefault(account_addr, Decimal(0)) + account_bals[account_addr] = Decimal(bal) + amount + print( + "LVT-holder:", account_addr, + "start:", bal, + "in:", amount, + "end:", account_bals[account_addr] + ) # Attribute Ethena asset balances on AMM pools to their respective LP token holders - for amm_pool in self.amm_balances_by_lp_token.values(): + for lp_token_addr, amm_pool in ( + (lp_token_addr, amm_pool) + for lp_token_addr, amm_pool in self.amm_balances_by_lp_token.items() + if amm_pool.pair_config.amm_quote_token_addr == self.eligible_token_addr + ): + print("======== LPT:", lp_token_addr, "========") for account_addr, account_shares in amm_pool.shares_by_account.items(): amount = ( - Decimal(amm_pool.total_assets) + Decimal(amm_pool.total_assets[0]) * Decimal(account_shares) / Decimal(amm_pool.total_supply) ) # If the account_addr is the vault_addr, then we need to attribute the # Ethena asset balances to the respective LV token holders - if account_addr == amm_pool.pair_config.vault_addr: - vault_share_token_addr = ( - amm_pool.pair_config.vault_share_token_addr - ) + if account_addr == amm_pool.pair_config.vault_addr and amount: + vault_share_token_addr = amm_pool.pair_config.vault_share_token_addr vault = self.vault_balances_by_vault_share_token[ vault_share_token_addr ] for ( - account_addr, - account_shares, + account_addr, account_shares ) in vault.shares_by_account.items(): - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = Decimal( - account_bals[account_addr] - ) + ( + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( amount * Decimal(account_shares) / Decimal(vault.total_supply) ) + account_bals[account_addr] = Decimal(bal) + qty + print( + "LVT-holder:", vault_share_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) else: - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = ( - Decimal(account_bals[account_addr]) + amount + bal = account_bals.setdefault(account_addr, Decimal(0)) + account_bals[account_addr] = Decimal(bal) + amount + print( + "LPT-holder:", account_addr, + "start:", bal, + "in:", amount, + "end:", account_bals[account_addr] ) # # Attribute PSM share token balances to their respective LP token holders @@ -665,69 +865,120 @@ def get_block_balances( # psm_pool = self.psm_balances_by_share_token[share_token_addr] # account_share_token_bals = psm_pool.shares_by_account # share_amount = ( - # Decimal(amm_pool.total_assets_by_token[share_token_addr]) + # Decimal(amm_pool.total_assets[1]) # * Decimal(account_shares) # / Decimal(amm_pool.total_supply) # ) - # account_share_token_bals.setdefault(account_addr, Decimal(0)) - # bal = Decimal(account_share_token_bals[account_addr]) - # account_share_token_bals[account_addr] = bal + share_amount + # bal = account_share_token_bals.setdefault(account_addr, Decimal(0)) + # account_share_token_bals[account_addr] = Decimal(bal) + share_amount # Attribute Ethena asset balances on PSM pools to their respective CT token holders - for psm_pool in self.psm_balances_by_share_token.values(): + for share_token_addr, psm_pool in self.psm_balances_by_share_token.items(): + print("======== CT:", share_token_addr, "========") for account_addr, account_shares in psm_pool.shares_by_account.items(): amount = ( Decimal(psm_pool.total_assets) * Decimal(account_shares) / Decimal(psm_pool.total_supply) ) - # If the account_addr is the vault_addr, then we need to attribute the + # If the account_addr is the Cork Vault address, then we need to attribute the # Ethena asset balances to the respective LV token holders - if account_addr == psm_pool.pair_config.vault_addr: - vault_share_token_addr = ( - psm_pool.pair_config.vault_share_token_addr - ) + if account_addr == psm_pool.pair_config.vault_addr and amount: + vault_share_token_addr = psm_pool.pair_config.vault_share_token_addr vault = self.vault_balances_by_vault_share_token[ vault_share_token_addr ] for ( - account_addr, - account_shares, + account_addr, account_shares ) in vault.shares_by_account.items(): - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = Decimal( - account_bals[account_addr] - ) + ( + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( amount * Decimal(account_shares) / Decimal(vault.total_supply) ) - # If the account_addr is the amm_contract, then we need to attribute the - # Ethena asset balances to the respective LP token holders - elif account_addr == psm_pool.term_config.amm_pool_addr: + account_bals[account_addr] = Decimal(bal) + qty + print( + "LVT-holder:", vault_share_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) + # If the account_addr is the UniV4 PoolManager address, then we need to + # attribute the Ethena asset balances to the respective LP token holders + elif account_addr == psm_pool.term_config.amm_pool_addr and amount: lp_token_addr = psm_pool.term_config.amm_lp_token_addr amm_pool = self.amm_balances_by_lp_token[lp_token_addr] + + # If there are other Uniswap V4 pools which manage PSM-shares, + # the total amount of PSM-shares at the UniV4 PoolManager address + # will exceed the amount present in the Cork AMM pool, + # so we need to correct the attributed amount. + if account_shares > amm_pool.total_assets[1]: + amount = ( + Decimal(psm_pool.total_assets) + * Decimal(amm_pool.total_assets[1]) + / Decimal(psm_pool.total_supply) + ) for ( - account_addr, - account_shares, + account_addr, account_shares ) in amm_pool.shares_by_account.items(): - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = Decimal( - account_bals[account_addr] - ) + ( - amount - * Decimal(account_shares) - / Decimal(amm_pool.total_supply) - ) + # If the account_addr is the vault_addr, then we need to attribute the + # Ethena asset balances to the respective LV token holders + if account_addr == amm_pool.pair_config.vault_addr and amount: + vault_share_token_addr = amm_pool.pair_config.vault_share_token_addr + vault = self.vault_balances_by_vault_share_token[ + vault_share_token_addr + ] + amount = ( + amount + * Decimal(account_shares) + / Decimal(amm_pool.total_supply) + ) + for ( + account_addr, account_shares + ) in vault.shares_by_account.items(): + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( + amount + * Decimal(account_shares) + / Decimal(vault.total_supply) + ) + account_bals[account_addr] = Decimal(bal) + qty + print( + "LPT-LVT-holder:", + lp_token_addr, vault_share_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) + else: + bal = account_bals.setdefault(account_addr, Decimal(0)) + qty = ( + amount + * Decimal(account_shares) + / Decimal(amm_pool.total_supply) + ) + account_bals[account_addr] = Decimal(bal) + qty + print( + "LPT-holder:", lp_token_addr, account_addr, + "start:", bal, + "in:", qty, + "end:", account_bals[account_addr] + ) else: - account_bals.setdefault(account_addr, Decimal(0)) - account_bals[account_addr] = ( - Decimal(account_bals[account_addr]) + amount + bal = account_bals.setdefault(account_addr, Decimal(0)) + account_bals[account_addr] = Decimal(bal) + amount + print( + "CT-holder:", account_addr, + "start:", bal, + "in:", amount, + "end:", account_bals[account_addr] ) # Round off to 4 decimals for account_addr, account_bal in account_bals.items(): - account_bals[account_addr] = round(account_bal / Decimal(1e18), 4) + account_bals[account_addr] = float(round(Decimal(account_bal) / Decimal(1e18), 4)) new_block_data[block] = account_bals cache_copy_of_account_bals[block] = account_bals @@ -738,13 +989,13 @@ def get_block_balances( # simple tests for the integration cork_integration = CorkIntegration( integration_id=IntegrationID.CORK_USDE, - start_block=PSM_USDE_START_BLOCK_BY_CHAIN[Chain.SEPOLIA], + eligible_token_addr=USDE_TOKEN_ADDRESS_BY_CHAIN[Chain.ETHEREUM], + start_block=USDE_START_BLOCK_BY_CHAIN[Chain.ETHEREUM], summary_cols=[SummaryColumn.CORK_PSM_PTS], - chain=Chain.SEPOLIA, + chain=Chain.ETHEREUM, reward_multiplier=50, excluded_addresses={ - Web3.to_checksum_address("0x0000000000000000000000000000000000000000"), - # AMM_ADDRESS_BY_CHAIN[Chain.SEPOLIA], # exclude Cork AMMs from being counted + ZERO_ADDRESS, }, ) @@ -752,8 +1003,8 @@ def get_block_balances( print( "Run without cached data", cork_integration.get_block_balances( - cached_data={}, blocks=[7686000, 7686001, 7686002] - ), + cached_data={}, blocks=[21929082, 21929083, 21929084] + ) ) # Example output: # { @@ -767,16 +1018,16 @@ def get_block_balances( "Run with cached data", cork_integration.get_block_balances( cached_data={ - 7686000: { - Web3.to_checksum_address("0x123"): 100, - Web3.to_checksum_address("0x456"): 200, + 21929082: { + Web3.to_checksum_address("0x0000000000000000000000000000000000000000"): 100, + Web3.to_checksum_address("0x0000000000000000000000000000000000000001"): 200, }, - 7686001: { - Web3.to_checksum_address("0x123"): 101, - Web3.to_checksum_address("0x456"): 201, + 21929083: { + Web3.to_checksum_address("0x0000000000000000000000000000000000000000"): 101, + Web3.to_checksum_address("0x0000000000000000000000000000000000000001"): 201, }, }, - blocks=[7686002], + blocks=[21929084], ), ) print("=" * 120) diff --git a/utils/web3_utils.py b/utils/web3_utils.py index 42c3da5..e4b9e7a 100644 --- a/utils/web3_utils.py +++ b/utils/web3_utils.py @@ -127,8 +127,9 @@ def fetch_events_logs_with_retry( return contract_event.get_logs(fromBlock=from_block, toBlock=to_block) else: return contract_event.get_logs( - argument_filters=filter, fromBlock=from_block, toBlock=to_block + fromBlock=from_block, toBlock=to_block, argument_filters=filter ) + except Exception as e: if attempt < retries - 1: time.sleep(delay) @@ -165,7 +166,7 @@ def multicall(w3: Web3, calls: list, block_identifier: BlockIdentifier = "latest aggregate_calls = [] for call in calls: contract, fn_name, args = call - call_data = contract.encodeABI(fn_name=fn_name, args=args) + call_data = contract.encode_abi(fn_name=fn_name, args=args) aggregate_calls.append((contract.address, call_data)) result = multicall_contract.functions.aggregate(aggregate_calls).call( @@ -196,7 +197,7 @@ def multicall_by_address( aggregate_calls = [] for call in calls: contract, fn_name, args = call - call_data = contract.encodeABI(fn_name=fn_name, args=args) + call_data = contract.encode_abi(fn_name=fn_name, args=args) aggregate_calls.append((contract.address, call_data)) result = multicall_contract.functions.aggregate(aggregate_calls).call(