diff --git a/.gitleaksignore b/.gitleaksignore index 8f397a8..8392612 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -3,4 +3,6 @@ 84bb27da7c7e36ae932749216a05fe563d83bc42:packages/dvilela/skills/tsunami_chained_abci/skill.yaml:generic-api-key:85 a4c606c6635c2562f67e4d2cb7c614e0d10d58f8:packages/dvilela/skills/prepare_tweets_abci/skill.yaml:generic-api-key:80 a4c606c6635c2562f67e4d2cb7c614e0d10d58f8:packages/dvilela/skills/tsunami_abci/skill.yaml:generic-api-key:80 -117e66917c1ddac74c0958c5b6d9d5435f55b02d:packages/dvilela/services/tsunami/service.yaml:generic-api-key:69 \ No newline at end of file +117e66917c1ddac74c0958c5b6d9d5435f55b02d:packages/dvilela/services/tsunami/service.yaml:generic-api-key:69 +3ffffb92954da6ffe5391bd13385c571c1db53db:packages/dvilela/contracts/olas_tokenomics/contract.yaml:generic-api-key:11 +f465f892ab8e6520d1fa57a2daeafb1fc1e5e66c:packages/dvilela/contracts/olas_tokenomics/contract.yaml:generic-api-key:10 \ No newline at end of file diff --git a/packages/dvilela/agents/tsunami/aea-config.yaml b/packages/dvilela/agents/tsunami/aea-config.yaml index 3128fb4..59508fa 100644 --- a/packages/dvilela/agents/tsunami/aea-config.yaml +++ b/packages/dvilela/agents/tsunami/aea-config.yaml @@ -26,6 +26,8 @@ contracts: - valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y - valory/service_registry:0.1.0:bafybeiekytropd5ysnap2wkekub3byi5jbda3qll7awchvhu5plbpafhmi - dvilela/olas_registries:0.1.0:bafybeict2xpt56m2a5ehezd2oylrhbhahrsas3dht2fdfbnrejlr5mdqpa +- dvilela/olas_tokenomics:0.1.0:bafybeifslkoofg3ohscvovzhgaa3up5jhmb6fac4r35b5wcdjphafzssxu +- dvilela/olas_treasury:0.1.0:bafybeidd6yelhuztyvtbso6fkc4iiq2pmegh734exyrtcbqh62yfwgluqy protocols: - open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi - valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u @@ -45,8 +47,8 @@ skills: - valory/transaction_settlement_abci:0.1.0:bafybeic3tccdjypuge2lewtlgprwkbb53lhgsgn7oiwzyrcrrptrbeyote - valory/registration_abci:0.1.0:bafybeieu7vq3pyns4t5ty6u3sbmpkd7yznpg3rmqifoz3jhy7pmqyg3w6q - valory/reset_pause_abci:0.1.0:bafybeiameewywqigpupy3u2iwnkfczeiiucue74x2l5lbge74rmw6bgaie -- dvilela/tsunami_abci:0.1.0:bafybeidzlzl4yqkw36uw6c3tbq5mz2twmkto6fkerv2skkcvmbtdnjmfjq -- dvilela/tsunami_chained_abci:0.1.0:bafybeicqrebte42fxb4eokfemydjwmfqcfsr7gogl3jeiqrxrlklgmsibi +- dvilela/tsunami_abci:0.1.0:bafybeifb4oatjxqa5tc37xxb36ru5wktebqqy4f5ig6d6wnwsovvyjysii +- dvilela/tsunami_chained_abci:0.1.0:bafybeiaj7y4bnugd45nlnfb6fz36ixnpzlhbgs76frukd7r2zyjooopngq default_ledger: ethereum required_ledgers: - ethereum @@ -218,6 +220,8 @@ models: agent_registry_address_ethereum: ${str:0x2F1f7D38e4772884b88f3eCd8B6b9faCdC319112} component_registry_address_ethereum: ${str:0x15bd56669F57192a97dF41A2aa8f4403e9491776} service_registry_address_gnosis: ${str:0x9338b5153AE39BB89f50468E608eD9d764B755fD} + treasury_address_ethereum: ${str:0xa0DA53447C0f6C4987964d8463da7e6628B30f82} + tokenomics_address_ethereum: ${str:0xc096362fa6f4A4B1a9ea68b1043416f3381ce300} initial_block_ethereum: ${int:19423661} initial_block_gnosis: ${int:33047920} twitter_credentials: ${str:{}} @@ -235,4 +239,5 @@ public_id: valory/http_server:0.22.0:bafybeicblltx7ha3ulthg7bzfccuqqyjmihhrvfezt type: connection config: host: ${str:0.0.0.0} + port: ${int:8000} target_skill_id: dvilela/tsunami_chained_abci:0.1.0 diff --git a/packages/dvilela/contracts/olas_tokenomics/__init__.py b/packages/dvilela/contracts/olas_tokenomics/__init__.py new file mode 100644 index 0000000..340fbe3 --- /dev/null +++ b/packages/dvilela/contracts/olas_tokenomics/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2022 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the support resources for the tokenomics contract.""" diff --git a/packages/dvilela/contracts/olas_tokenomics/build/OlasTokenomics.json b/packages/dvilela/contracts/olas_tokenomics/build/OlasTokenomics.json new file mode 100644 index 0000000..d2ff7b7 --- /dev/null +++ b/packages/dvilela/contracts/olas_tokenomics/build/OlasTokenomics.json @@ -0,0 +1,1905 @@ +{ + "abi": [ + { + "inputs":[ + + ], + "stateMutability":"nonpayable", + "type":"constructor" + }, + { + "inputs":[ + + ], + "name":"AlreadyInitialized", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"bondId", + "type":"uint256" + } + ], + "name":"BondNotRedeemable", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"uint256", + "name":"reward", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"topUp", + "type":"uint256" + } + ], + "name":"ClaimIncentivesFailed", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"DelegatecallOnly", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"DonatorBlacklisted", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"expected", + "type":"uint256" + } + ], + "name":"InsufficientAllowance", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"expected", + "type":"uint256" + } + ], + "name":"LowerThan", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"sender", + "type":"address" + }, + { + "internalType":"address", + "name":"manager", + "type":"address" + } + ], + "name":"ManagerOnly", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"NonZeroValue", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"max", + "type":"uint256" + } + ], + "name":"Overflow", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"sender", + "type":"address" + }, + { + "internalType":"address", + "name":"owner", + "type":"address" + } + ], + "name":"OwnerOnly", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"x", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"y", + "type":"uint256" + } + ], + "name":"PRBMath_MulDiv18_Overflow", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"x", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"y", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"denominator", + "type":"uint256" + } + ], + "name":"PRBMath_MulDiv_Overflow", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"x", + "type":"uint256" + } + ], + "name":"PRBMath_UD60x18_Convert_Overflow", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"Paused", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"productId", + "type":"uint256" + } + ], + "name":"ProductClosed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"tokenAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"productId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"deadline", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"curTime", + "type":"uint256" + } + ], + "name":"ProductExpired", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"tokenAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"productId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"requested", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"actual", + "type":"uint256" + } + ], + "name":"ProductSupplyLow", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"ReentrancyGuard", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"SameBlockNumberViolation", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"serviceId", + "type":"uint256" + } + ], + "name":"ServiceDoesNotExist", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"serviceId", + "type":"uint256" + } + ], + "name":"ServiceNeverDeployed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"token", + "type":"address" + }, + { + "internalType":"address", + "name":"from", + "type":"address" + }, + { + "internalType":"address", + "name":"to", + "type":"address" + }, + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"TransferFailed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"epochNumber", + "type":"uint256" + } + ], + "name":"TreasuryRebalanceFailed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"tokenAddress", + "type":"address" + } + ], + "name":"UnauthorizedToken", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"expected", + "type":"uint256" + } + ], + "name":"WrongAmount", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"numValues1", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"numValues2", + "type":"uint256" + } + ], + "name":"WrongArrayLength", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"provided", + "type":"address" + }, + { + "internalType":"address", + "name":"expected", + "type":"address" + } + ], + "name":"WrongTokenAddress", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"unitId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"unitType", + "type":"uint256" + } + ], + "name":"WrongUnitId", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"ZeroAddress", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"ZeroValue", + "type":"error" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"agentRegistry", + "type":"address" + } + ], + "name":"AgentRegistryUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"componentRegistry", + "type":"address" + } + ], + "name":"ComponentRegistryUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"depository", + "type":"address" + } + ], + "name":"DepositoryUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"dispenser", + "type":"address" + } + ], + "name":"DispenserUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"blacklist", + "type":"address" + } + ], + "name":"DonatorBlacklistUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"effectiveBond", + "type":"uint256" + } + ], + "name":"EffectiveBondUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"epochLen", + "type":"uint256" + } + ], + "name":"EpochLengthUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"epochCounter", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"treasuryRewards", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"accountRewards", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"accountTopUps", + "type":"uint256" + } + ], + "name":"EpochSettled", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"idf", + "type":"uint256" + } + ], + "name":"IDFUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"epochNumber", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"rewardComponentFraction", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"rewardAgentFraction", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"maxBondFraction", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"topUpComponentFraction", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"topUpAgentFraction", + "type":"uint256" + } + ], + "name":"IncentiveFractionsUpdateRequested", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"epochNumber", + "type":"uint256" + } + ], + "name":"IncentiveFractionsUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"owner", + "type":"address" + } + ], + "name":"OwnerUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"serviceRegistry", + "type":"address" + } + ], + "name":"ServiceRegistryUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"implementation", + "type":"address" + } + ], + "name":"TokenomicsImplementationUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"epochNumber", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"devsPerCapital", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"codePerDev", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"epsilonRate", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"epochLen", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"veOLASThreshold", + "type":"uint256" + } + ], + "name":"TokenomicsParametersUpdateRequested", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"epochNumber", + "type":"uint256" + } + ], + "name":"TokenomicsParametersUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"treasury", + "type":"address" + } + ], + "name":"TreasuryUpdated", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"MIN_EPOCH_LENGTH", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"MIN_PARAM_VALUE", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ONE_YEAR", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"PROXY_TOKENOMICS", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"VERSION", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"uint256[]", + "name":"unitTypes", + "type":"uint256[]" + }, + { + "internalType":"uint256[]", + "name":"unitIds", + "type":"uint256[]" + } + ], + "name":"accountOwnerIncentives", + "outputs":[ + { + "internalType":"uint256", + "name":"reward", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"topUp", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"agentRegistry", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_donatorBlacklist", + "type":"address" + } + ], + "name":"changeDonatorBlacklist", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_rewardComponentFraction", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_rewardAgentFraction", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_maxBondFraction", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_topUpComponentFraction", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_topUpAgentFraction", + "type":"uint256" + } + ], + "name":"changeIncentiveFractions", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_treasury", + "type":"address" + }, + { + "internalType":"address", + "name":"_depository", + "type":"address" + }, + { + "internalType":"address", + "name":"_dispenser", + "type":"address" + } + ], + "name":"changeManagers", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"newOwner", + "type":"address" + } + ], + "name":"changeOwner", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_componentRegistry", + "type":"address" + }, + { + "internalType":"address", + "name":"_agentRegistry", + "type":"address" + }, + { + "internalType":"address", + "name":"_serviceRegistry", + "type":"address" + } + ], + "name":"changeRegistries", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"implementation", + "type":"address" + } + ], + "name":"changeTokenomicsImplementation", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_devsPerCapital", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_codePerDev", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_epsilonRate", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_epochLen", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_veOLASThreshold", + "type":"uint256" + } + ], + "name":"changeTokenomicsParameters", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"checkpoint", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"codePerDev", + "outputs":[ + { + "internalType":"uint72", + "name":"", + "type":"uint72" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"componentRegistry", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"currentYear", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"depository", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"devsPerCapital", + "outputs":[ + { + "internalType":"uint72", + "name":"", + "type":"uint72" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"dispenser", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"donatorBlacklist", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"effectiveBond", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"epochCounter", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"epochLen", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"epsilonRate", + "outputs":[ + { + "internalType":"uint64", + "name":"", + "type":"uint64" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"epoch", + "type":"uint256" + } + ], + "name":"getIDF", + "outputs":[ + { + "internalType":"uint256", + "name":"idf", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"numYears", + "type":"uint256" + } + ], + "name":"getInflationForYear", + "outputs":[ + { + "internalType":"uint256", + "name":"inflationAmount", + "type":"uint256" + } + ], + "stateMutability":"pure", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getInflationPerEpoch", + "outputs":[ + { + "internalType":"uint256", + "name":"inflationPerEpoch", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getLastIDF", + "outputs":[ + { + "internalType":"uint256", + "name":"idf", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"uint256[]", + "name":"unitTypes", + "type":"uint256[]" + }, + { + "internalType":"uint256[]", + "name":"unitIds", + "type":"uint256[]" + } + ], + "name":"getOwnerIncentives", + "outputs":[ + { + "internalType":"uint256", + "name":"reward", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"topUp", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"numYears", + "type":"uint256" + } + ], + "name":"getSupplyCapForYear", + "outputs":[ + { + "internalType":"uint256", + "name":"supplyCap", + "type":"uint256" + } + ], + "stateMutability":"pure", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"epoch", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"unitType", + "type":"uint256" + } + ], + "name":"getUnitPoint", + "outputs":[ + { + "components":[ + { + "internalType":"uint96", + "name":"sumUnitTopUpsOLAS", + "type":"uint96" + }, + { + "internalType":"uint32", + "name":"numNewUnits", + "type":"uint32" + }, + { + "internalType":"uint8", + "name":"rewardUnitFraction", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"topUpUnitFraction", + "type":"uint8" + } + ], + "internalType":"struct UnitPoint", + "name":"up", + "type":"tuple" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"inflationPerSecond", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_olas", + "type":"address" + }, + { + "internalType":"address", + "name":"_treasury", + "type":"address" + }, + { + "internalType":"address", + "name":"_depository", + "type":"address" + }, + { + "internalType":"address", + "name":"_dispenser", + "type":"address" + }, + { + "internalType":"address", + "name":"_ve", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_epochLen", + "type":"uint256" + }, + { + "internalType":"address", + "name":"_componentRegistry", + "type":"address" + }, + { + "internalType":"address", + "name":"_agentRegistry", + "type":"address" + }, + { + "internalType":"address", + "name":"_serviceRegistry", + "type":"address" + }, + { + "internalType":"address", + "name":"_donatorBlacklist", + "type":"address" + } + ], + "name":"initializeTokenomics", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"lastDonationBlockNumber", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"mapEpochTokenomics", + "outputs":[ + { + "components":[ + { + "internalType":"uint96", + "name":"totalDonationsETH", + "type":"uint96" + }, + { + "internalType":"uint96", + "name":"totalTopUpsOLAS", + "type":"uint96" + }, + { + "internalType":"uint64", + "name":"idf", + "type":"uint64" + }, + { + "internalType":"uint32", + "name":"numNewOwners", + "type":"uint32" + }, + { + "internalType":"uint32", + "name":"endTime", + "type":"uint32" + }, + { + "internalType":"uint8", + "name":"rewardTreasuryFraction", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"maxBondFraction", + "type":"uint8" + } + ], + "internalType":"struct EpochPoint", + "name":"epochPoint", + "type":"tuple" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"mapNewOwners", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"mapNewUnits", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"mapOwnerRewards", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"mapOwnerTopUps", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"mapServiceAmounts", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"mapUnitIncentives", + "outputs":[ + { + "internalType":"uint96", + "name":"reward", + "type":"uint96" + }, + { + "internalType":"uint96", + "name":"pendingRelativeReward", + "type":"uint96" + }, + { + "internalType":"uint96", + "name":"topUp", + "type":"uint96" + }, + { + "internalType":"uint96", + "name":"pendingRelativeTopUp", + "type":"uint96" + }, + { + "internalType":"uint32", + "name":"lastEpoch", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maxBond", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"nextEpochLen", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"nextVeOLASThreshold", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"olas", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"owner", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"refundFromBondProgram", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"reserveAmountForBondProgram", + "outputs":[ + { + "internalType":"bool", + "name":"success", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"serviceRegistry", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"timeLaunch", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"tokenomicsImplementation", + "outputs":[ + { + "internalType":"address", + "name":"implementation", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"tokenomicsParametersUpdated", + "outputs":[ + { + "internalType":"bytes1", + "name":"", + "type":"bytes1" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"donator", + "type":"address" + }, + { + "internalType":"uint256[]", + "name":"serviceIds", + "type":"uint256[]" + }, + { + "internalType":"uint256[]", + "name":"amounts", + "type":"uint256[]" + }, + { + "internalType":"uint256", + "name":"donationETH", + "type":"uint256" + } + ], + "name":"trackServiceDonations", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"treasury", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ve", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"veOLASThreshold", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + } + ], + "bytecode": "" +} \ No newline at end of file diff --git a/packages/dvilela/contracts/olas_tokenomics/contract.py b/packages/dvilela/contracts/olas_tokenomics/contract.py new file mode 100644 index 0000000..c6c3262 --- /dev/null +++ b/packages/dvilela/contracts/olas_tokenomics/contract.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2021-2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the class to connect to the tokenomics contract.""" +import logging +from typing import List, Optional, Union, cast + +from aea.common import JSONLike +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea_ledger_ethereum import EthereumApi +from web3.exceptions import MismatchedABI + + +PUBLIC_ID = PublicId.from_str("dvilela/olas_tokenomics:0.1.0") + +_logger = logging.getLogger( + f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" +) + + +# pylint: disable=too-many-arguments,invalid-name +class OlasTokenomicsContract(Contract): + """The olas tokenomics contract.""" + + contract_id = PUBLIC_ID + + @classmethod + def get_events( # pylint: disable=unused-argument + cls, + ledger_api: EthereumApi, + contract_address: str, + event_name: str, + from_block: int, + to_block: Union[int, str] = "latest", + chain_name: str = "ethereum", + ) -> Optional[JSONLike]: + """Get events.""" + contract_instance = cls.get_instance(ledger_api, contract_address) + + # Avoid parsing too many blocks at a time. This might take too long and + # the connection could time out. + MAX_BLOCKS = 5000 + + to_block = ( + ledger_api.api.eth.get_block_number() - 1 + if to_block == "latest" + else to_block + ) + + ranges: List[int] = list(range(from_block, cast(int, to_block), MAX_BLOCKS)) + [ + cast(int, to_block) + ] + + event = getattr(contract_instance.events, event_name) + events = [] + for i in range(len(ranges) - 1): + from_block = ranges[i] + to_block = ranges[i + 1] + new_events = [] + + while True: + try: + new_events = event.create_filter( + fromBlock=from_block, # exclusive + toBlock=to_block, # inclusive + ).get_all_entries() # limited to 10k entries for now + break + # Gnosis RPCs sometimes returns: + # ValueError: Filter with id: x does not exist + # MismatchedABI: The event signature did not match the provided ABI + # Retrying several times makes it work + except ValueError as e: + _logger.error(e) + except MismatchedABI as e: + _logger.error(e) + + events += new_events + + return dict( + events=events, + latest_block=int(to_block), + ) diff --git a/packages/dvilela/contracts/olas_tokenomics/contract.yaml b/packages/dvilela/contracts/olas_tokenomics/contract.yaml new file mode 100644 index 0000000..42545ef --- /dev/null +++ b/packages/dvilela/contracts/olas_tokenomics/contract.yaml @@ -0,0 +1,23 @@ +name: olas_tokenomics +author: dvilela +version: 0.1.0 +type: contract +description: Service Registry contract +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeigluox22eqqusqzynkbowsq4bnrw4gwodaawets5i2hrp42v43jfm + build/OlasTokenomics.json: bafybeic4dyhqnnfnivfee5krnfyffmglk7icnmoo4wr7kmoixnllrh2jje + contract.py: bafybeiafc7acx2ffv2p2ys6kzq3ltptreud26rkoindvqkyxlild42xzde +fingerprint_ignore_patterns: [] +contracts: [] +class_name: OlasTokenomicsContract +contract_interface_paths: + ethereum: build/OlasTokenomics.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.52.0 + open-aea-test-autonomy: + version: ==0.14.12 + web3: + version: <7,>=6.0.0 diff --git a/packages/dvilela/contracts/olas_treasury/__init__.py b/packages/dvilela/contracts/olas_treasury/__init__.py new file mode 100644 index 0000000..b122ec0 --- /dev/null +++ b/packages/dvilela/contracts/olas_treasury/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2022 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the support resources for the treasury contract.""" diff --git a/packages/dvilela/contracts/olas_treasury/build/OlasTreasury.json b/packages/dvilela/contracts/olas_treasury/build/OlasTreasury.json new file mode 100644 index 0000000..ae5de61 --- /dev/null +++ b/packages/dvilela/contracts/olas_treasury/build/OlasTreasury.json @@ -0,0 +1,1099 @@ +{ + "abi": [ + { + "inputs":[ + { + "internalType":"address", + "name":"_olas", + "type":"address" + }, + { + "internalType":"address", + "name":"_tokenomics", + "type":"address" + }, + { + "internalType":"address", + "name":"_depository", + "type":"address" + }, + { + "internalType":"address", + "name":"_dispenser", + "type":"address" + } + ], + "stateMutability":"payable", + "type":"constructor" + }, + { + "inputs":[ + + ], + "name":"AlreadyInitialized", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"bondId", + "type":"uint256" + } + ], + "name":"BondNotRedeemable", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"uint256", + "name":"reward", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"topUp", + "type":"uint256" + } + ], + "name":"ClaimIncentivesFailed", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"DelegatecallOnly", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"DonatorBlacklisted", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"expected", + "type":"uint256" + } + ], + "name":"InsufficientAllowance", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"expected", + "type":"uint256" + } + ], + "name":"LowerThan", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"sender", + "type":"address" + }, + { + "internalType":"address", + "name":"manager", + "type":"address" + } + ], + "name":"ManagerOnly", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"NonZeroValue", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"max", + "type":"uint256" + } + ], + "name":"Overflow", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"sender", + "type":"address" + }, + { + "internalType":"address", + "name":"owner", + "type":"address" + } + ], + "name":"OwnerOnly", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"Paused", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"productId", + "type":"uint256" + } + ], + "name":"ProductClosed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"tokenAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"productId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"deadline", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"curTime", + "type":"uint256" + } + ], + "name":"ProductExpired", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"tokenAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"productId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"requested", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"actual", + "type":"uint256" + } + ], + "name":"ProductSupplyLow", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"ReentrancyGuard", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"SameBlockNumberViolation", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"serviceId", + "type":"uint256" + } + ], + "name":"ServiceDoesNotExist", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"serviceId", + "type":"uint256" + } + ], + "name":"ServiceNeverDeployed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"token", + "type":"address" + }, + { + "internalType":"address", + "name":"from", + "type":"address" + }, + { + "internalType":"address", + "name":"to", + "type":"address" + }, + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"TransferFailed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"epochNumber", + "type":"uint256" + } + ], + "name":"TreasuryRebalanceFailed", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"tokenAddress", + "type":"address" + } + ], + "name":"UnauthorizedToken", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"provided", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"expected", + "type":"uint256" + } + ], + "name":"WrongAmount", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"numValues1", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"numValues2", + "type":"uint256" + } + ], + "name":"WrongArrayLength", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"provided", + "type":"address" + }, + { + "internalType":"address", + "name":"expected", + "type":"address" + } + ], + "name":"WrongTokenAddress", + "type":"error" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"unitId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"unitType", + "type":"uint256" + } + ], + "name":"WrongUnitId", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"ZeroAddress", + "type":"error" + }, + { + "inputs":[ + + ], + "name":"ZeroValue", + "type":"error" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"token", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"tokenAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"olasAmount", + "type":"uint256" + } + ], + "name":"DepositTokenFromAccount", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"depository", + "type":"address" + } + ], + "name":"DepositoryUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"token", + "type":"address" + } + ], + "name":"DisableToken", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"dispenser", + "type":"address" + } + ], + "name":"DispenserUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256[]", + "name":"serviceIds", + "type":"uint256[]" + }, + { + "indexed":false, + "internalType":"uint256[]", + "name":"amounts", + "type":"uint256[]" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"donation", + "type":"uint256" + } + ], + "name":"DonateToServicesETH", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"token", + "type":"address" + } + ], + "name":"EnableToken", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"MinAcceptedETHUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"owner", + "type":"address" + } + ], + "name":"OwnerUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + + ], + "name":"PauseTreasury", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"ReceiveETH", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"tokenomics", + "type":"address" + } + ], + "name":"TokenomicsUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + + ], + "name":"UnpauseTreasury", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"ETHOwned", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"ETHFromServices", + "type":"uint256" + } + ], + "name":"UpdateTreasuryBalances", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"token", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"to", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"tokenAmount", + "type":"uint256" + } + ], + "name":"Withdraw", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"ETHFromServices", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ETHOwned", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ETH_TOKEN_ADDRESS", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_tokenomics", + "type":"address" + }, + { + "internalType":"address", + "name":"_depository", + "type":"address" + }, + { + "internalType":"address", + "name":"_dispenser", + "type":"address" + } + ], + "name":"changeManagers", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_minAcceptedETH", + "type":"uint256" + } + ], + "name":"changeMinAcceptedETH", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"newOwner", + "type":"address" + } + ], + "name":"changeOwner", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256[]", + "name":"serviceIds", + "type":"uint256[]" + }, + { + "internalType":"uint256[]", + "name":"amounts", + "type":"uint256[]" + } + ], + "name":"depositServiceDonationsETH", + "outputs":[ + + ], + "stateMutability":"payable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"uint256", + "name":"tokenAmount", + "type":"uint256" + }, + { + "internalType":"address", + "name":"token", + "type":"address" + }, + { + "internalType":"uint256", + "name":"olasMintAmount", + "type":"uint256" + } + ], + "name":"depositTokenForOLAS", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"depository", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"token", + "type":"address" + } + ], + "name":"disableToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"dispenser", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"drainServiceSlashedFunds", + "outputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"token", + "type":"address" + } + ], + "name":"enableToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"token", + "type":"address" + } + ], + "name":"isEnabled", + "outputs":[ + { + "internalType":"bool", + "name":"enabled", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"mapEnabledTokens", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"mapTokenReserves", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"minAcceptedETH", + "outputs":[ + { + "internalType":"uint96", + "name":"", + "type":"uint96" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"olas", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"owner", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"pause", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"paused", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"treasuryRewards", + "type":"uint256" + } + ], + "name":"rebalanceTreasury", + "outputs":[ + { + "internalType":"bool", + "name":"success", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"tokenomics", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"unpause", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"to", + "type":"address" + }, + { + "internalType":"uint256", + "name":"tokenAmount", + "type":"uint256" + }, + { + "internalType":"address", + "name":"token", + "type":"address" + } + ], + "name":"withdraw", + "outputs":[ + { + "internalType":"bool", + "name":"success", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"uint256", + "name":"accountRewards", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"accountTopUps", + "type":"uint256" + } + ], + "name":"withdrawToAccount", + "outputs":[ + { + "internalType":"bool", + "name":"success", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "stateMutability":"payable", + "type":"receive" + } + ], + "bytecode": "" +} \ No newline at end of file diff --git a/packages/dvilela/contracts/olas_treasury/contract.py b/packages/dvilela/contracts/olas_treasury/contract.py new file mode 100644 index 0000000..5776c85 --- /dev/null +++ b/packages/dvilela/contracts/olas_treasury/contract.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2021-2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the class to connect to the treasury contract.""" +import logging +from typing import List, Optional, Union, cast + +from aea.common import JSONLike +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea_ledger_ethereum import EthereumApi +from web3.exceptions import MismatchedABI + + +PUBLIC_ID = PublicId.from_str("dvilela/olas_treasury:0.1.0") + +_logger = logging.getLogger( + f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" +) + + +# pylint: disable=too-many-arguments,invalid-name +class OlasTreasuryContract(Contract): + """The olas treasury contract.""" + + contract_id = PUBLIC_ID + + @classmethod + def get_events( # pylint: disable=unused-argument + cls, + ledger_api: EthereumApi, + contract_address: str, + event_name: str, + from_block: int, + to_block: Union[int, str] = "latest", + chain_name: str = "ethereum", + ) -> Optional[JSONLike]: + """Get events.""" + contract_instance = cls.get_instance(ledger_api, contract_address) + + # Avoid parsing too many blocks at a time. This might take too long and + # the connection could time out. + MAX_BLOCKS = 5000 + + to_block = ( + ledger_api.api.eth.get_block_number() - 1 + if to_block == "latest" + else to_block + ) + + ranges: List[int] = list(range(from_block, cast(int, to_block), MAX_BLOCKS)) + [ + cast(int, to_block) + ] + + event = getattr(contract_instance.events, event_name) + events = [] + for i in range(len(ranges) - 1): + from_block = ranges[i] + to_block = ranges[i + 1] + new_events = [] + + while True: + try: + new_events = event.create_filter( + fromBlock=from_block, # exclusive + toBlock=to_block, # inclusive + ).get_all_entries() # limited to 10k entries for now + break + # Gnosis RPCs sometimes returns: + # ValueError: Filter with id: x does not exist + # MismatchedABI: The event signature did not match the provided ABI + # Retrying several times makes it work + except ValueError as e: + _logger.error(e) + except MismatchedABI as e: + _logger.error(e) + + events += new_events + + return dict( + events=events, + latest_block=int(to_block), + ) diff --git a/packages/dvilela/contracts/olas_treasury/contract.yaml b/packages/dvilela/contracts/olas_treasury/contract.yaml new file mode 100644 index 0000000..e7e46ae --- /dev/null +++ b/packages/dvilela/contracts/olas_treasury/contract.yaml @@ -0,0 +1,23 @@ +name: olas_treasury +author: dvilela +version: 0.1.0 +type: contract +description: Service Registry contract +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeigv5vccsux5xbgxdowpxet2qwzyym6jzxxycvuuf3bqpaxe6zpaem + build/OlasTreasury.json: bafybeier45zqqza5guhusfhchu6d63yktigfxvojq4so2ftmslxeezbk3m + contract.py: bafybeidoby6xmkztlqdkeqmg6larbibbwavrf7b563ngemie24k664jnlq +fingerprint_ignore_patterns: [] +contracts: [] +class_name: OlasTreasuryContract +contract_interface_paths: + ethereum: build/OlasTreasury.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.52.0 + open-aea-test-autonomy: + version: ==0.14.12 + web3: + version: <7,>=6.0.0 diff --git a/packages/dvilela/services/tsunami/service.yaml b/packages/dvilela/services/tsunami/service.yaml index e25803b..59788d3 100644 --- a/packages/dvilela/services/tsunami/service.yaml +++ b/packages/dvilela/services/tsunami/service.yaml @@ -8,7 +8,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeibh5bgshii5oqjfuhwmiivfvfqy7fw5pzvarxkpe4qrgivxtc3xym fingerprint_ignore_patterns: [] -agent: dvilela/tsunami:0.1.0:bafybeidplwab7irdxxasjk3ir3wgnmxwg7dc5us5oijmnijnu7pjlgtmxa +agent: dvilela/tsunami:0.1.0:bafybeiac2s5bwsi54yu2azqh6hvyhx3wnene2mesfmfaxonyuxqo4fgqhm number_of_agents: 1 deployment: agent: @@ -96,6 +96,8 @@ extra: agent_registry_address_ethereum: ${AGENT_REGISTRY_ADDRESS_ETHEREUM:str:0x2F1f7D38e4772884b88f3eCd8B6b9faCdC319112} component_registry_address_ethereum: ${COMPONENT_REGISTRY_ADDRESS_ETHEREUM:str:0x15bd56669F57192a97dF41A2aa8f4403e9491776} service_registry_address_gnosis: ${SERVICE_REGISTRY_ADDRESS_GNOSIS:str:0x9338b5153AE39BB89f50468E608eD9d764B755fD} + treasury_address_ethereum: ${TREASURY_ADDRESS_ETHEREUM:str:0xa0DA53447C0f6C4987964d8463da7e6628B30f82} + tokenomics_address_ethereum: ${TOKENOMICS_ADDRESS_ETHEREUM:str:0xc096362fa6f4A4B1a9ea68b1043416f3381ce300} initial_block_ethereum: ${INITIAL_BLOCK_ETHEREUM:int:18500000} initial_block_gnosis: ${INITIAL_BLOCK_GNOSIS:int:18500000} twitter_credentials: ${TWITTER_CREDENTIALS:str:{}} @@ -176,4 +178,5 @@ public_id: valory/http_server:0.22.0:bafybeicblltx7ha3ulthg7bzfccuqqyjmihhrvfezt type: connection config: host: ${HTTP_SERVER_HOST:str:0.0.0.0} + port: ${HTTP_SERVER_PORT:int:8000} target_skill_id: dvilela/tsunami_chained_abci:0.1.0 diff --git a/packages/dvilela/skills/tsunami_abci/behaviours.py b/packages/dvilela/skills/tsunami_abci/behaviours.py index 4b4a90c..82879bd 100644 --- a/packages/dvilela/skills/tsunami_abci/behaviours.py +++ b/packages/dvilela/skills/tsunami_abci/behaviours.py @@ -40,6 +40,8 @@ PUBLIC_ID as SUNO_CONNECTION_PUBLIC_ID, ) from packages.dvilela.contracts.olas_registries.contract import OlasRegistriesContract +from packages.dvilela.contracts.olas_tokenomics.contract import OlasTokenomicsContract +from packages.dvilela.contracts.olas_treasury.contract import OlasTreasuryContract from packages.dvilela.protocols.kv_store.dialogues import ( KvStoreDialogue, KvStoreDialogues, @@ -228,26 +230,51 @@ def __init__(self, **kwargs: Any): self.tracked_events = { "ethereum": { "service_registry": { + "contract_id": str(OlasRegistriesContract.contract_id), "contract_address": self.params.service_registry_address_ethereum, "event_to_template": { "CreateService": EVENT_USER_PROMPT_TEMPLATES["service_minted"], }, + "build_thread_function": self.build_registry_tweet, }, "agent_registry": { + "contract_id": str(OlasRegistriesContract.contract_id), "contract_address": self.params.agent_registry_address_ethereum, "event_to_template": { "CreateUnit": EVENT_USER_PROMPT_TEMPLATES["agent_minted"] }, + "build_thread_function": self.build_registry_tweet, }, "component_registry": { + "contract_id": str(OlasRegistriesContract.contract_id), "contract_address": self.params.component_registry_address_ethereum, "event_to_template": { "CreateUnit": EVENT_USER_PROMPT_TEMPLATES["component_minted"] }, + "build_thread_function": self.build_registry_tweet, + }, + "tokenomics": { + "contract_id": str(OlasTokenomicsContract.contract_id), + "contract_address": self.params.tokenomics_address_ethereum, + "event_to_template": { + "EpochSettled": EVENT_USER_PROMPT_TEMPLATES["epoch_settled"] + }, + "build_thread_function": self.build_tokenomics_tweet, + }, + "treasury": { + "contract_id": str(OlasTreasuryContract.contract_id), + "contract_address": self.params.treasury_address_ethereum, + "event_to_template": { + "DonateToServicesETH": EVENT_USER_PROMPT_TEMPLATES[ + "donation_sent" + ] + }, + "build_thread_function": self.build_treasury_tweet, }, }, "gnosis": { "service_registry": { + "contract_id": str(OlasRegistriesContract.contract_id), "contract_address": self.params.service_registry_address_gnosis, "event_to_template": { "CreateService": EVENT_USER_PROMPT_TEMPLATES["service_minted"], @@ -490,7 +517,10 @@ def _do_connection_request( return response def build_thread( - self, user_prompt: str, header: Optional[str] = None + self, + user_prompt: str, + header: Optional[str] = None, + footer: Optional[str] = None, ) -> Generator[None, None, Optional[List[str]]]: """Build thread""" @@ -529,6 +559,10 @@ def build_thread( if "#OlasNetwork" not in tweet_attempt: tweet_attempt += " #OlasNetwork" + # Add footer + if footer: + tweet_attempt = tweet_attempt + footer + # Create a single-tweet thread if tweet_len(tweet_attempt) < MAX_TWEET_CHARS: self.context.logger.info("Tweet is OK!") @@ -556,6 +590,205 @@ def build_thread( return thread + def get_token_uri( + self, chain_id: str, contract_id: str, contract_address: str, unit_id: str + ) -> Generator[None, None, Optional[str]]: + """Get registries events""" + + self.context.logger.info( + f"Retrieving uri for unit_id {unit_id} on contract {chain_id}::{contract_id}::{contract_address}" + ) + + contract_api_msg = yield from self.get_contract_api_response( + performative=ContractApiMessage.Performative.GET_STATE, # type: ignore + contract_address=contract_address, + contract_id=contract_id, + contract_callable="get_token_uri", + unit_id=unit_id, + chain_id=chain_id, + ) + + if contract_api_msg.performative != ContractApiMessage.Performative.STATE: + self.context.logger.info( + f"Error retrieving the events [{contract_api_msg.performative}]" + ) + return None + + uri = cast(dict, contract_api_msg.state.body)["result"] + + self.context.logger.info(f"Got uri: {uri}") + + return uri + + def build_registry_tweet( # pylint: disable=too-many-arguments,too-many-locals + self, + chain_id: str, + contract_id: str, + contract_name: str, + contract_address: str, + event_name: str, + event: Any, + event_template: str, + ) -> Generator[None, None, Tuple[Optional[List[str]], Optional[str]]]: + """Build a thread for a registry event""" + + unit_type = "service" if contract_name == "service_registry" else "unit" + component_type = contract_name.split("_", maxsplit=1)[ + 0 + ] # service, agent or component + + self.context.logger.info(f"Processing registry event {event}") + + unit_id = getattr(event.args, f"{unit_type}Id") + + kwargs = { + "unit_id": unit_id, + "chain_name": chain_id, + } + + user_prompt = event_template.format(**kwargs) + + # Get token URI + uri = yield from self.get_token_uri( + chain_id, contract_id, contract_address, unit_id + ) + + if uri is None: + self.context.logger.error( + f"Error while retieving uri: {uri}\n. Skipping event {chain_id}:{contract_name}:{event_name}:{event}..." + ) + return None, None + + # Get unit data + self.context.logger.info("Getting token data...") + response = yield from self.get_http_response( # type: ignore + method="GET", url=uri + ) + + if response.status_code != HTTP_OK: # type: ignore + self.context.logger.error( + f"Error while download token data: {response}\n. Skipping event {chain_id}:{contract_name}:{event_name}:{event}...\n{response}" # type: ignore + ) + return None, None + + response_json = json.loads(response.body) # type: ignore + self.context.logger.info(f"Got token data: {response_json}") + + unit_name = response_json["name"] + unit_description = response_json["description"] + user_prompt += f" The {unit_type}'s name is {unit_name}. Its description is: {unit_description}'" + unit_url = f"{OLAS_REGISTRY_URL}/{chain_id}/{component_type}s/{unit_id}" + + thread = yield from self.build_thread(user_prompt) + + return thread, unit_url + + def build_tokenomics_tweet( # pylint: disable=too-many-arguments,too-many-locals,unused-argument + self, + chain_id: str, + contract_id: str, + contract_name: str, + contract_address: str, + event_name: str, + event: Any, + event_template: str, + ) -> Generator[None, None, Tuple[Optional[List[str]], Optional[str]]]: + """Build a thread for a tokenomics event""" + + self.context.logger.info(f"Processing tokenomics event {event}") + + kwargs = { + "n_epoch": event.args["epochCounter"], + "eth_rewards": event.args["accountRewards"] / 1e18, + "olas_topups": event.args["accountTopUps"] / 1e18, + } + + user_prompt = event_template.format(**kwargs) + thread = yield from self.build_thread(user_prompt) + + return thread, None + + def build_treasury_tweet( # pylint: disable=too-many-arguments,too-many-locals,unused-argument + self, + chain_id: str, + contract_id: str, + contract_name: str, + contract_address: str, + event_name: str, + event: Any, + event_template: str, + ) -> Generator[None, None, Tuple[Optional[List[str]], Optional[str]]]: + """Build a thread for a treasury event""" + + self.context.logger.info(f"Processing treasury event {event}") + + packages = yield from self.get_packages(package_type="service") + service_id_to_name = { + str(s["tokenId"]): s["publicId"] for s in packages["units"] # type: ignore + } + + donations = [ + f"Here's the complete list of donations from address {event.args['sender']}:" + ] + if packages: + for amount, service_id in zip( + event.args["amounts"], event.args["serviceIds"] + ): + service_name = service_id_to_name[str(service_id)] + donations.append(f"☴ {amount / 1e18:.2f} ETH for {service_name}") + + kwargs = { + "donator": event.args["sender"], + "amount": event.args["donation"] / 1e18, + "n_services": len(event.args["serviceIds"]), + } + + user_prompt = event_template.format(**kwargs) + thread = yield from self.build_thread(user_prompt) + + if not thread: + return None, None + + thread += donations + + return thread, None + + def get_packages(self, package_type: str) -> Generator[None, None, Optional[Dict]]: + """Gets minted packages from the subgraph""" + + self.context.logger.info("Getting packages from Olas subgraph...") + + SUBGRAPH_URL = "https://subgraph.autonolas.tech/subgraphs/name/autonolas" + + headers = { + "Content-Type": "application/json", + } + + data = { + "query": AGENT_QUERY, + "variables": { + "package_type": package_type, + }, + } + + # Get all existing agents from the subgraph + self.context.logger.info("Getting agents from subgraph") + response = yield from self.get_http_response( # type: ignore + method="POST", + url=SUBGRAPH_URL, + headers=headers, + content=json.dumps(data).encode(), + ) + + if response.status_code != HTTP_OK: # type: ignore + self.context.logger.error( + f"Error getting agents from subgraph: {response}" # type: ignore + ) + return None + + response_json = json.loads(response.body)["data"] # type: ignore + return response_json + class TrackChainEventsBehaviour( TsunamiBaseBehaviour @@ -601,8 +834,6 @@ def build_tweets( # pylint: disable=too-many-locals,too-many-statements tweets = json.loads(response["tweets"]) self.context.logger.info(f"Loaded tweets from db: {tweets}") - contract_id = str(OlasRegistriesContract.contract_id) - # Chain loop for chain_id, contracts_data in self.tracked_events.items(): # Default from_block @@ -641,11 +872,8 @@ def build_tweets( # pylint: disable=too-many-locals,too-many-statements # Contract loop for contract_name, contract_data in contracts_data.items(): + contract_id = contract_data["contract_id"] contract_address = contract_data["contract_address"] - unit_type = "service" if contract_name == "service_registry" else "unit" - component_type = contract_name.split("_", maxsplit=1)[ - 0 - ] # service, agent or component # Event type loop for event_name, event_template in contract_data[ @@ -673,58 +901,27 @@ def build_tweets( # pylint: disable=too-many-locals,too-many-statements # Event loop for event in events: - self.context.logger.info(f"Processing event {event}") - - unit_id = getattr(event.args, f"{unit_type}Id") - - kwargs = { - "unit_id": unit_id, - "chain_name": chain_id, - } - - user_prompt = event_template.format(**kwargs) - - # Get token URI - uri = yield from self.get_token_uri( - chain_id, contract_id, contract_address, unit_id - ) - - if uri is None: - self.context.logger.error( - f"Error while retieving uri: {ledger_api_response}\n. Skipping event {chain_id}:{contract_name}:{event_name}:{event}..." - ) - continue - - # Get unit data - self.context.logger.info("Getting token data...") - response = yield from self.get_http_response( # type: ignore - method="GET", url=uri + build_thread_function = contract_data["build_thread_function"] + + thread, link = yield from build_thread_function( + chain_id, + contract_id, + contract_name, + contract_address, + event_name, + event, + event_template, ) - if response.status_code != HTTP_OK: # type: ignore - self.context.logger.error( - f"Error while download token data: {ledger_api_response}\n. Skipping event {chain_id}:{contract_name}:{event_name}:{event}...\n{response}" # type: ignore - ) - continue - - response_json = json.loads(response.body) # type: ignore - self.context.logger.info(f"Got token data: {response_json}") - - unit_name = response_json["name"] - unit_description = response_json["description"] - user_prompt += f" The {unit_type}'s name is {unit_name}. Its description is: {unit_description}'" - unit_url = f"{OLAS_REGISTRY_URL}/{chain_id}/{component_type}s/{unit_id}" - - thread = yield from self.build_thread(user_prompt) - if thread is None: self.context.logger.error( "Error while building thread. Skipping..." ) continue - # Add a link to the unit - thread.append(unit_url) + # Add a link to the event + if link: + thread.append(link) tweets.append( { @@ -790,36 +987,6 @@ def get_events( # pylint: disable=too-many-arguments return events, latest_block - def get_token_uri( - self, chain_id: str, contract_id: str, contract_address: str, unit_id: str - ) -> Generator[None, None, Optional[str]]: - """Get registries events""" - - self.context.logger.info( - f"Retrieving uri for unit_id {unit_id} on contract {chain_id}::{contract_id}::{contract_address}" - ) - - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=contract_address, - contract_id=contract_id, - contract_callable="get_token_uri", - unit_id=unit_id, - chain_id=chain_id, - ) - - if contract_api_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info( - f"Error retrieving the events [{contract_api_msg.performative}]" - ) - return None - - uri = cast(dict, contract_api_msg.state.body)["result"] - - self.context.logger.info(f"Got uri: {uri}") - - return uri - class TrackReposBehaviour(TsunamiBaseBehaviour): # pylint: disable=too-many-ancestors """TrackReposBehaviour""" @@ -1193,36 +1360,11 @@ def get_suno_tweets( # pylint: disable=too-many-locals,too-many-return-statemen ) return tweets - SUBGRAPH_URL = "https://subgraph.autonolas.tech/subgraphs/name/autonolas" - - headers = { - "Content-Type": "application/json", - } - - data = { - "query": AGENT_QUERY, - "variables": { - "package_type": "agent", - }, - } - - # Get all existing agents from the subgraph - self.context.logger.info("Getting agents from subgraph") - response = yield from self.get_http_response( # type: ignore - method="POST", - url=SUBGRAPH_URL, - headers=headers, - content=json.dumps(data).encode(), - ) - - if response.status_code != HTTP_OK: # type: ignore - self.context.logger.error( - f"Error getting agents from subgraph: {response}" # type: ignore - ) + packages = yield from self.get_packages(package_type="agent") + if not packages: return tweets - response_json = json.loads(response.body)["data"] # type: ignore - agents = [u for u in response_json["units"] if u["packageType"] == "agent"] + agents = [u for u in packages["units"] if u["packageType"] == "agent"] agents = sorted(agents, key=lambda i: int(i["tokenId"])) n_agents = len(agents) diff --git a/packages/dvilela/skills/tsunami_abci/models.py b/packages/dvilela/skills/tsunami_abci/models.py index c8f04e9..f79f03c 100644 --- a/packages/dvilela/skills/tsunami_abci/models.py +++ b/packages/dvilela/skills/tsunami_abci/models.py @@ -69,6 +69,12 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.service_registry_address_gnosis = self._ensure( "service_registry_address_gnosis", kwargs, str ) + self.treasury_address_ethereum = self._ensure( + "treasury_address_ethereum", kwargs, str + ) + self.tokenomics_address_ethereum = self._ensure( + "tokenomics_address_ethereum", kwargs, str + ) self.initial_block_ethereum = self._ensure( "initial_block_ethereum", kwargs, int ) diff --git a/packages/dvilela/skills/tsunami_abci/prompts.py b/packages/dvilela/skills/tsunami_abci/prompts.py index afcff19..7447e2d 100644 --- a/packages/dvilela/skills/tsunami_abci/prompts.py +++ b/packages/dvilela/skills/tsunami_abci/prompts.py @@ -77,11 +77,17 @@ EVENT_USER_PROMPT_SERVICE_CREATED = "A new service with id {unit_id} has been minted on the Olas protocol on {chain_name}." EVENT_USER_PROMPT_AGENT_CREATED = "A new agent with id {unit_id} has been minted on the Olas protocol on {chain_name}." EVENT_USER_PROMPT_COMPONENT_CREATED = "A new component with id {unit_id} has been minted on the Olas protocol on {chain_name}." +EVENT_USER_PROMPT_EPOCH_SETTLED = "Tokenomics epoch {n_epoch} has finished. A total of {eth_rewards:.2f} ETH and {olas_topups:.2f} OLAS have been distributed to Olas developers." +EVENT_USER_PROMPT_DONATION_SENT = ( + "Address {donator} has donated {amount:.2f} ETH to {n_services} services." +) EVENT_USER_PROMPT_TEMPLATES = { "service_minted": EVENT_USER_PROMPT_SERVICE_CREATED, "agent_minted": EVENT_USER_PROMPT_AGENT_CREATED, "component_minted": EVENT_USER_PROMPT_COMPONENT_CREATED, + "epoch_settled": EVENT_USER_PROMPT_EPOCH_SETTLED, + "donation_sent": EVENT_USER_PROMPT_DONATION_SENT, } REPO_USER_PROMPT_RELEASE = ( diff --git a/packages/dvilela/skills/tsunami_abci/skill.yaml b/packages/dvilela/skills/tsunami_abci/skill.yaml index 7bd9539..2bd7bad 100644 --- a/packages/dvilela/skills/tsunami_abci/skill.yaml +++ b/packages/dvilela/skills/tsunami_abci/skill.yaml @@ -8,13 +8,13 @@ license: Apache-2.0 aea_version: '>=1.0.0, <2.0.0' fingerprint: __init__.py: bafybeiaicsttkv5xapta2eqove7si2pyv3zmshkqolluxpnrh3hkulqsqu - behaviours.py: bafybeidcxd5rmllbvzdsb7qqjw74n5jfyhpi7zrjg7nkxjwqssnezzsbam + behaviours.py: bafybeiahkmts365cpdamupwoq3l3m6d4brmpnhlbiugbtvlgn5i4ys5zxy dialogues.py: bafybeidmgjji6zw6wcvhijrxb74batj2kc2lskfuqxv76duv2j7azcqwra fsm_specification.yaml: bafybeidlfuabsldhezjaovupkvzrtydpcimzz6r56phsi2psrtdzougu4u handlers.py: bafybeigjy73h3uaroovfuuo3ugffrm3oq6pntz5me7nrbsbiwwjceztj5m - models.py: bafybeibfh42jl5t3klvrwn5m27h25ae6iehnejk4bqirkeqel3eagx3r7y + models.py: bafybeicx5tpwcxy2hufcaydozc6ho4fjalgk4imfh3jgelt2rxea3h4ipu payloads.py: bafybeicejv72ralhxgwzkcprgj5akehu65jfik2cpwsnrxs7zlglpdrl6u - prompts.py: bafybeidsgafonns54625e334xrqgfundtzkgc3ct3pxpdbhc7eyue22ima + prompts.py: bafybeicjacdvtggitktvwnzqq6nsic7zf7qpaaf4gy7uepzjdr55ql2cs4 rounds.py: bafybeidmfi6v335lgvjidptqrvuruhtk5hhq3fkcubwbln7xbn2iiok7di subgraph.py: bafybeib7f63y2hozc73lgp3f4ehpssjd23oaotamemeg3xmwxy3esbdlii fingerprint_ignore_patterns: [] @@ -27,6 +27,8 @@ connections: - valory/http_server:0.22.0:bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m contracts: - dvilela/olas_registries:0.1.0:bafybeict2xpt56m2a5ehezd2oylrhbhahrsas3dht2fdfbnrejlr5mdqpa +- dvilela/olas_tokenomics:0.1.0:bafybeifslkoofg3ohscvovzhgaa3up5jhmb6fac4r35b5wcdjphafzssxu +- dvilela/olas_treasury:0.1.0:bafybeidd6yelhuztyvtbso6fkc4iiq2pmegh734exyrtcbqh62yfwgluqy protocols: - valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i - valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni @@ -153,6 +155,8 @@ models: agent_registry_address_ethereum: '0x2F1f7D38e4772884b88f3eCd8B6b9faCdC319112' component_registry_address_ethereum: '0x15bd56669F57192a97dF41A2aa8f4403e9491776' service_registry_address_gnosis: '0x9338b5153AE39BB89f50468E608eD9d764B755fD' + treasury_address_ethereum: '0xa0DA53447C0f6C4987964d8463da7e6628B30f82' + tokenomics_address_ethereum: '0xc096362fa6f4A4B1a9ea68b1043416f3381ce300' initial_block_ethereum: 18500000 initial_block_gnosis: 18500000 twitter_credentials: '{}' diff --git a/packages/dvilela/skills/tsunami_chained_abci/skill.yaml b/packages/dvilela/skills/tsunami_chained_abci/skill.yaml index c603796..510c571 100644 --- a/packages/dvilela/skills/tsunami_chained_abci/skill.yaml +++ b/packages/dvilela/skills/tsunami_chained_abci/skill.yaml @@ -23,7 +23,7 @@ skills: - valory/reset_pause_abci:0.1.0:bafybeiameewywqigpupy3u2iwnkfczeiiucue74x2l5lbge74rmw6bgaie - valory/transaction_settlement_abci:0.1.0:bafybeic3tccdjypuge2lewtlgprwkbb53lhgsgn7oiwzyrcrrptrbeyote - valory/termination_abci:0.1.0:bafybeif2zim2de356eo3sipkmoev5emwadpqqzk3huwqarywh4tmqt3vzq -- dvilela/tsunami_abci:0.1.0:bafybeidzlzl4yqkw36uw6c3tbq5mz2twmkto6fkerv2skkcvmbtdnjmfjq +- dvilela/tsunami_abci:0.1.0:bafybeifb4oatjxqa5tc37xxb36ru5wktebqqy4f5ig6d6wnwsovvyjysii behaviours: main: args: {} @@ -150,6 +150,8 @@ models: agent_registry_address_ethereum: '0x2F1f7D38e4772884b88f3eCd8B6b9faCdC319112' component_registry_address_ethereum: '0x15bd56669F57192a97dF41A2aa8f4403e9491776' service_registry_address_gnosis: '0x9338b5153AE39BB89f50468E608eD9d764B755fD' + treasury_address_ethereum: '0xa0DA53447C0f6C4987964d8463da7e6628B30f82' + tokenomics_address_ethereum: '0xc096362fa6f4A4B1a9ea68b1043416f3381ce300' initial_block_ethereum: 18500000 initial_block_gnosis: 18500000 twitter_credentials: '{}' diff --git a/packages/packages.json b/packages/packages.json index 3b8f829..07a4d3a 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -2,14 +2,16 @@ "dev": { "protocol/dvilela/kv_store/0.1.0": "bafybeihimf5f37uupxmugvagmaxworgmz7cxuqpikkyzlgldtbq46jbvci", "contract/dvilela/olas_registries/0.1.0": "bafybeict2xpt56m2a5ehezd2oylrhbhahrsas3dht2fdfbnrejlr5mdqpa", + "contract/dvilela/olas_tokenomics/0.1.0": "bafybeifslkoofg3ohscvovzhgaa3up5jhmb6fac4r35b5wcdjphafzssxu", + "contract/dvilela/olas_treasury/0.1.0": "bafybeidd6yelhuztyvtbso6fkc4iiq2pmegh734exyrtcbqh62yfwgluqy", "connection/dvilela/kv_store/0.1.0": "bafybeiekugvb2kan4342hliluxl3h5och3fjwqoafdyttpcn57evvyztq4", "connection/dvilela/llama/0.1.0": "bafybeiauzzq2pxmn4brdqgdyxrrikbc5ywjpmetlajyohute5qtnn37aqq", "connection/valory/twitter/0.1.0": "bafybeihotqawulig3g4a7fosi4pljsjii2neiqxtepd42e2neemhqecfcq", "connection/dvilela/suno/0.1.0": "bafybeihy2phtjwbz27ntv55wxfk754kp5tjceujzsdbppjafljoydjflhi", - "skill/dvilela/tsunami_abci/0.1.0": "bafybeidzlzl4yqkw36uw6c3tbq5mz2twmkto6fkerv2skkcvmbtdnjmfjq", - "skill/dvilela/tsunami_chained_abci/0.1.0": "bafybeicqrebte42fxb4eokfemydjwmfqcfsr7gogl3jeiqrxrlklgmsibi", - "agent/dvilela/tsunami/0.1.0": "bafybeidplwab7irdxxasjk3ir3wgnmxwg7dc5us5oijmnijnu7pjlgtmxa", - "service/dvilela/tsunami/0.1.0": "bafybeigdblrlizsanfjxdoxuz4ctcbfnz2kmd27d7qo4qikm2umn3ylah4" + "skill/dvilela/tsunami_abci/0.1.0": "bafybeifb4oatjxqa5tc37xxb36ru5wktebqqy4f5ig6d6wnwsovvyjysii", + "skill/dvilela/tsunami_chained_abci/0.1.0": "bafybeiaj7y4bnugd45nlnfb6fz36ixnpzlhbgs76frukd7r2zyjooopngq", + "agent/dvilela/tsunami/0.1.0": "bafybeiac2s5bwsi54yu2azqh6hvyhx3wnene2mesfmfaxonyuxqo4fgqhm", + "service/dvilela/tsunami/0.1.0": "bafybeiaikowdosu6luqkyf43bjsjzfdboccgioaa2dzpdy747fzkyey7vq" }, "third_party": { "protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi", diff --git a/scripts/aea-config-replace.py b/scripts/aea-config-replace.py index a530b4e..bf2bc30 100644 --- a/scripts/aea-config-replace.py +++ b/scripts/aea-config-replace.py @@ -38,6 +38,10 @@ def main() -> None: "farcaster_mnemonic" ] = f"${{str:{os.getenv('FARCASTER_MNEMONIC')}}}" + config[2]["config"]["repo_id"] = f"${{str:{os.getenv('LLAMA_REPO_ID')}}}" + + config[2]["config"]["filename"] = f"${{str:{os.getenv('LLAMA_FILENAME')}}}" + config[5]["config"]["ledger_apis"]["ethereum"][ "address" ] = f"${{str:{os.getenv('ETHEREUM_LEDGER_RPC')}}}"