From abe44a9f78390a6f29699299c7e4280beb5c4ff5 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 14:12:17 +0300 Subject: [PATCH 1/8] rename ai agent --- .gitignore | 3 + LICENSE | 2 +- README.md | 121 +++++++++++++----- deployment/31337.json | 6 + docs/src/README.md | 86 ++++++++----- docs/src/src/AIAgent.sol/contract.AIAgent.md | 2 +- .../AIAgent.sol/contract.AIAgentFactory.md | 2 +- .../src/src/Artifact.sol/contract.Artifact.md | 2 +- .../Artifact.sol/contract.ArtifactFactory.md | 2 +- docs/src/src/Swan.sol/constants.Swan.md | 2 +- docs/src/src/Swan.sol/contract.Swan.md | 2 +- .../SwanManager.sol/abstract.SwanManager.md | 2 +- .../struct.SwanMarketParameters.md | 2 +- .../src/mock/SvanV2.sol/contract.SwanV2.md | 2 +- script/Deploy.s.sol | 4 +- script/HelperConfig.s.sol | 24 ++-- src/Swan.sol | 75 +++++------ src/{AIAgent.sol => SwanAgent.sol} | 28 ++-- src/{Artifact.sol => SwanArtifact.sol} | 8 +- src/SwanManager.sol | 3 +- test/Helper.t.sol | 44 ++++--- ...{AIAgentTest.t.sol => SwanAgentTest.t.sol} | 45 ++++--- test/SwanFuzzTest.t.sol | 26 ++-- test/SwanIntervalsTest.t.sol | 20 +-- test/SwanTest.t.sol | 98 +++++++------- .../SvanV2.sol => test/contracts/SwanV2.sol | 3 +- test/{ => contracts}/WETH9.sol | 0 27 files changed, 349 insertions(+), 265 deletions(-) rename src/{AIAgent.sol => SwanAgent.sol} (95%) rename src/{Artifact.sol => SwanArtifact.sol} (87%) rename test/{AIAgentTest.t.sol => SwanAgentTest.t.sol} (74%) rename src/mock/SvanV2.sol => test/contracts/SwanV2.sol (66%) rename test/{ => contracts}/WETH9.sol (100%) diff --git a/.gitignore b/.gitignore index 8242ced..c0dc496 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ storage/ # Dotenv file .env + +# appleeeee +.DS_Store diff --git a/LICENSE b/LICENSE index 0589540..26ade36 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright 2023 FirstBatch +Copyright 2024 FirstBatch Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 87ccba3..88f7afe 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,48 @@ -# Swan Protocol -Swan is a **Decentralized Protocol** where AI agents (buyers) dynamically interact with asset creators. Agents operate with budgets to purchase assets that match their objectives. Asset creators design assets to align with buyers’ needs to convince the LLM to buy their asset/assets. +

+ logo +

+ +

+

+ Swan Protocol +

+

+ Simulated Worlds with AI Narratives. +

+

+ +

+ + License: Apache 2.0 + + + Workflow: Tests + + + Discord + +

+ +Swan is a decentralized protocol where AI agents dynamically interact with users who create artifacts inlined with agent's narratives. + +## Installation + +First, make sure you have the requirements: + +- We are using [Foundry](https://book.getfoundry.sh/), so make sure you [install](https://book.getfoundry.sh/getting-started/installation) it first. +- Upgradable contracts make use of [NodeJS](https://nodejs.org/en), so you should [install](https://nodejs.org/en/download/package-manager) that as well. + +Clone the repository: -## Compile +```sh +git clone git@github.com:firstbatchxyz/swan-contracts.git +``` + +Install dependencies with: + +```sh +forge install +``` Compile the contracts with: @@ -9,22 +50,25 @@ Compile the contracts with: forge clean && forge build ``` -> [!NOTE] -> -> Openzeppelin' foundry modules expect that running `forge clean` before running Foundry script or test or include `--force` option when running `forge script` or `forge test`. +### Upgradability -## Test +We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library. To make sure upgrades are **safe**, you must do one of the following before you run `forge script` or `forge test` (as per their [docs](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running)): -Run tests on local: +- `forge clean` beforehand, e.g. `forge clean && forge test` +- include `--force` option when running, e.g. `forge test --force` -```sh -forge clean && forge test -``` +> Note that for some users this may fail (see [issue](https://github.com/firstbatchxyz/dria-oracle-contracts/issues/16)) due to a missing NPM package called `@openzeppelin/upgrades-core`. To fix it, do: +> +> ```sh +> npm install @openzeppelin/upgrades-core@latest -g +> ``` + +### Updates -or on any other evm chain: +To update contracts to the latest library versions, use: ```sh -forge clean && forge test --rpc-url +forge update ``` ## Deployment @@ -42,6 +86,7 @@ Create keystores for deployment. [See more for keystores](https://eips.ethereum. ```sh cast wallet import --interactive ``` + You can see your wallets with: ```sh @@ -66,18 +111,17 @@ Deploy the contract with: ```sh forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast ``` + or for instant verification use: ```sh forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast --verify --verifier --verifier-url ``` -> [!NOTE] -> `` should be expolorer's homepage url. Forge reads your `` from .env file so you don't need to add this at the end of ``. +> [!NOTE] > `` should be expolorer's homepage url. Forge reads your `` from .env file so you don't need to add this at the end of ``. > -> e.g. +> e.g. > `https://base-sepolia.blockscout.com/api/` for `Base Sepolia Network` -> You can see deployed contract addresses under the `deployment/.json` @@ -89,13 +133,28 @@ Verify contract manually with: forge verify-contract src/$.sol: --verifier --verifier-url ``` -## Coverage +## Testing & Diagnostics + +Run tests on local network: + +```sh +forge clean && forge test +``` + +or fork an existing chain and run the tests on it: + +```sh +forge clean && forge test --rpc-url +``` + +### Coverage Check coverages with: ```sh forge clean && bash coverage.sh ``` + or to see summarized coverages on terminal: ```sh @@ -104,7 +163,7 @@ forge clean && forge coverage --no-match-coverage "(test|mock|script)" You can see coverages under the coverage directory. -## Storage Layout +### Storage Layout Get storage layout with: @@ -114,7 +173,7 @@ forge clean && bash storage.sh You can see storage layouts under the storage directory. -## Gas Snapshot +### Gas Snapshot Take the gas snapshot with: @@ -124,28 +183,20 @@ forge clean && forge snapshot You can see the snapshot `.gas-snapshot` file in the current directory. -## Format +## Documentation -Format code with: - -```sh -forge fmt -``` - -## Generate documentation - -Generate documentation with: +We have auto-generated documentation under the [`docs`](./docs) folder, generated with the following command: ```sh forge doc ``` -## Update - -Update modules with: +We provide an MDBook template over it, which you can open via: ```sh -forge update +cd docs && mdbook serve --open ``` -You can see the documentation under the `docs/` directory. +## License + +We are using Apache-2.0 license. diff --git a/deployment/31337.json b/deployment/31337.json index 1d6aadb..3a5adfa 100644 --- a/deployment/31337.json +++ b/deployment/31337.json @@ -16,5 +16,11 @@ "Swan": { "proxyAddr": "0xdeb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", "implAddr": "0x62c20aa1e0272312bc100b4e23b4dc1ed96dd7d1" + }, + "SwanAgentFactory": { + "addr": "0x34a1d3fff3958843c43ad80f30b94c510645c316" + }, + "SwanArtifactFactory": { + "addr": "0x90193c961a926261b756d1e5bb255e67ff9498a1" } } \ No newline at end of file diff --git a/docs/src/README.md b/docs/src/README.md index a6394ed..2c88f81 100644 --- a/docs/src/README.md +++ b/docs/src/README.md @@ -1,30 +1,41 @@ -# Swan Protocol -Swan is a **Decentralized Protocol** where AI agents (buyers) dynamically interact with asset creators. Agents operate with budgets to purchase assets that match their objectives. Asset creators design assets to align with buyers’ needs to convince the LLM to buy their asset/assets. +

+ logo +

-## Compile +

+

+ Swan Protocol +

+

+ Simulated Worlds with AI Narratives. +

+

-Compile the contracts with: +Swan is a decentralized protocol where AI agents dynamically interact with users who create artifacts inlined with agent's narratives. -```sh -forge clean && forge build -``` +## Installation -> [!NOTE] -> -> Openzeppelin' foundry modules expect that running `forge clean` before running Foundry script or test or include `--force` option when running `forge script` or `forge test`. +Install everything with: -## Test +```sh +forge install +``` -Run tests on local: +Compile the contracts with: ```sh -forge clean && forge test +forge clean && forge build ``` -or on any other evm chain: +We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library. To make sure upgrades are **safe**, you must do one of the following before you run `forge script` or `forge test` (as per their [docs](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running)): + +- `forge clean` beforehand, e.g. `forge clean && forge test` +- include `--force` option when running, e.g. `forge test --force` + +To update Swan in case any library is updated, you can do: ```sh -forge clean && forge test --rpc-url +forge update ``` ## Deployment @@ -42,6 +53,7 @@ Create keystores for deployment. [See more for keystores](https://eips.ethereum. ```sh cast wallet import --interactive ``` + You can see your wallets with: ```sh @@ -66,18 +78,17 @@ Deploy the contract with: ```sh forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast ``` + or for instant verification use: ```sh -forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast --verify --verifier --verifier-url +forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast --verify --verifier --verifier-url ``` -> [!NOTE] -> `` should be expolorer's homepage url. Forge reads your `` from .env file so you don't need to add this at the end of ``. +> [!NOTE] > `` should be expolorer's homepage url. Forge reads your `` from .env file so you don't need to add this at the end of ``. > -> e.g. +> e.g. > `https://base-sepolia.blockscout.com/api/` for `Base Sepolia Network` -> You can see deployed contract addresses under the `deployment/.json` @@ -89,13 +100,28 @@ Verify contract manually with: forge verify-contract src/$.sol: --verifier --verifier-url ``` -## Coverage +## Testing & Diagnostics + +Run tests on local network: + +```sh +forge clean && forge test +``` + +or fork an existing chain and run the tests on it: + +```sh +forge clean && forge test --rpc-url +``` + +### Coverage Check coverages with: ```sh forge clean && bash coverage.sh ``` + or to see summarized coverages on terminal: ```sh @@ -104,7 +130,7 @@ forge clean && forge coverage --no-match-coverage "(test|mock|script)" You can see coverages under the coverage directory. -## Storage Layout +### Storage Layout Get storage layout with: @@ -114,7 +140,7 @@ forge clean && bash storage.sh You can see storage layouts under the storage directory. -## Gas Snapshot +### Gas Snapshot Take the gas snapshot with: @@ -132,20 +158,14 @@ Format code with: forge fmt ``` -## Generate documentation +## Documentation -Generate documentation with: +We have auto-generated documentation under the [`docs`](./docs) folder, generated with the following command: ```sh forge doc ``` -## Update - -Update modules with: - -```sh -forge update -``` +## License -You can see the documentation under the `docs/` directory. +We are using Apache-2.0 license. diff --git a/docs/src/src/AIAgent.sol/contract.AIAgent.md b/docs/src/src/AIAgent.sol/contract.AIAgent.md index 79bd2e2..df19295 100644 --- a/docs/src/src/AIAgent.sol/contract.AIAgent.md +++ b/docs/src/src/AIAgent.sol/contract.AIAgent.md @@ -1,5 +1,5 @@ # AIAgent -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/AIAgent.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/AIAgent.sol) **Inherits:** Ownable diff --git a/docs/src/src/AIAgent.sol/contract.AIAgentFactory.md b/docs/src/src/AIAgent.sol/contract.AIAgentFactory.md index fb18bbc..e172d62 100644 --- a/docs/src/src/AIAgent.sol/contract.AIAgentFactory.md +++ b/docs/src/src/AIAgent.sol/contract.AIAgentFactory.md @@ -1,5 +1,5 @@ # AIAgentFactory -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/AIAgent.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/AIAgent.sol) Factory contract to deploy AIAgent contracts. diff --git a/docs/src/src/Artifact.sol/contract.Artifact.md b/docs/src/src/Artifact.sol/contract.Artifact.md index ce053b9..a972dcb 100644 --- a/docs/src/src/Artifact.sol/contract.Artifact.md +++ b/docs/src/src/Artifact.sol/contract.Artifact.md @@ -1,5 +1,5 @@ # Artifact -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/Artifact.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/Artifact.sol) **Inherits:** ERC721, Ownable diff --git a/docs/src/src/Artifact.sol/contract.ArtifactFactory.md b/docs/src/src/Artifact.sol/contract.ArtifactFactory.md index 6d23f87..75ba7aa 100644 --- a/docs/src/src/Artifact.sol/contract.ArtifactFactory.md +++ b/docs/src/src/Artifact.sol/contract.ArtifactFactory.md @@ -1,5 +1,5 @@ # ArtifactFactory -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/Artifact.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/Artifact.sol) Factory contract to deploy Artifact tokens. diff --git a/docs/src/src/Swan.sol/constants.Swan.md b/docs/src/src/Swan.sol/constants.Swan.md index 549a937..6b85ff3 100644 --- a/docs/src/src/Swan.sol/constants.Swan.md +++ b/docs/src/src/Swan.sol/constants.Swan.md @@ -1,5 +1,5 @@ # Constants -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/Swan.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/Swan.sol) ### SwanAIAgentPurchaseOracleProtocol diff --git a/docs/src/src/Swan.sol/contract.Swan.md b/docs/src/src/Swan.sol/contract.Swan.md index 71c2a50..5b49138 100644 --- a/docs/src/src/Swan.sol/contract.Swan.md +++ b/docs/src/src/Swan.sol/contract.Swan.md @@ -1,5 +1,5 @@ # Swan -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/Swan.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/Swan.sol) **Inherits:** [SwanManager](/src/SwanManager.sol/abstract.SwanManager.md), UUPSUpgradeable diff --git a/docs/src/src/SwanManager.sol/abstract.SwanManager.md b/docs/src/src/SwanManager.sol/abstract.SwanManager.md index 6d77972..bd6ceb1 100644 --- a/docs/src/src/SwanManager.sol/abstract.SwanManager.md +++ b/docs/src/src/SwanManager.sol/abstract.SwanManager.md @@ -1,5 +1,5 @@ # SwanManager -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/SwanManager.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/SwanManager.sol) **Inherits:** OwnableUpgradeable diff --git a/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md b/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md index c341110..98df9f9 100644 --- a/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md +++ b/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md @@ -1,5 +1,5 @@ # SwanMarketParameters -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/SwanManager.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/SwanManager.sol) Collection of market-related parameters. diff --git a/docs/src/src/mock/SvanV2.sol/contract.SwanV2.md b/docs/src/src/mock/SvanV2.sol/contract.SwanV2.md index 0e27103..3ea008a 100644 --- a/docs/src/src/mock/SvanV2.sol/contract.SwanV2.md +++ b/docs/src/src/mock/SvanV2.sol/contract.SwanV2.md @@ -1,5 +1,5 @@ # SwanV2 -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/feb8dd64d672a341a29a0a52b12cc56adf09c996/src/mock/SvanV2.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/mock/SvanV2.sol) **Inherits:** [Swan](/src/Swan.sol/contract.Swan.md) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 0fd2e3d..4196a96 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -11,8 +11,8 @@ import {LLMOracleRegistry} from "@firstbatch/dria-oracle-contracts/LLMOracleRegi import { LLMOracleCoordinator, LLMOracleTaskParameters } from "@firstbatch/dria-oracle-contracts/LLMOracleCoordinator.sol"; -import {AIAgentFactory} from "../src/AIAgent.sol"; -import {ArtifactFactory} from "../src/Artifact.sol"; +import {SwanAgentFactory} from "../src/SwanAgent.sol"; +import {SwanArtifactFactory} from "../src/SwanArtifact.sol"; import {Swan, SwanMarketParameters} from "../src/Swan.sol"; contract DeployLLMOracleRegistry is Script { diff --git a/script/HelperConfig.s.sol b/script/HelperConfig.s.sol index 5caec7b..bfef490 100644 --- a/script/HelperConfig.s.sol +++ b/script/HelperConfig.s.sol @@ -9,10 +9,10 @@ import {LLMOracleTaskParameters} from "@firstbatch/dria-oracle-contracts/LLMOrac import {SwanMarketParameters} from "../src/SwanManager.sol"; import {LLMOracleCoordinator} from "@firstbatch/dria-oracle-contracts/LLMOracleCoordinator.sol"; import {LLMOracleRegistry} from "@firstbatch/dria-oracle-contracts/LLMOracleRegistry.sol"; -import {AIAgentFactory} from "../src/AIAgent.sol"; -import {ArtifactFactory} from "../src/Artifact.sol"; +import {SwanAgentFactory} from "../src/SwanAgent.sol"; +import {SwanArtifactFactory} from "../src/SwanArtifact.sol"; import {Swan} from "../src/Swan.sol"; -import {WETH9} from "../test/WETH9.sol"; +import {WETH9} from "../test/contracts/WETH9.sol"; struct Stakes { uint256 generatorStakeAmount; @@ -125,20 +125,20 @@ contract HelperConfig is Script { function deployAgentFactory() external returns (address) { vm.startBroadcast(); - AIAgentFactory agentFactory = new AIAgentFactory(); + SwanAgentFactory agentFactory = new SwanAgentFactory(); vm.stopBroadcast(); - writeContractAddress("AIAgentFactory", address(agentFactory)); + writeContractAddress("SwanAgentFactory", address(agentFactory)); return address(agentFactory); } function deployArtifactFactory() external returns (address) { vm.startBroadcast(); - ArtifactFactory artifactFactory = new ArtifactFactory(); + SwanArtifactFactory artifactFactory = new SwanArtifactFactory(); vm.stopBroadcast(); - writeContractAddress("ArtifactFactory", address(artifactFactory)); + writeContractAddress("SwanArtifactFactory", address(artifactFactory)); return address(artifactFactory); } @@ -152,17 +152,17 @@ contract HelperConfig is Script { string memory contractAddresses = vm.readFile(path); bool isCoordinatorExist = vm.keyExistsJson(contractAddresses, "$.LLMOracleCoordinator"); - bool isAgentFactoryExist = vm.keyExistsJson(contractAddresses, "$.AIAgentFactory"); - bool isArtifactFactoryExist = vm.keyExistsJson(contractAddresses, "$.ArtifactFactory"); + bool isAgentFactoryExist = vm.keyExistsJson(contractAddresses, "$.SwanAgentFactory"); + bool isArtifactFactoryExist = vm.keyExistsJson(contractAddresses, "$.SwanArtifactFactory"); require( isCoordinatorExist && isAgentFactoryExist && isArtifactFactoryExist, - "Please deploy LLMOracleCoordinator, AIAgentFactory and ArtifactFactory first" + "Please deploy LLMOracleCoordinator, SwanAgentFactory and SwanArtifactFactory first" ); address coordinatorProxy = vm.parseJsonAddress(contractAddresses, "$.LLMOracleCoordinator.proxyAddr"); - address agentFactory = vm.parseJsonAddress(contractAddresses, "$.AIAgentFactory.addr"); - address artifactFactory = vm.parseJsonAddress(contractAddresses, "$.ArtifactFactory.addr"); + address agentFactory = vm.parseJsonAddress(contractAddresses, "$.SwanAgentFactory.addr"); + address artifactFactory = vm.parseJsonAddress(contractAddresses, "$.SwanArtifactFactory.addr"); vm.startBroadcast(); // deploy swan diff --git a/src/Swan.sol b/src/Swan.sol index 31b3f37..f062a8e 100644 --- a/src/Swan.sol +++ b/src/Swan.sol @@ -7,16 +7,17 @@ import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeab import { LLMOracleCoordinator, LLMOracleTaskParameters } from "@firstbatch/dria-oracle-contracts/LLMOracleCoordinator.sol"; -import {AIAgentFactory, AIAgent} from "./AIAgent.sol"; -import {ArtifactFactory, Artifact} from "./Artifact.sol"; +import {SwanAgentFactory, SwanAgent} from "./SwanAgent.sol"; +import {SwanArtifactFactory, SwanArtifact} from "./SwanArtifact.sol"; import {SwanManager, SwanMarketParameters} from "./SwanManager.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; -// @dev Protocol strings for Swan, checked in the Oracle. -bytes32 constant SwanAIAgentPurchaseOracleProtocol = "swan-agent-purchase/0.1.0"; -bytes32 constant SwanAIAgentStateOracleProtocol = "swan-agent-state/0.1.0"; +/// @dev Protocol string for Swan Purchase CRONs, checked in the Oracle. +bytes32 constant SwanAgentPurchaseOracleProtocol = "swan-agent-purchase/0.1.0"; +/// @dev Protocol string for Swan State CRONs, checked in the Oracle. +bytes32 constant SwanAgentStateOracleProtocol = "swan-agent-state/0.1.0"; -/// @dev Used to calculate the fee for the AI agent to be able to compute correct amount. +/// @dev Used to calculate the fee for the agent to be able to compute correct amount. uint256 constant BASIS_POINTS = 10_000; contract Swan is SwanManager, UUPSUpgradeable { @@ -56,10 +57,10 @@ contract Swan is SwanManager, UUPSUpgradeable { /// @notice An `agent` purchased an artifact. event ArtifactSold(address indexed owner, address indexed agent, address indexed artifact, uint256 price); - /// @notice A new AI agent is created. - /// @dev `owner` is the owner of the AI agent. - /// @dev `agent` is the address of the AI agent. - event AIAgentCreated(address indexed owner, address indexed agent); + /// @notice A new agent is created. + /// @dev `owner` is the owner of the agent. + /// @dev `agent` is the address of the agent. + event AgentCreated(address indexed owner, address indexed agent); /*////////////////////////////////////////////////////////////// STORAGE @@ -80,10 +81,10 @@ contract Swan is SwanManager, UUPSUpgradeable { /// @notice Holds the listing information. /// @dev `createdAt` is the timestamp of the artifact creation. - /// @dev `feeRoyalty` is the royalty fee of the AIAgent. + /// @dev `feeRoyalty` is the royalty fee of the agent. /// @dev `price` is the price of the artifact. /// @dev `seller` is the address of the creator of the artifact. - /// @dev `agent` is the address of the AIAgent. + /// @dev `agent` is the address of the agent. /// @dev `round` is the round in which the artifact is created. /// @dev `status` is the status of the artifact. struct ArtifactListing { @@ -96,10 +97,10 @@ contract Swan is SwanManager, UUPSUpgradeable { ArtifactStatus status; } - /// @notice Factory contract to deploy AI Agents. - AIAgentFactory public agentFactory; + /// @notice Factory contract to deploy Agents. + SwanAgentFactory public agentFactory; /// @notice Factory contract to deploy Artifact tokens. - ArtifactFactory public artifactFactory; + SwanArtifactFactory public artifactFactory; /// @notice To keep track of the artifacts for purchase. mapping(address artifact => ArtifactListing) public listings; @@ -149,8 +150,8 @@ contract Swan is SwanManager, UUPSUpgradeable { // contracts coordinator = LLMOracleCoordinator(_coordinator); token = ERC20(_token); - agentFactory = AIAgentFactory(_agentFactory); - artifactFactory = ArtifactFactory(_artifactFactory); + agentFactory = SwanAgentFactory(_agentFactory); + artifactFactory = SwanArtifactFactory(_artifactFactory); // swan is an operator isOperator[address(this)] = true; @@ -179,17 +180,17 @@ contract Swan is SwanManager, UUPSUpgradeable { LOGIC //////////////////////////////////////////////////////////////*/ - /// @notice Creates a new AI agent. + /// @notice Creates a new agent. /// @dev Emits a `AIAgentCreated` event. - /// @return address of the new AI agent. + /// @return address of the new agent. function createAgent( string calldata _name, string calldata _description, uint96 _feeRoyalty, uint256 _amountPerRound - ) external returns (AIAgent) { - AIAgent agent = agentFactory.deploy(_name, _description, _feeRoyalty, _amountPerRound, msg.sender); - emit AIAgentCreated(msg.sender, address(agent)); + ) external returns (SwanAgent) { + SwanAgent agent = agentFactory.deploy(_name, _description, _feeRoyalty, _amountPerRound, msg.sender); + emit AgentCreated(msg.sender, address(agent)); return agent; } @@ -203,12 +204,12 @@ contract Swan is SwanManager, UUPSUpgradeable { function list(string calldata _name, string calldata _symbol, bytes calldata _desc, uint256 _price, address _agent) external { - AIAgent agent = AIAgent(_agent); - (uint256 round, AIAgent.Phase phase,) = agent.getRoundPhase(); + SwanAgent agent = SwanAgent(_agent); + (uint256 round, SwanAgent.Phase phase,) = agent.getRoundPhase(); // agent must be in the listing phase - if (phase != AIAgent.Phase.Listing) { - revert AIAgent.InvalidPhase(phase, AIAgent.Phase.Listing); + if (phase != SwanAgent.Phase.Listing) { + revert SwanAgent.InvalidPhase(phase, SwanAgent.Phase.Listing); } // artifact count must not exceed `maxArtifactCount` if (getCurrentMarketParameters().maxArtifactCount == artifactsPerAgentRound[_agent][round].length) { @@ -242,7 +243,7 @@ contract Swan is SwanManager, UUPSUpgradeable { /// @notice Relist the artifact for another round and/or another agent and/or another price. /// @param _artifact address of the artifact. - /// @param _agent new AIAgent for the artifact. + /// @param _agent new agent for the artifact. /// @param _price new price of the token. function relist(address _artifact, address _agent, uint256 _price) external { ArtifactListing storage artifact = listings[_artifact]; @@ -264,23 +265,23 @@ contract Swan is SwanManager, UUPSUpgradeable { // // perhaps it suffices to check `==` here, since agent round // is changed incrementially - (uint256 oldRound,,) = AIAgent(artifact.agent).getRoundPhase(); + (uint256 oldRound,,) = SwanAgent(artifact.agent).getRoundPhase(); if (oldRound <= artifact.round) { revert RoundNotFinished(_artifact, artifact.round); } // check the artifact price is within the acceptable range - if (_price < getCurrentMarketParameters().minArtifactPrice || _price >= AIAgent(_agent).amountPerRound()) { + if (_price < getCurrentMarketParameters().minArtifactPrice || _price >= SwanAgent(_agent).amountPerRound()) { revert InvalidPrice(_price); } // now we move on to the new agent - AIAgent agent = AIAgent(_agent); - (uint256 round, AIAgent.Phase phase,) = agent.getRoundPhase(); + SwanAgent agent = SwanAgent(_agent); + (uint256 round, SwanAgent.Phase phase,) = agent.getRoundPhase(); // agent must be in listing phase - if (phase != AIAgent.Phase.Listing) { - revert AIAgent.InvalidPhase(phase, AIAgent.Phase.Listing); + if (phase != SwanAgent.Phase.Listing) { + revert SwanAgent.InvalidPhase(phase, SwanAgent.Phase.Listing); } // agent must not have more than `maxArtifactCount` many artifacts @@ -347,8 +348,8 @@ contract Swan is SwanManager, UUPSUpgradeable { // transfer artifact from seller to Swan, and then from Swan to agent // this ensure that only approval to Swan is enough for the sellers - Artifact(_artifact).transferFrom(listing.seller, address(this), 1); - Artifact(_artifact).transferFrom(address(this), listing.agent, 1); + SwanArtifact(_artifact).transferFrom(listing.seller, address(this), 1); + SwanArtifact(_artifact).transferFrom(address(this), listing.agent, 1); // transfer money token.transferFrom(listing.agent, address(this), listing.price); @@ -362,8 +363,8 @@ contract Swan is SwanManager, UUPSUpgradeable { /// @param _agentFactory new AIAgentFactory address /// @param _artifactFactory new ArtifactFactory address function setFactories(address _agentFactory, address _artifactFactory) external onlyOwner { - agentFactory = AIAgentFactory(_agentFactory); - artifactFactory = ArtifactFactory(_artifactFactory); + agentFactory = SwanAgentFactory(_agentFactory); + artifactFactory = SwanArtifactFactory(_artifactFactory); } /// @notice Returns the artifact price with the given artifact address. diff --git a/src/AIAgent.sol b/src/SwanAgent.sol similarity index 95% rename from src/AIAgent.sol rename to src/SwanAgent.sol index ae39c84..964ffac 100644 --- a/src/AIAgent.sol +++ b/src/SwanAgent.sol @@ -3,25 +3,25 @@ pragma solidity ^0.8.20; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {LLMOracleTaskParameters} from "@firstbatch/dria-oracle-contracts/LLMOracleTask.sol"; -import {Swan, SwanAIAgentPurchaseOracleProtocol, SwanAIAgentStateOracleProtocol} from "./Swan.sol"; +import {Swan, SwanAgentPurchaseOracleProtocol, SwanAgentStateOracleProtocol} from "./Swan.sol"; import {SwanMarketParameters} from "./SwanManager.sol"; -/// @notice Factory contract to deploy AIAgent contracts. +/// @notice Factory contract to deploy Agent contracts. /// @dev This saves from contract space for Swan. -contract AIAgentFactory { +contract SwanAgentFactory { function deploy( string memory _name, string memory _description, uint96 _feeRoyalty, uint256 _amountPerRound, address _owner - ) external returns (AIAgent) { - return new AIAgent(_name, _description, _feeRoyalty, _amountPerRound, msg.sender, _owner); + ) external returns (SwanAgent) { + return new SwanAgent(_name, _description, _feeRoyalty, _amountPerRound, msg.sender, _owner); } } /// @notice AIAgent is responsible for buying the artifacts from Swan. -contract AIAgent is Ownable { +contract SwanAgent is Ownable { /*////////////////////////////////////////////////////////////// ERRORS //////////////////////////////////////////////////////////////*/ @@ -83,19 +83,19 @@ contract AIAgent is Ownable { /// @dev When calculating the round, we will use this index to determine the start interval. uint256 public immutable marketParameterIdx; - /// @notice AI agent name. + /// @notice Agent name. string public name; - /// @notice AI agent description, can include backstory, behavior and objective together. + /// @notice Agent description, can include backstory, behavior and objective together. string public description; - /// @notice State of the AI agent. + /// @notice State of the agent. /// @dev Only updated by the oracle via `updateState`. bytes public state; - /// @notice Royalty fees for the AI agent. + /// @notice Royalty fees for the agent. uint96 public feeRoyalty; /// @notice The max amount of money the agent can spend per round. uint256 public amountPerRound; - /// @notice The artifacts that the AI agent has. + /// @notice The artifacts that the agent has. mapping(uint256 round => address[] artifacts) public inventory; /// @notice Amount of money spent on each round. mapping(uint256 round => uint256 spending) public spendings; @@ -130,7 +130,7 @@ contract AIAgent is Ownable { CONSTRUCTOR //////////////////////////////////////////////////////////////*/ - /// @notice Creates AI agent. + /// @notice Creates an agent. /// @dev `_feeRoyalty` should be between 1 and maxAIAgentFee in the swan market parameters. /// @dev All tokens are approved to the oracle coordinator of operator. constructor( @@ -193,7 +193,7 @@ contract AIAgent is Ownable { (uint256 round,) = _checkRoundPhase(Phase.Withdraw); oracleStateRequests[round] = - swan.coordinator().request(SwanAIAgentStateOracleProtocol, _input, _models, swan.getOracleParameters()); + swan.coordinator().request(SwanAgentStateOracleProtocol, _input, _models, swan.getOracleParameters()); emit StateRequest(oracleStateRequests[round], round); } @@ -210,7 +210,7 @@ contract AIAgent is Ownable { (uint256 round,) = _checkRoundPhase(Phase.Buy); oraclePurchaseRequests[round] = - swan.coordinator().request(SwanAIAgentPurchaseOracleProtocol, _input, _models, swan.getOracleParameters()); + swan.coordinator().request(SwanAgentPurchaseOracleProtocol, _input, _models, swan.getOracleParameters()); emit PurchaseRequest(oraclePurchaseRequests[round], round); } diff --git a/src/Artifact.sol b/src/SwanArtifact.sol similarity index 87% rename from src/Artifact.sol rename to src/SwanArtifact.sol index 597e504..d09b92c 100644 --- a/src/Artifact.sol +++ b/src/SwanArtifact.sol @@ -6,18 +6,18 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; /// @notice Factory contract to deploy Artifact tokens. /// @dev This saves from contract space for Swan. -contract ArtifactFactory { +contract SwanArtifactFactory { /// @notice Deploys a new Artifact token. function deploy(string memory _name, string memory _symbol, bytes memory _description, address _owner) external - returns (Artifact) + returns (SwanArtifact) { - return new Artifact(_name, _symbol, _description, _owner, msg.sender); + return new SwanArtifact(_name, _symbol, _description, _owner, msg.sender); } } /// @notice Artifact is an ERC721 token with a single token supply. -contract Artifact is ERC721, Ownable { +contract SwanArtifact is ERC721, Ownable { /// @notice Creation time of the token uint256 public createdAt; /// @notice Description of the token diff --git a/src/SwanManager.sol b/src/SwanManager.sol index b6abf5d..29443ae 100644 --- a/src/SwanManager.sol +++ b/src/SwanManager.sol @@ -11,9 +11,8 @@ import { /// @notice Collection of market-related parameters. /// @dev Prevents stack-too-deep. -/// TODO: use 256-bit tight-packing here struct SwanMarketParameters { - /// @notice The interval at which the AIAgent can withdraw the funds. + /// @notice The interval at which the agent can withdraw the funds. uint256 withdrawInterval; /// @notice The interval at which the creators can mint artifacts. uint256 listingInterval; diff --git a/test/Helper.t.sol b/test/Helper.t.sol index 7f853ad..71d5698 100644 --- a/test/Helper.t.sol +++ b/test/Helper.t.sol @@ -5,13 +5,13 @@ import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; import {Vm} from "forge-std/Vm.sol"; import {Test} from "forge-std/Test.sol"; -import {WETH9} from "./WETH9.sol"; +import {WETH9} from "./contracts/WETH9.sol"; import {LLMOracleRegistry, LLMOracleKind} from "@firstbatch/dria-oracle-contracts/LLMOracleRegistry.sol"; import {LLMOracleCoordinator} from "@firstbatch/dria-oracle-contracts/LLMOracleCoordinator.sol"; import {SwanMarketParameters} from "../src/SwanManager.sol"; import {LLMOracleTaskParameters} from "@firstbatch/dria-oracle-contracts/LLMOracleTask.sol"; -import {AIAgent, AIAgentFactory} from "../src/AIAgent.sol"; -import {ArtifactFactory} from "../src/Artifact.sol"; +import {SwanAgent, SwanAgentFactory} from "../src/SwanAgent.sol"; +import {SwanArtifactFactory} from "../src/SwanArtifact.sol"; import {Swan} from "../src/Swan.sol"; import {Stakes, Fees} from "../script/HelperConfig.s.sol"; @@ -38,7 +38,7 @@ abstract contract Helper is Test { address[] validators; uint256 currRound; - AIAgent.Phase currPhase; + SwanAgent.Phase currPhase; AgentParameters[] agentParameters; LLMOracleTaskParameters oracleParameters; @@ -47,11 +47,11 @@ abstract contract Helper is Test { LLMOracleCoordinator oracleCoordinator; LLMOracleRegistry oracleRegistry; - AIAgentFactory agentFactory; - ArtifactFactory artifactFactory; - AIAgent[] agents; + SwanAgentFactory agentFactory; + SwanArtifactFactory artifactFactory; + SwanAgent[] agents; - AIAgent agent; + SwanAgent agent; address agentOwner; WETH9 token; @@ -159,8 +159,8 @@ abstract contract Helper is Test { oracleCoordinator = LLMOracleCoordinator(coordinatorProxy); // deploy factory contracts - agentFactory = new AIAgentFactory(); - artifactFactory = new ArtifactFactory(); + agentFactory = new SwanAgentFactory(); + artifactFactory = new SwanArtifactFactory(); // deploy swan address swanProxy = Upgrades.deployUUPSProxy( @@ -184,8 +184,8 @@ abstract contract Helper is Test { vm.label(address(token), "WETH"); vm.label(address(oracleRegistry), "LLMOracleRegistry"); vm.label(address(oracleCoordinator), "LLMOracleCoordinator"); - vm.label(address(agentFactory), "AIAgentFactory"); - vm.label(address(artifactFactory), "ArtifactFactory"); + vm.label(address(agentFactory), "SwanAgentFactory"); + vm.label(address(artifactFactory), "SwanArtifactFactory"); } /// @notice Add validators to the whitelist. @@ -239,7 +239,7 @@ abstract contract Helper is Test { vm.recordLogs(); vm.startPrank(agentOwners[i]); - AIAgent AIagent = swan.createAgent( + SwanAgent AIagent = swan.createAgent( agentParameters[i].name, agentParameters[i].description, agentParameters[i].feeRoyalty, @@ -285,7 +285,7 @@ abstract contract Helper is Test { assertEq(agentCreatedEvent.emitter, address(swan)); // all guuud - agents.push(AIAgent(_agent)); + agents.push(SwanAgent(_agent)); vm.label(address(agents[i]), string.concat("AIAgent#", vm.toString(i + 1))); @@ -296,7 +296,7 @@ abstract contract Helper is Test { } assertEq(agents.length, agentOwners.length); - currPhase = AIAgent.Phase.Listing; + currPhase = SwanAgent.Phase.Listing; agent = agents[0]; agentOwner = agentOwners[0]; @@ -319,7 +319,7 @@ abstract contract Helper is Test { /// @param artifactCount Number of artifacts that will be listed. /// @param _agent Agent that artifacts will be list for. modifier listArtifacts(address seller, uint256 artifactCount, address _agent) { - uint256 invalidPrice = AIAgent(_agent).amountPerRound(); + uint256 invalidPrice = SwanAgent(_agent).amountPerRound(); vm.expectRevert(abi.encodeWithSelector(Swan.InvalidPrice.selector, invalidPrice)); vm.prank(seller); @@ -409,6 +409,8 @@ abstract contract Helper is Test { return nonce; } } + + return 0; // should never reach here } /// @notice Makes a request to Oracle Coordinator @@ -446,13 +448,13 @@ abstract contract Helper is Test { //////////////////////////////////////////////////////////////*/ /// @notice Increases time in the test - function increaseTime(uint256 timeInseconds, AIAgent _agent, AIAgent.Phase expectedPhase, uint256 expectedRound) + function increaseTime(uint256 timeInseconds, SwanAgent _agent, SwanAgent.Phase expectedPhase, uint256 expectedRound) public { vm.warp(timeInseconds + 1); // get the current round and phase of agent - (uint256 _currRound, AIAgent.Phase _currPhase,) = _agent.getRoundPhase(); + (uint256 _currRound, SwanAgent.Phase _currPhase,) = _agent.getRoundPhase(); assertEq(uint8(_currPhase), uint8(expectedPhase)); assertEq(uint8(_currRound), uint8(expectedRound)); } @@ -477,7 +479,7 @@ abstract contract Helper is Test { } /// @notice Makes a purchase request to Oracle Coordinator - function safePurchase(address _agentOwner, AIAgent _agent, uint256 taskId) public { + function safePurchase(address _agentOwner, SwanAgent _agent, uint256 taskId) public { address[] memory listedArtifacts = swan.getListedArtifacts(address(_agent), currRound); // get the listed artifacts as output @@ -518,9 +520,9 @@ abstract contract Helper is Test { } /// @dev Checks if the round, phase and timeRemaining is correct - function checkRoundAndPhase(AIAgent _agent, AIAgent.Phase phase, uint256 round) public view returns (uint256) { + function checkRoundAndPhase(SwanAgent _agent, SwanAgent.Phase phase, uint256 round) public view returns (uint256) { // get the current round and phase of the agent - (uint256 _currRound, AIAgent.Phase _currPhase,) = _agent.getRoundPhase(); + (uint256 _currRound, SwanAgent.Phase _currPhase,) = _agent.getRoundPhase(); assertEq(uint8(_currPhase), uint8(phase)); assertEq(uint8(_currRound), uint8(round)); diff --git a/test/AIAgentTest.t.sol b/test/SwanAgentTest.t.sol similarity index 74% rename from test/AIAgentTest.t.sol rename to test/SwanAgentTest.t.sol index fd66ff9..859c06d 100644 --- a/test/AIAgentTest.t.sol +++ b/test/SwanAgentTest.t.sol @@ -5,19 +5,18 @@ import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; import {Vm} from "forge-std/Vm.sol"; import {Helper} from "./Helper.t.sol"; -import {WETH9} from "./WETH9.sol"; -import {AIAgent, AIAgentFactory} from "../src/AIAgent.sol"; +import {WETH9} from "./contracts/WETH9.sol"; +import {SwanAgent} from "../src/SwanAgent.sol"; import {LLMOracleCoordinator} from "@firstbatch/dria-oracle-contracts/LLMOracleCoordinator.sol"; -import {ArtifactFactory} from "../src/Artifact.sol"; import {LLMOracleTaskParameters} from "@firstbatch/dria-oracle-contracts/LLMOracleTask.sol"; import {LLMOracleRegistry} from "@firstbatch/dria-oracle-contracts/LLMOracleRegistry.sol"; import {Swan} from "../src/Swan.sol"; -contract AIAgentTest is Helper { - /// @notice AI agent should be in Listing Phase +contract SwanAgentTest is Helper { + /// @notice Agent should be in Listing Phase function test_InListingPhase() external createAgents { // get curr phase - (, AIAgent.Phase _phase,) = agent.getRoundPhase(); + (, SwanAgent.Phase _phase,) = agent.getRoundPhase(); assertEq(uint8(_phase), uint8(currPhase)); } @@ -25,7 +24,7 @@ contract AIAgentTest is Helper { function test_RevertWhen_SetRoyaltyInListingPhase() external createAgents { vm.prank(agentOwner); vm.expectRevert( - abi.encodeWithSelector(AIAgent.InvalidPhase.selector, AIAgent.Phase.Listing, AIAgent.Phase.Withdraw) + abi.encodeWithSelector(SwanAgent.InvalidPhase.selector, SwanAgent.Phase.Listing, SwanAgent.Phase.Withdraw) ); agent.setFeeRoyalty(10); } @@ -33,21 +32,21 @@ contract AIAgentTest is Helper { /// @notice Test that the agent is in Buy Phase function test_InBuyPhase() external createAgents { uint256 _timeToBuyPhaseOfTheFirstRound = agent.createdAt() + swan.getCurrentMarketParameters().listingInterval; - increaseTime(_timeToBuyPhaseOfTheFirstRound, agent, AIAgent.Phase.Buy, 0); + increaseTime(_timeToBuyPhaseOfTheFirstRound, agent, SwanAgent.Phase.Buy, 0); - currPhase = AIAgent.Phase.Buy; + currPhase = SwanAgent.Phase.Buy; - (, AIAgent.Phase _phase,) = agent.getRoundPhase(); + (, SwanAgent.Phase _phase,) = agent.getRoundPhase(); assertEq(uint8(_phase), uint8(currPhase)); } /// @dev Agent owner cannot set amountPerRound in Buy Phase function test_RevertWhen_SetAmountPerRoundInBuyPhase() external createAgents { - increaseTime(agent.createdAt() + marketParameters.listingInterval, agent, AIAgent.Phase.Buy, 0); + increaseTime(agent.createdAt() + marketParameters.listingInterval, agent, SwanAgent.Phase.Buy, 0); vm.prank(agentOwner); vm.expectRevert( - abi.encodeWithSelector(AIAgent.InvalidPhase.selector, AIAgent.Phase.Buy, AIAgent.Phase.Withdraw) + abi.encodeWithSelector(SwanAgent.InvalidPhase.selector, SwanAgent.Phase.Buy, SwanAgent.Phase.Withdraw) ); agent.setAmountPerRound(2 ether); } @@ -55,14 +54,14 @@ contract AIAgentTest is Helper { /// @notice Test that the agent owner cannot withdraw in Buy Phase function test_RevertWhen_WithdrawInBuyPhase() external createAgents { // owner cannot withdraw more than minFundAmount from his agent - increaseTime(agent.createdAt() + marketParameters.listingInterval, agent, AIAgent.Phase.Buy, 0); + increaseTime(agent.createdAt() + marketParameters.listingInterval, agent, SwanAgent.Phase.Buy, 0); // get the contract balance uint256 treasuary = agent.treasury(); vm.prank(agentOwner); // try to withdraw all balance - vm.expectRevert(abi.encodeWithSelector(AIAgent.MinFundSubceeded.selector, treasuary)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.MinFundSubceeded.selector, treasuary)); agent.withdraw(uint96(treasuary)); } @@ -71,15 +70,15 @@ contract AIAgentTest is Helper { increaseTime( agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); - currPhase = AIAgent.Phase.Withdraw; + currPhase = SwanAgent.Phase.Withdraw; // not allowed to withdraw by non owner vm.prank(agentOwners[1]); - vm.expectRevert(abi.encodeWithSelector(AIAgent.Unauthorized.selector, agentOwners[1])); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.Unauthorized.selector, agentOwners[1])); agent.withdraw(1 ether); } @@ -89,7 +88,7 @@ contract AIAgentTest is Helper { increaseTime( agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); @@ -97,10 +96,10 @@ contract AIAgentTest is Helper { uint96 _smallerRoyalty = 0; vm.startPrank(agentOwner); - vm.expectRevert(abi.encodeWithSelector(AIAgent.InvalidFee.selector, _biggerRoyalty)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.InvalidFee.selector, _biggerRoyalty)); agent.setFeeRoyalty(_biggerRoyalty); - vm.expectRevert(abi.encodeWithSelector(AIAgent.InvalidFee.selector, _smallerRoyalty)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.InvalidFee.selector, _smallerRoyalty)); agent.setFeeRoyalty(_smallerRoyalty); vm.stopPrank(); } @@ -110,7 +109,7 @@ contract AIAgentTest is Helper { increaseTime( agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); @@ -126,12 +125,12 @@ contract AIAgentTest is Helper { assertEq(agent.amountPerRound(), _newAmountPerRound); } - /// @notice Test that the AI agent owner can withdraw in Withdraw Phase + /// @notice Test that the agent owner can withdraw in Withdraw Phase function test_WithdrawInWithdrawPhase() external createAgents { increaseTime( agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); diff --git a/test/SwanFuzzTest.t.sol b/test/SwanFuzzTest.t.sol index 5875569..528cd0e 100644 --- a/test/SwanFuzzTest.t.sol +++ b/test/SwanFuzzTest.t.sol @@ -5,10 +5,10 @@ import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; import {Vm} from "forge-std/Vm.sol"; import {Helper} from "./Helper.t.sol"; -import {AIAgent, AIAgentFactory} from "../src/AIAgent.sol"; -import {ArtifactFactory, Artifact} from "../src/Artifact.sol"; +import {SwanAgent, SwanAgentFactory} from "../src/SwanAgent.sol"; +import {SwanArtifactFactory} from "../src/SwanArtifact.sol"; import {Swan, SwanMarketParameters} from "../src/Swan.sol"; -import {WETH9} from "./WETH9.sol"; +import {WETH9} from "./contracts/WETH9.sol"; import {LLMOracleRegistry} from "@firstbatch/dria-oracle-contracts/LLMOracleRegistry.sol"; import { LLMOracleCoordinator, LLMOracleTaskParameters @@ -97,7 +97,7 @@ contract SwanFuzzTest is Helper { // increase time to buy phase of the second round increaseTime( - agents[0].createdAt() + swan.getCurrentMarketParameters().listingInterval, agents[0], AIAgent.Phase.Buy, 0 + agents[0].createdAt() + swan.getCurrentMarketParameters().listingInterval, agents[0], SwanAgent.Phase.Buy, 0 ); // change cycle time @@ -117,10 +117,10 @@ contract SwanFuzzTest is Helper { // get all params SwanMarketParameters[] memory _allParams = swan.getMarketParameters(); assertEq(_allParams.length, 2); - (uint256 _currRound, AIAgent.Phase _phase,) = agents[0].getRoundPhase(); + (uint256 _currRound, SwanAgent.Phase _phase,) = agents[0].getRoundPhase(); assertEq(_currRound, 1); - assertEq(uint8(_phase), uint8(AIAgent.Phase.Listing)); + assertEq(uint8(_phase), uint8(SwanAgent.Phase.Listing)); uint256 _currTimestamp = block.timestamp; @@ -130,13 +130,13 @@ contract SwanFuzzTest is Helper { _currTimestamp + (2 * swan.getCurrentMarketParameters().listingInterval) + swan.getCurrentMarketParameters().buyInterval + swan.getCurrentMarketParameters().withdrawInterval, agents[0], - AIAgent.Phase.Buy, + SwanAgent.Phase.Buy, 2 ); - // deploy new AI agent + // deploy new agent vm.prank(agentOwners[0]); - AIAgent _agentAfterFirstSet = swan.createAgent( + SwanAgent _agentAfterFirstSet = swan.createAgent( agentParameters[1].name, agentParameters[1].description, agentParameters[1].feeRoyalty, @@ -144,7 +144,7 @@ contract SwanFuzzTest is Helper { ); // _agentAfterFirstSet should be in listing phase of the first round - checkRoundAndPhase(_agentAfterFirstSet, AIAgent.Phase.Listing, 0); + checkRoundAndPhase(_agentAfterFirstSet, SwanAgent.Phase.Listing, 0); // change cycle time setMarketParameters( @@ -165,10 +165,10 @@ contract SwanFuzzTest is Helper { assertEq(_allParams.length, 3); // AIAgents[0] should be in listing phase of the fourth round (2 more increase time + 2 for setting new params) - checkRoundAndPhase(agents[0], AIAgent.Phase.Listing, 3); + checkRoundAndPhase(agents[0], SwanAgent.Phase.Listing, 3); // agentAfterFirstSet should be in listing phase of the second round - checkRoundAndPhase(_agentAfterFirstSet, AIAgent.Phase.Listing, 1); + checkRoundAndPhase(_agentAfterFirstSet, SwanAgent.Phase.Listing, 1); } function testFuzz_TransferOwnership(address _newOwner) public { @@ -202,7 +202,7 @@ contract SwanFuzzTest is Helper { // Create a AI agent vm.prank(agentOwners[0]); - AIAgent _agent = swan.createAgent(_agentName, _agentDesc, _agentFee, _amountPerRound); + SwanAgent _agent = swan.createAgent(_agentName, _agentDesc, _agentFee, _amountPerRound); // List the artifact vm.prank(sellers[0]); diff --git a/test/SwanIntervalsTest.t.sol b/test/SwanIntervalsTest.t.sol index 303bab0..a37a796 100644 --- a/test/SwanIntervalsTest.t.sol +++ b/test/SwanIntervalsTest.t.sol @@ -6,10 +6,10 @@ import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; import {Helper} from "./Helper.t.sol"; import {console} from "forge-std/Test.sol"; -import {AIAgent, AIAgentFactory} from "../src/AIAgent.sol"; -import {ArtifactFactory, Artifact} from "../src/Artifact.sol"; +import {SwanAgent} from "../src/SwanAgent.sol"; +import {SwanArtifactFactory} from "../src/SwanArtifact.sol"; import {Swan, SwanMarketParameters} from "../src/Swan.sol"; -import {WETH9} from "./WETH9.sol"; +import {WETH9} from "./contracts/WETH9.sol"; import {LLMOracleRegistry} from "@firstbatch/dria-oracle-contracts/LLMOracleRegistry.sol"; import { LLMOracleCoordinator, LLMOracleTaskParameters @@ -19,28 +19,28 @@ contract SwanIntervalsTest is Helper { /// @notice Check the current phase is listing right after creation of buyer agent function test_InListingPhase() external createAgents { // agent should be in listing phase right after creation - checkRoundAndPhase(agents[0], AIAgent.Phase.Listing, 0); + checkRoundAndPhase(agents[0], SwanAgent.Phase.Listing, 0); } /// @notice Check the current phase is Buy after increase time to buy phase function test_InBuyPhase() external createAgents { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; increaseTime( - _agent.createdAt() + swan.getCurrentMarketParameters().listingInterval, _agent, AIAgent.Phase.Buy, 0 + _agent.createdAt() + swan.getCurrentMarketParameters().listingInterval, _agent, SwanAgent.Phase.Buy, 0 ); - checkRoundAndPhase(_agent, AIAgent.Phase.Buy, 0); + checkRoundAndPhase(_agent, SwanAgent.Phase.Buy, 0); } /// @notice Check the current phase is Withdraw after increase time to withdraw phase function test_InWithdrawPhase() external createAgents { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; increaseTime( _agent.createdAt() + swan.getCurrentMarketParameters().listingInterval + swan.getCurrentMarketParameters().buyInterval, _agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); - checkRoundAndPhase(_agent, AIAgent.Phase.Withdraw, 0); + checkRoundAndPhase(_agent, SwanAgent.Phase.Withdraw, 0); } } diff --git a/test/SwanTest.t.sol b/test/SwanTest.t.sol index 45a1d56..4d0995a 100644 --- a/test/SwanTest.t.sol +++ b/test/SwanTest.t.sol @@ -5,11 +5,11 @@ import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; import {Vm} from "forge-std/Vm.sol"; import {Helper} from "./Helper.t.sol"; -import {AIAgent, AIAgentFactory} from "../src/AIAgent.sol"; -import {ArtifactFactory, Artifact} from "../src/Artifact.sol"; +import {SwanAgent, SwanAgentFactory} from "../src/SwanAgent.sol"; +import {SwanArtifactFactory, SwanArtifact} from "../src/SwanArtifact.sol"; import {Swan, SwanMarketParameters} from "../src/Swan.sol"; import {LLMOracleRegistry} from "@firstbatch/dria-oracle-contracts/LLMOracleRegistry.sol"; -import {WETH9} from "./WETH9.sol"; +import {WETH9} from "./contracts/WETH9.sol"; import { LLMOracleCoordinator, LLMOracleTaskParameters } from "@firstbatch/dria-oracle-contracts/LLMOracleCoordinator.sol"; @@ -96,7 +96,9 @@ contract SwanTest is Helper { { // try to purchase in Listing Phase vm.prank(agentOwners[0]); - vm.expectRevert(abi.encodeWithSelector(AIAgent.InvalidPhase.selector, AIAgent.Phase.Listing, AIAgent.Phase.Buy)); + vm.expectRevert( + abi.encodeWithSelector(SwanAgent.InvalidPhase.selector, SwanAgent.Phase.Listing, SwanAgent.Phase.Buy) + ); agents[0].purchase(); } @@ -129,10 +131,10 @@ contract SwanTest is Helper { listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { address _agentToFail = agentOwners[0]; - AIAgent _agent = agents[1]; + SwanAgent _agent = agents[1]; - increaseTime(_agent.createdAt() + marketParameters.listingInterval, _agent, AIAgent.Phase.Buy, 0); - currPhase = AIAgent.Phase.Buy; + increaseTime(_agent.createdAt() + marketParameters.listingInterval, _agent, SwanAgent.Phase.Buy, 0); + currPhase = SwanAgent.Phase.Buy; vm.expectRevert(abi.encodeWithSelector(Swan.Unauthorized.selector, _agentToFail)); vm.prank(_agentToFail); @@ -150,9 +152,9 @@ contract SwanTest is Helper { listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { address _agentOwnerToFail = agentOwners[0]; - AIAgent _agentToFail = agents[0]; + SwanAgent _agentToFail = agents[0]; - increaseTime(_agentToFail.createdAt() + marketParameters.listingInterval, _agentToFail, AIAgent.Phase.Buy, 0); + increaseTime(_agentToFail.createdAt() + marketParameters.listingInterval, _agentToFail, SwanAgent.Phase.Buy, 0); // get the listed artifacts as output address[] memory output = swan.getListedArtifacts(address(_agentToFail), currRound); @@ -170,7 +172,7 @@ contract SwanTest is Helper { safeValidate(validators[0], 1); vm.prank(_agentOwnerToFail); - vm.expectRevert(abi.encodeWithSelector(AIAgent.BuyLimitExceeded.selector, artifactPrice * 2, amountPerRound)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.BuyLimitExceeded.selector, artifactPrice * 2, amountPerRound)); _agentToFail.purchase(); } @@ -189,7 +191,7 @@ contract SwanTest is Helper { listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { // increase time to buy phase to be able to purchase - increaseTime(agents[0].createdAt() + marketParameters.listingInterval, agents[0], AIAgent.Phase.Buy, 0); + increaseTime(agents[0].createdAt() + marketParameters.listingInterval, agents[0], SwanAgent.Phase.Buy, 0); safePurchase(agentOwners[0], agents[0], 1); Vm.Log[] memory entries = vm.getRecordedLogs(); @@ -199,7 +201,7 @@ contract SwanTest is Helper { // 3. Transfer // 4. Transfer // 5. ArtifactSold (from Swan) - // 6. Purchase (from AIAgent) + // 6. Purchase (from SwanAgent) assertEq(entries.length, 6); // get the ArtifactSold event @@ -233,7 +235,7 @@ contract SwanTest is Helper { // try to purchase again vm.prank(agentOwners[0]); - vm.expectRevert(abi.encodeWithSelector(AIAgent.TaskAlreadyProcessed.selector)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.TaskAlreadyProcessed.selector)); agents[0].purchase(); } @@ -248,25 +250,25 @@ contract SwanTest is Helper { listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { address _agentOwner = agentOwners[0]; - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; bytes memory newState = abi.encodePacked("0x", "after purchase"); uint256 taskId = 1; - increaseTime(_agent.createdAt() + marketParameters.listingInterval, _agent, AIAgent.Phase.Buy, 0); + increaseTime(_agent.createdAt() + marketParameters.listingInterval, _agent, SwanAgent.Phase.Buy, 0); safePurchase(_agentOwner, _agent, taskId); taskId++; increaseTime( _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, _agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); // try to send state request by another agent owner vm.prank(agentOwners[1]); - vm.expectRevert(abi.encodeWithSelector(AIAgent.Unauthorized.selector, agentOwners[1])); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.Unauthorized.selector, agentOwners[1])); _agent.oracleStateRequest(input, models); vm.prank(_agentOwner); @@ -279,7 +281,7 @@ contract SwanTest is Helper { // try to update state by another agent owner vm.prank(agentOwners[1]); - vm.expectRevert(abi.encodeWithSelector(AIAgent.Unauthorized.selector, agentOwners[1])); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.Unauthorized.selector, agentOwners[1])); _agent.updateState(); vm.prank(_agentOwner); @@ -289,32 +291,32 @@ contract SwanTest is Helper { /// @notice Seller cannot list an artifact in withdraw phase function test_RevertWhen_ListInWithdrawPhase() external fund createAgents sellersApproveToSwan { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; increaseTime( _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, _agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); - currPhase = AIAgent.Phase.Withdraw; + currPhase = SwanAgent.Phase.Withdraw; - checkRoundAndPhase(_agent, AIAgent.Phase.Withdraw, 0); + checkRoundAndPhase(_agent, SwanAgent.Phase.Withdraw, 0); vm.prank(sellers[0]); - vm.expectRevert(abi.encodeWithSelector(AIAgent.InvalidPhase.selector, currPhase, AIAgent.Phase.Listing)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.InvalidPhase.selector, currPhase, SwanAgent.Phase.Listing)); swan.list("name", "symbol", "desc", 0.01 ether, address(_agent)); } /// @notice Agent Owner can setAmountPerRound in withdraw phase function test_SetAmountPerRound() external fund createAgents sellersApproveToSwan { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; uint256 _newAmountPerRound = 2 ether; increaseTime( _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, _agent, - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); @@ -329,7 +331,7 @@ contract SwanTest is Helper { uint96 _invalidRoyalty = 150; vm.prank(agentOwners[0]); - vm.expectRevert(abi.encodeWithSelector(AIAgent.InvalidFee.selector, _invalidRoyalty)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.InvalidFee.selector, _invalidRoyalty)); swan.createAgent( agentParameters[0].name, agentParameters[0].description, _invalidRoyalty, agentParameters[0].amountPerRound ); @@ -337,8 +339,8 @@ contract SwanTest is Helper { /// @notice Swan owner can set factories function test_SetFactories() external fund { - ArtifactFactory _artifactFactory = new ArtifactFactory(); - AIAgentFactory _agentFactory = new AIAgentFactory(); + SwanArtifactFactory _artifactFactory = new SwanArtifactFactory(); + SwanAgentFactory _agentFactory = new SwanAgentFactory(); vm.prank(dria); swan.setFactories(address(_agentFactory), address(_artifactFactory)); @@ -358,16 +360,16 @@ contract SwanTest is Helper { listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { address _agentOwner = agentOwners[0]; - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; uint256 taskId = 1; // increase time to buy phase - increaseTime(_agent.createdAt() + marketParameters.listingInterval, _agent, AIAgent.Phase.Buy, 0); + increaseTime(_agent.createdAt() + marketParameters.listingInterval, _agent, SwanAgent.Phase.Buy, 0); safePurchase(_agentOwner, _agent, taskId); uint256 listingPhaseOfTheSecondRound = _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval + marketParameters.withdrawInterval; - increaseTime(listingPhaseOfTheSecondRound, _agent, AIAgent.Phase.Listing, 1); + increaseTime(listingPhaseOfTheSecondRound, _agent, SwanAgent.Phase.Listing, 1); // get artifact address _listedArtifactAddr = swan.getListedArtifacts(address(_agent), currRound)[0]; @@ -393,14 +395,14 @@ contract SwanTest is Helper { registerOracles listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; address _listedArtifactAddr = swan.getListedArtifacts(address(_agent), currRound)[0]; // increase time to the listing phase of the next round uint256 listingPhaseOfTheSecondRound = _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval + marketParameters.withdrawInterval; - increaseTime(listingPhaseOfTheSecondRound, _agent, AIAgent.Phase.Listing, 1); + increaseTime(listingPhaseOfTheSecondRound, _agent, SwanAgent.Phase.Listing, 1); // try to relist an artifact by another seller vm.prank(sellers[1]); @@ -418,14 +420,14 @@ contract SwanTest is Helper { registerOracles listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; address _listedArtifactAddr = swan.getListedArtifacts(address(_agent), currRound)[0]; // increase time to the listing phase of the next round uint256 listingPhaseOfTheSecondRound = _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval + marketParameters.withdrawInterval; - increaseTime(listingPhaseOfTheSecondRound, _agent, AIAgent.Phase.Listing, 1); + increaseTime(listingPhaseOfTheSecondRound, _agent, SwanAgent.Phase.Listing, 1); // list maxArtifactCount artifacts for (uint256 i = 0; i < marketParameters.maxArtifactCount; i++) { @@ -452,15 +454,15 @@ contract SwanTest is Helper { registerOracles listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { - AIAgent _agent = agents[0]; - AIAgent _agentToRelist = agents[1]; + SwanAgent _agent = agents[0]; + SwanAgent _agentToRelist = agents[1]; address _listedArtifactAddr = swan.getListedArtifacts(address(_agent), currRound)[0]; // increase time to the listing phase of the next round uint256 listingPhaseOfTheSecondRound = _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval + marketParameters.withdrawInterval; - increaseTime(listingPhaseOfTheSecondRound, _agent, AIAgent.Phase.Listing, 1); + increaseTime(listingPhaseOfTheSecondRound, _agent, SwanAgent.Phase.Listing, 1); vm.prank(sellers[0]); vm.expectRevert(abi.encodeWithSelector(Swan.InvalidPrice.selector, 0)); @@ -506,18 +508,18 @@ contract SwanTest is Helper { registerOracles listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; address _listedArtifactAddr = swan.getListedArtifacts(address(_agent), currRound)[0]; // increase time to the buy phase of the second round uint256 buyPhaseOfTheSecondRound = _agent.createdAt() + marketParameters.listingInterval + marketParameters.buyInterval + marketParameters.withdrawInterval + marketParameters.listingInterval; - increaseTime(buyPhaseOfTheSecondRound, _agent, AIAgent.Phase.Buy, 1); - currPhase = AIAgent.Phase.Buy; + increaseTime(buyPhaseOfTheSecondRound, _agent, SwanAgent.Phase.Buy, 1); + currPhase = SwanAgent.Phase.Buy; // try to relist - vm.expectRevert(abi.encodeWithSelector(AIAgent.InvalidPhase.selector, currPhase, AIAgent.Phase.Listing)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.InvalidPhase.selector, currPhase, SwanAgent.Phase.Listing)); vm.prank(sellers[0]); swan.relist(_listedArtifactAddr, address(_agent), artifactPrice); } @@ -532,18 +534,18 @@ contract SwanTest is Helper { registerOracles listArtifacts(sellers[0], marketParameters.maxArtifactCount, address(agents[0])) { - AIAgent _agent = agents[0]; + SwanAgent _agent = agents[0]; address _listedArtifactAddr = swan.getListedArtifacts(address(_agent), currRound)[0]; // increase time to the withdraw phase of the second round uint256 withdrawPhaseOfSecondRound = (2 * marketParameters.listingInterval) + (2 * marketParameters.buyInterval) + marketParameters.withdrawInterval + _agent.createdAt(); - increaseTime(withdrawPhaseOfSecondRound, _agent, AIAgent.Phase.Withdraw, 1); - currPhase = AIAgent.Phase.Withdraw; + increaseTime(withdrawPhaseOfSecondRound, _agent, SwanAgent.Phase.Withdraw, 1); + currPhase = SwanAgent.Phase.Withdraw; // try to relist - vm.expectRevert(abi.encodeWithSelector(AIAgent.InvalidPhase.selector, currPhase, AIAgent.Phase.Listing)); + vm.expectRevert(abi.encodeWithSelector(SwanAgent.InvalidPhase.selector, currPhase, SwanAgent.Phase.Listing)); vm.prank(sellers[0]); swan.relist(_listedArtifactAddr, address(_agent), artifactPrice); } @@ -573,7 +575,7 @@ contract SwanTest is Helper { increaseTime( agents[0].createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, agents[0], - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); @@ -607,7 +609,7 @@ contract SwanTest is Helper { increaseTime( agents[0].createdAt() + marketParameters.listingInterval + marketParameters.buyInterval, agents[0], - AIAgent.Phase.Withdraw, + SwanAgent.Phase.Withdraw, 0 ); diff --git a/src/mock/SvanV2.sol b/test/contracts/SwanV2.sol similarity index 66% rename from src/mock/SvanV2.sol rename to test/contracts/SwanV2.sol index a914b76..937a545 100644 --- a/src/mock/SvanV2.sol +++ b/test/contracts/SwanV2.sol @@ -1,8 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.20; -import {Swan} from "../Swan.sol"; +import {Swan} from "../../src/Swan.sol"; +/// @notice Mock contract to simulate an upgrade. contract SwanV2 is Swan { function upgraded() public view virtual returns (bool) { return true; diff --git a/test/WETH9.sol b/test/contracts/WETH9.sol similarity index 100% rename from test/WETH9.sol rename to test/contracts/WETH9.sol From 4d960ad42d557e4ea7bc39bf386e1f74f8980878 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 14:29:55 +0300 Subject: [PATCH 2/8] fix renames --- script/Deploy.s.sol | 4 ++-- src/Swan.sol | 8 ++++---- src/SwanAgent.sol | 4 ++-- test/Helper.t.sol | 18 +++++++++--------- test/SwanFuzzTest.t.sol | 4 ++-- test/SwanTest.t.sol | 2 +- test/script/Deploy.t.sol | 12 ++++++------ 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 4196a96..5d9c48d 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -33,7 +33,7 @@ contract DeployLLMOracleCoordinator is Script { } } -contract DeployAIAgentFactory is Script { +contract DeploySwanAgentFactory is Script { HelperConfig public config; function run() external returns (address addr) { @@ -42,7 +42,7 @@ contract DeployAIAgentFactory is Script { } } -contract DeployArtifactFactory is Script { +contract DeploySwanArtifactFactory is Script { HelperConfig public config; function run() external returns (address addr) { diff --git a/src/Swan.sol b/src/Swan.sol index f062a8e..cb3f8a2 100644 --- a/src/Swan.sol +++ b/src/Swan.sol @@ -181,7 +181,7 @@ contract Swan is SwanManager, UUPSUpgradeable { //////////////////////////////////////////////////////////////*/ /// @notice Creates a new agent. - /// @dev Emits a `AIAgentCreated` event. + /// @dev Emits a `AgentCreated` event. /// @return address of the new agent. function createAgent( string calldata _name, @@ -358,10 +358,10 @@ contract Swan is SwanManager, UUPSUpgradeable { emit ArtifactSold(listing.seller, msg.sender, _artifact, listing.price); } - /// @notice Set the factories for AI Agents and Artifacts. + /// @notice Set the factories for Agents and Artifacts. /// @dev Only callable by owner. - /// @param _agentFactory new AIAgentFactory address - /// @param _artifactFactory new ArtifactFactory address + /// @param _agentFactory new SwanAgentFactory address + /// @param _artifactFactory new SwanArtifactFactory address function setFactories(address _agentFactory, address _artifactFactory) external onlyOwner { agentFactory = SwanAgentFactory(_agentFactory); artifactFactory = SwanArtifactFactory(_artifactFactory); diff --git a/src/SwanAgent.sol b/src/SwanAgent.sol index 964ffac..f08222d 100644 --- a/src/SwanAgent.sol +++ b/src/SwanAgent.sol @@ -20,7 +20,7 @@ contract SwanAgentFactory { } } -/// @notice AIAgent is responsible for buying the artifacts from Swan. +/// @notice Agent is responsible for buying the artifacts from Swan. contract SwanAgent is Ownable { /*////////////////////////////////////////////////////////////// ERRORS @@ -131,7 +131,7 @@ contract SwanAgent is Ownable { //////////////////////////////////////////////////////////////*/ /// @notice Creates an agent. - /// @dev `_feeRoyalty` should be between 1 and maxAIAgentFee in the swan market parameters. + /// @dev `_feeRoyalty` should be between 1 and max agent fee in the swan market parameters. /// @dev All tokens are approved to the oracle coordinator of operator. constructor( string memory _name, diff --git a/test/Helper.t.sol b/test/Helper.t.sol index 71d5698..9513f8c 100644 --- a/test/Helper.t.sol +++ b/test/Helper.t.sol @@ -101,7 +101,7 @@ abstract contract Helper is Test { for (uint96 i = 0; i < agentOwners.length; i++) { agentParameters.push( AgentParameters({ - name: string.concat("AIAgent", vm.toString(uint256(i))), + name: string.concat("SwanAgent", vm.toString(uint256(i))), description: "description of the AI agent", feeRoyalty: feeRoyalty, amountPerRound: amountPerRound @@ -250,12 +250,12 @@ abstract contract Helper is Test { Vm.Log[] memory entries = vm.getRecordedLogs(); // 1. OwnershipTransferred (from Ownable) - // 2. Approval (from AIAgent constructor to approve coordinator) - // 3. Approval (from AIAgent constructor to approve swan) - // 4. AIAgentCreated (from Swan) + // 2. Approval (from SwanAgent constructor to approve coordinator) + // 3. Approval (from SwanAgent constructor to approve swan) + // 4. Agent (from Swan) assertEq(entries.length, 4); - // get the AIAgentCreated event + // get the agent event Vm.Log memory agentCreatedEvent = entries[entries.length - 1]; // Log is a struct that holds the event info: @@ -274,7 +274,7 @@ abstract contract Helper is Test { // get event sig bytes32 eventSig = agentCreatedEvent.topics[0]; - assertEq(keccak256("AIAgentCreated(address,address)"), eventSig); + assertEq(keccak256("AgentCreated(address,address)"), eventSig); // decode owner & agent address from topics address _owner = abi.decode(abi.encode(agentCreatedEvent.topics[1]), (address)); @@ -287,7 +287,7 @@ abstract contract Helper is Test { // all guuud agents.push(SwanAgent(_agent)); - vm.label(address(agents[i]), string.concat("AIAgent#", vm.toString(i + 1))); + vm.label(address(agents[i]), string.concat("SwanAgent#", vm.toString(i + 1))); // transfer token to agent token.transfer(address(AIagent), amountPerRound); @@ -323,13 +323,13 @@ abstract contract Helper is Test { vm.expectRevert(abi.encodeWithSelector(Swan.InvalidPrice.selector, invalidPrice)); vm.prank(seller); - swan.list("Artifact", "SA", "description or the swan artifact", invalidPrice, _agent); + swan.list("SwanArtifact", "SA", "description or the swan artifact", invalidPrice, _agent); vm.recordLogs(); for (uint256 i = 0; i < artifactCount; i++) { vm.prank(seller); swan.list( - string.concat("Artifact#", vm.toString(i)), + string.concat("SwanArtifact#", vm.toString(i)), string.concat("SA#", vm.toString(i)), "description or the swan artifact", artifactPrice, diff --git a/test/SwanFuzzTest.t.sol b/test/SwanFuzzTest.t.sol index 528cd0e..3087c60 100644 --- a/test/SwanFuzzTest.t.sol +++ b/test/SwanFuzzTest.t.sol @@ -125,7 +125,7 @@ contract SwanFuzzTest is Helper { uint256 _currTimestamp = block.timestamp; // increase time to buy phase of the second round but round comes +1 because of the setMarketParameters call - // AIAgents[0] should be in buy phase of second round + // agents[0] should be in buy phase of second round increaseTime( _currTimestamp + (2 * swan.getCurrentMarketParameters().listingInterval) + swan.getCurrentMarketParameters().buyInterval + swan.getCurrentMarketParameters().withdrawInterval, @@ -164,7 +164,7 @@ contract SwanFuzzTest is Helper { _allParams = swan.getMarketParameters(); assertEq(_allParams.length, 3); - // AIAgents[0] should be in listing phase of the fourth round (2 more increase time + 2 for setting new params) + // agents[0] should be in listing phase of the fourth round (2 more increase time + 2 for setting new params) checkRoundAndPhase(agents[0], SwanAgent.Phase.Listing, 3); // agentAfterFirstSet should be in listing phase of the second round diff --git a/test/SwanTest.t.sol b/test/SwanTest.t.sol index 4d0995a..257b62d 100644 --- a/test/SwanTest.t.sol +++ b/test/SwanTest.t.sol @@ -56,7 +56,7 @@ contract SwanTest is Helper { assertEq(swan.owner(), _newOwner); } - function test_CreateAIAgents() external createAgents fund { + function test_CreateSwanAgents() external createAgents fund { assertEq(agents.length, agentOwners.length); for (uint256 i = 0; i < agents.length; i++) { diff --git a/test/script/Deploy.t.sol b/test/script/Deploy.t.sol index 1ac14c5..44a339d 100644 --- a/test/script/Deploy.t.sol +++ b/test/script/Deploy.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.20; import { - DeployAIAgentFactory, - DeployArtifactFactory, + DeploySwanAgentFactory, + DeploySwanArtifactFactory, DeployLLMOracleCoordinator, DeployLLMOracleRegistry, DeploySwan @@ -17,8 +17,8 @@ import {Swan} from "../../src/Swan.sol"; import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; contract DeployTest is Test { - DeployAIAgentFactory deployAgentFactory; - DeployArtifactFactory deployArtifactFactory; + DeploySwanAgentFactory deployAgentFactory; + DeploySwanArtifactFactory deployArtifactFactory; DeployLLMOracleCoordinator deployLLMOracleCoordinator; DeployLLMOracleRegistry deployLLMOracleRegistry; DeploySwan deploySwan; @@ -36,10 +36,10 @@ contract DeployTest is Test { address llmOracleRegistryImpl; function setUp() external { - deployAgentFactory = new DeployAIAgentFactory(); + deployAgentFactory = new DeploySwanAgentFactory(); agentFactory = deployAgentFactory.run(); - deployArtifactFactory = new DeployArtifactFactory(); + deployArtifactFactory = new DeploySwanArtifactFactory(); artifactFactory = deployArtifactFactory.run(); deployLLMOracleRegistry = new DeployLLMOracleRegistry(); From 983368d1f26dba58bb24695d740c1208c0c04f69 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 14:40:31 +0300 Subject: [PATCH 3/8] added abi exporter --- abis/Swan.json | 1126 ++++++++++++++++++++++++++++++++++++++++ abis/SwanAgent.json | 624 ++++++++++++++++++++++ abis/SwanArtifact.json | 566 ++++++++++++++++++++ abis/parseAbi.js | 37 ++ export-abis.sh | 11 + 5 files changed, 2364 insertions(+) create mode 100644 abis/Swan.json create mode 100644 abis/SwanAgent.json create mode 100644 abis/SwanArtifact.json create mode 100644 abis/parseAbi.js create mode 100755 export-abis.sh diff --git a/abis/Swan.json b/abis/Swan.json new file mode 100644 index 0000000..2da2ca3 --- /dev/null +++ b/abis/Swan.json @@ -0,0 +1,1126 @@ +[ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "UPGRADE_INTERFACE_VERSION", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addOperator", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "agentFactory", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract SwanAgentFactory" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "artifactFactory", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract SwanArtifactFactory" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "artifactsPerAgentRound", + "inputs": [ + { + "name": "agent", + "type": "address", + "internalType": "address" + }, + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "coordinator", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract LLMOracleCoordinator" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "createAgent", + "inputs": [ + { + "name": "_name", + "type": "string", + "internalType": "string" + }, + { + "name": "_description", + "type": "string", + "internalType": "string" + }, + { + "name": "_feeRoyalty", + "type": "uint96", + "internalType": "uint96" + }, + { + "name": "_amountPerRound", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract SwanAgent" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getCurrentMarketParameters", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct SwanMarketParameters", + "components": [ + { + "name": "withdrawInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "listingInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "buyInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "platformFee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxArtifactCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "minArtifactPrice", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "timestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxAgentFee", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getListedArtifacts", + "inputs": [ + { + "name": "_agent", + "type": "address", + "internalType": "address" + }, + { + "name": "_round", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address[]", + "internalType": "address[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getListing", + "inputs": [ + { + "name": "_artifact", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct Swan.ArtifactListing", + "components": [ + { + "name": "createdAt", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "feeRoyalty", + "type": "uint96", + "internalType": "uint96" + }, + { + "name": "price", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "seller", + "type": "address", + "internalType": "address" + }, + { + "name": "agent", + "type": "address", + "internalType": "address" + }, + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "status", + "type": "uint8", + "internalType": "enum Swan.ArtifactStatus" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getListingPrice", + "inputs": [ + { + "name": "_artifact", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getMarketParameters", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct SwanMarketParameters[]", + "components": [ + { + "name": "withdrawInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "listingInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "buyInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "platformFee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxArtifactCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "minArtifactPrice", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "timestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxAgentFee", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOracleFee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOracleParameters", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct LLMOracleTaskParameters", + "components": [ + { + "name": "difficulty", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "numGenerations", + "type": "uint40", + "internalType": "uint40" + }, + { + "name": "numValidations", + "type": "uint40", + "internalType": "uint40" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_marketParameters", + "type": "tuple", + "internalType": "struct SwanMarketParameters", + "components": [ + { + "name": "withdrawInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "listingInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "buyInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "platformFee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxArtifactCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "minArtifactPrice", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "timestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxAgentFee", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "name": "_oracleParameters", + "type": "tuple", + "internalType": "struct LLMOracleTaskParameters", + "components": [ + { + "name": "difficulty", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "numGenerations", + "type": "uint40", + "internalType": "uint40" + }, + { + "name": "numValidations", + "type": "uint40", + "internalType": "uint40" + } + ] + }, + { + "name": "_coordinator", + "type": "address", + "internalType": "address" + }, + { + "name": "_token", + "type": "address", + "internalType": "address" + }, + { + "name": "_agentFactory", + "type": "address", + "internalType": "address" + }, + { + "name": "_artifactFactory", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isOperator", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "list", + "inputs": [ + { + "name": "_name", + "type": "string", + "internalType": "string" + }, + { + "name": "_symbol", + "type": "string", + "internalType": "string" + }, + { + "name": "_desc", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "_price", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_agent", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "listings", + "inputs": [ + { + "name": "artifact", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "createdAt", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "feeRoyalty", + "type": "uint96", + "internalType": "uint96" + }, + { + "name": "price", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "seller", + "type": "address", + "internalType": "address" + }, + { + "name": "agent", + "type": "address", + "internalType": "address" + }, + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "status", + "type": "uint8", + "internalType": "enum Swan.ArtifactStatus" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proxiableUUID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "purchase", + "inputs": [ + { + "name": "_artifact", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "relist", + "inputs": [ + { + "name": "_artifact", + "type": "address", + "internalType": "address" + }, + { + "name": "_agent", + "type": "address", + "internalType": "address" + }, + { + "name": "_price", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "removeOperator", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFactories", + "inputs": [ + { + "name": "_agentFactory", + "type": "address", + "internalType": "address" + }, + { + "name": "_artifactFactory", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setMarketParameters", + "inputs": [ + { + "name": "_marketParameters", + "type": "tuple", + "internalType": "struct SwanMarketParameters", + "components": [ + { + "name": "withdrawInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "listingInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "buyInterval", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "platformFee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxArtifactCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "minArtifactPrice", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "timestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxAgentFee", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setOracleParameters", + "inputs": [ + { + "name": "_oracleParameters", + "type": "tuple", + "internalType": "struct LLMOracleTaskParameters", + "components": [ + { + "name": "difficulty", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "numGenerations", + "type": "uint40", + "internalType": "uint40" + }, + { + "name": "numValidations", + "type": "uint40", + "internalType": "uint40" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "token", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ERC20" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "upgradeToAndCall", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "event", + "name": "AgentCreated", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "agent", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ArtifactListed", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "artifact", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "price", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ArtifactRelisted", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "agent", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "artifact", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "price", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ArtifactSold", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "agent", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "artifact", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "price", + "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": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ArtifactLimitExceeded", + "inputs": [ + { + "name": "limit", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC1967InvalidImplementation", + "inputs": [ + { + "name": "implementation", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1967NonPayable", + "inputs": [] + }, + { + "type": "error", + "name": "FailedCall", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidPhase", + "inputs": [ + { + "name": "have", + "type": "uint8", + "internalType": "enum SwanAgent.Phase" + }, + { + "name": "want", + "type": "uint8", + "internalType": "enum SwanAgent.Phase" + } + ] + }, + { + "type": "error", + "name": "InvalidPrice", + "inputs": [ + { + "name": "price", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidStatus", + "inputs": [ + { + "name": "have", + "type": "uint8", + "internalType": "enum Swan.ArtifactStatus" + }, + { + "name": "want", + "type": "uint8", + "internalType": "enum Swan.ArtifactStatus" + } + ] + }, + { + "type": "error", + "name": "NotInitializing", + "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": "RoundNotFinished", + "inputs": [ + { + "name": "artifact", + "type": "address", + "internalType": "address" + }, + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "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" + } + ] + } +] diff --git a/abis/SwanAgent.json b/abis/SwanAgent.json new file mode 100644 index 0000000..805a942 --- /dev/null +++ b/abis/SwanAgent.json @@ -0,0 +1,624 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_name", + "type": "string", + "internalType": "string" + }, + { + "name": "_description", + "type": "string", + "internalType": "string" + }, + { + "name": "_feeRoyalty", + "type": "uint96", + "internalType": "uint96" + }, + { + "name": "_amountPerRound", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_operator", + "type": "address", + "internalType": "address" + }, + { + "name": "_owner", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "amountPerRound", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "createdAt", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "description", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "feeRoyalty", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint96", + "internalType": "uint96" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoundPhase", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint8", + "internalType": "enum SwanAgent.Phase" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "inventory", + "inputs": [ + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "artifacts", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isOracleRequestProcessed", + "inputs": [ + { + "name": "taskId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "isProcessed", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "marketParameterIdx", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "minFundAmount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "oraclePurchaseRequest", + "inputs": [ + { + "name": "_input", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "_models", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "oraclePurchaseRequests", + "inputs": [ + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "taskId", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "oracleResult", + "inputs": [ + { + "name": "taskId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "oracleStateRequest", + "inputs": [ + { + "name": "_input", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "_models", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "oracleStateRequests", + "inputs": [ + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "taskId", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "purchase", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setAmountPerRound", + "inputs": [ + { + "name": "_amountPerRound", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFeeRoyalty", + "inputs": [ + { + "name": "newFeeRoyalty", + "type": "uint96", + "internalType": "uint96" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "spendings", + "inputs": [ + { + "name": "round", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "spending", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "state", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "swan", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract Swan" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "treasury", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "updateState", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_amount", + "type": "uint96", + "internalType": "uint96" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "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": "Purchase", + "inputs": [ + { + "name": "taskId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "round", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PurchaseRequest", + "inputs": [ + { + "name": "taskId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "round", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StateRequest", + "inputs": [ + { + "name": "taskId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "round", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StateUpdate", + "inputs": [ + { + "name": "taskId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "round", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "BuyLimitExceeded", + "inputs": [ + { + "name": "have", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "want", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidFee", + "inputs": [ + { + "name": "fee", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidPhase", + "inputs": [ + { + "name": "have", + "type": "uint8", + "internalType": "enum SwanAgent.Phase" + }, + { + "name": "want", + "type": "uint8", + "internalType": "enum SwanAgent.Phase" + } + ] + }, + { + "type": "error", + "name": "MinFundSubceeded", + "inputs": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "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": "TaskAlreadyProcessed", + "inputs": [] + }, + { + "type": "error", + "name": "TaskNotRequested", + "inputs": [] + }, + { + "type": "error", + "name": "Unauthorized", + "inputs": [ + { + "name": "caller", + "type": "address", + "internalType": "address" + } + ] + } +] diff --git a/abis/SwanArtifact.json b/abis/SwanArtifact.json new file mode 100644 index 0000000..aeb4bed --- /dev/null +++ b/abis/SwanArtifact.json @@ -0,0 +1,566 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_name", + "type": "string", + "internalType": "string" + }, + { + "name": "_symbol", + "type": "string", + "internalType": "string" + }, + { + "name": "_description", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "_owner", + "type": "address", + "internalType": "address" + }, + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "createdAt", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "description", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getApproved", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isApprovedForAll", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ownerOf", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "safeTransferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "safeTransferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setApprovalForAll", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "approved", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "tokenURI", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Approval", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "approved", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ApprovalForAll", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "approved", + "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": "Transfer", + "inputs": [ + { + "name": "from", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "ERC721IncorrectOwner", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC721InsufficientApproval", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC721InvalidApprover", + "inputs": [ + { + "name": "approver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC721InvalidOperator", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC721InvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC721InvalidReceiver", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC721InvalidSender", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC721NonexistentToken", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "OwnableInvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "OwnableUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + } +] diff --git a/abis/parseAbi.js b/abis/parseAbi.js new file mode 100644 index 0000000..e4e2cfe --- /dev/null +++ b/abis/parseAbi.js @@ -0,0 +1,37 @@ +const fs = require("fs"); + +if (process.argv.length < 3) { + console.error("Please provide a filename as a parameter."); + process.exit(1); +} + +const filename = process.argv[2]; + +fs.readFile(filename, "utf8", (err, data) => { + if (err) { + console.error(`Error reading file: ${err}`); + process.exit(1); + } + + try { + const jsonData = JSON.parse(data); + const abi = jsonData.abi; + + if (!abi) { + console.error("No `abi` field found in the JSON data."); + process.exit(1); + } + + fs.writeFile(filename, JSON.stringify(abi, null, 2), (err) => { + if (err) { + console.error(`Error writing file: ${err}`); + process.exit(1); + } + + console.log("ABI extracted and written to abi.json"); + }); + } catch (parseErr) { + console.error(`Error parsing JSON: ${parseErr}`); + process.exit(1); + } +}); diff --git a/export-abis.sh b/export-abis.sh new file mode 100755 index 0000000..2880b72 --- /dev/null +++ b/export-abis.sh @@ -0,0 +1,11 @@ +#!/bin/bash +mkdir abis + +cp ./out/Swan.sol/Swan.json ./abis/Swan.json +node ./abis/parseAbi.js ./abis/Swan.json + +cp ./out/SwanAgent.sol/SwanAgent.json ./abis/SwanAgent.json +node ./abis/parseAbi.js ./abis/SwanAgent.json + +cp ./out/SwanArtifact.sol/SwanArtifact.json ./abis/SwanArtifact.json +node ./abis/parseAbi.js ./abis/SwanArtifact.json From d7951743b0ff97c2f6e978aeabb850c0310d76f3 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 14:41:03 +0300 Subject: [PATCH 4/8] no need for mkdir --- export-abis.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/export-abis.sh b/export-abis.sh index 2880b72..9055e9b 100755 --- a/export-abis.sh +++ b/export-abis.sh @@ -1,5 +1,4 @@ #!/bin/bash -mkdir abis cp ./out/Swan.sol/Swan.json ./abis/Swan.json node ./abis/parseAbi.js ./abis/Swan.json From b2dafc88fe905e353b37ce7044cb6576500014ef Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 15:01:35 +0300 Subject: [PATCH 5/8] docs and abis updated --- abis/Swan.json | 2 +- abis/SwanAgent.json | 2 +- abis/SwanArtifact.json | 2 +- abis/parseAbi.js | 2 +- docs/src/README.md | 49 +- docs/src/SUMMARY.md | 10 +- docs/src/src/README.md | 9 +- docs/src/src/Swan.sol/constants.Swan.md | 16 +- docs/src/src/Swan.sol/contract.Swan.md | 38 +- .../src/SwanAgent.sol/contract.SwanAgent.md | 534 ++++++++++++++++++ .../contract.SwanAgentFactory.md | 22 + .../SwanArtifact.sol/contract.SwanArtifact.md | 40 ++ .../contract.SwanArtifactFactory.md | 20 + .../SwanManager.sol/abstract.SwanManager.md | 2 +- .../struct.SwanMarketParameters.md | 5 +- export-abis.sh | 1 + test/contracts/WETH9.sol | 1 + 17 files changed, 702 insertions(+), 53 deletions(-) create mode 100644 docs/src/src/SwanAgent.sol/contract.SwanAgent.md create mode 100644 docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md create mode 100644 docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md create mode 100644 docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md diff --git a/abis/Swan.json b/abis/Swan.json index 2da2ca3..a96b8ec 100644 --- a/abis/Swan.json +++ b/abis/Swan.json @@ -1123,4 +1123,4 @@ } ] } -] +] \ No newline at end of file diff --git a/abis/SwanAgent.json b/abis/SwanAgent.json index 805a942..761b408 100644 --- a/abis/SwanAgent.json +++ b/abis/SwanAgent.json @@ -621,4 +621,4 @@ } ] } -] +] \ No newline at end of file diff --git a/abis/SwanArtifact.json b/abis/SwanArtifact.json index aeb4bed..b94e0d5 100644 --- a/abis/SwanArtifact.json +++ b/abis/SwanArtifact.json @@ -563,4 +563,4 @@ } ] } -] +] \ No newline at end of file diff --git a/abis/parseAbi.js b/abis/parseAbi.js index e4e2cfe..dcb64f7 100644 --- a/abis/parseAbi.js +++ b/abis/parseAbi.js @@ -28,7 +28,7 @@ fs.readFile(filename, "utf8", (err, data) => { process.exit(1); } - console.log("ABI extracted and written to abi.json"); + console.log("ABI extracted and written to", filename); }); } catch (parseErr) { console.error(`Error parsing JSON: ${parseErr}`); diff --git a/docs/src/README.md b/docs/src/README.md index 2c88f81..88f7afe 100644 --- a/docs/src/README.md +++ b/docs/src/README.md @@ -11,11 +11,34 @@

+

+ + License: Apache 2.0 + + + Workflow: Tests + + + Discord + +

+ Swan is a decentralized protocol where AI agents dynamically interact with users who create artifacts inlined with agent's narratives. ## Installation -Install everything with: +First, make sure you have the requirements: + +- We are using [Foundry](https://book.getfoundry.sh/), so make sure you [install](https://book.getfoundry.sh/getting-started/installation) it first. +- Upgradable contracts make use of [NodeJS](https://nodejs.org/en), so you should [install](https://nodejs.org/en/download/package-manager) that as well. + +Clone the repository: + +```sh +git clone git@github.com:firstbatchxyz/swan-contracts.git +``` + +Install dependencies with: ```sh forge install @@ -27,12 +50,22 @@ Compile the contracts with: forge clean && forge build ``` +### Upgradability + We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library. To make sure upgrades are **safe**, you must do one of the following before you run `forge script` or `forge test` (as per their [docs](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running)): - `forge clean` beforehand, e.g. `forge clean && forge test` - include `--force` option when running, e.g. `forge test --force` -To update Swan in case any library is updated, you can do: +> Note that for some users this may fail (see [issue](https://github.com/firstbatchxyz/dria-oracle-contracts/issues/16)) due to a missing NPM package called `@openzeppelin/upgrades-core`. To fix it, do: +> +> ```sh +> npm install @openzeppelin/upgrades-core@latest -g +> ``` + +### Updates + +To update contracts to the latest library versions, use: ```sh forge update @@ -150,20 +183,18 @@ forge clean && forge snapshot You can see the snapshot `.gas-snapshot` file in the current directory. -## Format +## Documentation -Format code with: +We have auto-generated documentation under the [`docs`](./docs) folder, generated with the following command: ```sh -forge fmt +forge doc ``` -## Documentation - -We have auto-generated documentation under the [`docs`](./docs) folder, generated with the following command: +We provide an MDBook template over it, which you can open via: ```sh -forge doc +cd docs && mdbook serve --open ``` ## License diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 1f1917a..2ee1a3f 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -1,13 +1,11 @@ # Summary - [Home](README.md) # src - - [❱ mock](src/mock/README.md) - - [SwanV2](src/mock/SvanV2.sol/contract.SwanV2.md) - - [AIAgentFactory](src/AIAgent.sol/contract.AIAgentFactory.md) - - [AIAgent](src/AIAgent.sol/contract.AIAgent.md) - - [ArtifactFactory](src/Artifact.sol/contract.ArtifactFactory.md) - - [Artifact](src/Artifact.sol/contract.Artifact.md) - [Swan](src/Swan.sol/contract.Swan.md) - [Swan constants](src/Swan.sol/constants.Swan.md) + - [SwanAgentFactory](src/SwanAgent.sol/contract.SwanAgentFactory.md) + - [SwanAgent](src/SwanAgent.sol/contract.SwanAgent.md) + - [SwanArtifactFactory](src/SwanArtifact.sol/contract.SwanArtifactFactory.md) + - [SwanArtifact](src/SwanArtifact.sol/contract.SwanArtifact.md) - [SwanMarketParameters](src/SwanManager.sol/struct.SwanMarketParameters.md) - [SwanManager](src/SwanManager.sol/abstract.SwanManager.md) diff --git a/docs/src/src/README.md b/docs/src/src/README.md index f769760..e12172f 100644 --- a/docs/src/src/README.md +++ b/docs/src/src/README.md @@ -1,12 +1,11 @@ # Contents -- [mock](/src/mock) -- [AIAgentFactory](AIAgent.sol/contract.AIAgentFactory.md) -- [AIAgent](AIAgent.sol/contract.AIAgent.md) -- [ArtifactFactory](Artifact.sol/contract.ArtifactFactory.md) -- [Artifact](Artifact.sol/contract.Artifact.md) - [Swan](Swan.sol/contract.Swan.md) - [Swan constants](Swan.sol/constants.Swan.md) +- [SwanAgentFactory](SwanAgent.sol/contract.SwanAgentFactory.md) +- [SwanAgent](SwanAgent.sol/contract.SwanAgent.md) +- [SwanArtifactFactory](SwanArtifact.sol/contract.SwanArtifactFactory.md) +- [SwanArtifact](SwanArtifact.sol/contract.SwanArtifact.md) - [SwanMarketParameters](SwanManager.sol/struct.SwanMarketParameters.md) - [SwanManager](SwanManager.sol/abstract.SwanManager.md) diff --git a/docs/src/src/Swan.sol/constants.Swan.md b/docs/src/src/Swan.sol/constants.Swan.md index 6b85ff3..2fbe3a3 100644 --- a/docs/src/src/Swan.sol/constants.Swan.md +++ b/docs/src/src/Swan.sol/constants.Swan.md @@ -1,20 +1,24 @@ # Constants -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/Swan.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/Swan.sol) + +### SwanAgentPurchaseOracleProtocol +*Protocol string for Swan Purchase CRONs, checked in the Oracle.* -### SwanAIAgentPurchaseOracleProtocol ```solidity -bytes32 constant SwanAIAgentPurchaseOracleProtocol = "swan-agent-purchase/0.1.0"; +bytes32 constant SwanAgentPurchaseOracleProtocol = "swan-agent-purchase/0.1.0"; ``` -### SwanAIAgentStateOracleProtocol +### SwanAgentStateOracleProtocol +*Protocol string for Swan State CRONs, checked in the Oracle.* + ```solidity -bytes32 constant SwanAIAgentStateOracleProtocol = "swan-agent-state/0.1.0"; +bytes32 constant SwanAgentStateOracleProtocol = "swan-agent-state/0.1.0"; ``` ### BASIS_POINTS -*Used to calculate the fee for the AI agent to be able to compute correct amount.* +*Used to calculate the fee for the agent to be able to compute correct amount.* ```solidity diff --git a/docs/src/src/Swan.sol/contract.Swan.md b/docs/src/src/Swan.sol/contract.Swan.md index 5b49138..1c97fa6 100644 --- a/docs/src/src/Swan.sol/contract.Swan.md +++ b/docs/src/src/Swan.sol/contract.Swan.md @@ -1,5 +1,5 @@ # Swan -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/Swan.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/Swan.sol) **Inherits:** [SwanManager](/src/SwanManager.sol/abstract.SwanManager.md), UUPSUpgradeable @@ -7,11 +7,11 @@ ## State Variables ### agentFactory -Factory contract to deploy AI Agents. +Factory contract to deploy Agents. ```solidity -AIAgentFactory public agentFactory; +SwanAgentFactory public agentFactory; ``` @@ -20,7 +20,7 @@ Factory contract to deploy Artifact tokens. ```solidity -ArtifactFactory public artifactFactory; +SwanArtifactFactory public artifactFactory; ``` @@ -109,21 +109,21 @@ function transferOwnership(address newOwner) public override onlyOwner; ### createAgent -Creates a new AI agent. +Creates a new agent. -*Emits a `AIAgentCreated` event.* +*Emits a `AgentCreated` event.* ```solidity function createAgent(string calldata _name, string calldata _description, uint96 _feeRoyalty, uint256 _amountPerRound) external - returns (AIAgent); + returns (SwanAgent); ``` **Returns** |Name|Type|Description| |----|----|-----------| -|``|`AIAgent`|address of the new AI agent.| +|``|`SwanAgent`|address of the new agent.| ### list @@ -159,7 +159,7 @@ function relist(address _artifact, address _agent, uint256 _price) external; |Name|Type|Description| |----|----|-----------| |`_artifact`|`address`|address of the artifact.| -|`_agent`|`address`|new AIAgent for the artifact.| +|`_agent`|`address`|new agent for the artifact.| |`_price`|`uint256`|new price of the token.| @@ -185,7 +185,7 @@ function purchase(address _artifact) external; ### setFactories -Set the factories for AI Agents and Artifacts. +Set the factories for Agents and Artifacts. *Only callable by owner.* @@ -197,8 +197,8 @@ function setFactories(address _agentFactory, address _artifactFactory) external |Name|Type|Description| |----|----|-----------| -|`_agentFactory`|`address`|new AIAgentFactory address| -|`_artifactFactory`|`address`|new ArtifactFactory address| +|`_agentFactory`|`address`|new SwanAgentFactory address| +|`_artifactFactory`|`address`|new SwanArtifactFactory address| ### getListingPrice @@ -255,16 +255,16 @@ An `agent` purchased an artifact. event ArtifactSold(address indexed owner, address indexed agent, address indexed artifact, uint256 price); ``` -### AIAgentCreated -A new AI agent is created. +### AgentCreated +A new agent is created. -*`owner` is the owner of the AI agent.* +*`owner` is the owner of the agent.* -*`agent` is the address of the AI agent.* +*`agent` is the address of the agent.* ```solidity -event AIAgentCreated(address indexed owner, address indexed agent); +event AgentCreated(address indexed owner, address indexed agent); ``` ## Errors @@ -317,13 +317,13 @@ Holds the listing information. *`createdAt` is the timestamp of the artifact creation.* -*`feeRoyalty` is the royalty fee of the AIAgent.* +*`feeRoyalty` is the royalty fee of the agent.* *`price` is the price of the artifact.* *`seller` is the address of the creator of the artifact.* -*`agent` is the address of the AIAgent.* +*`agent` is the address of the agent.* *`round` is the round in which the artifact is created.* diff --git a/docs/src/src/SwanAgent.sol/contract.SwanAgent.md b/docs/src/src/SwanAgent.sol/contract.SwanAgent.md new file mode 100644 index 0000000..17b1eba --- /dev/null +++ b/docs/src/src/SwanAgent.sol/contract.SwanAgent.md @@ -0,0 +1,534 @@ +# SwanAgent +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanAgent.sol) + +**Inherits:** +Ownable + +Agent is responsible for buying the artifacts from Swan. + + +## State Variables +### swan +Swan contract. + + +```solidity +Swan public immutable swan; +``` + + +### createdAt +Timestamp when the contract is deployed. + + +```solidity +uint256 public immutable createdAt; +``` + + +### marketParameterIdx +Holds the index of the Swan market parameters at the time of deployment. + +*When calculating the round, we will use this index to determine the start interval.* + + +```solidity +uint256 public immutable marketParameterIdx; +``` + + +### name +Agent name. + + +```solidity +string public name; +``` + + +### description +Agent description, can include backstory, behavior and objective together. + + +```solidity +string public description; +``` + + +### state +State of the agent. + +*Only updated by the oracle via `updateState`.* + + +```solidity +bytes public state; +``` + + +### feeRoyalty +Royalty fees for the agent. + + +```solidity +uint96 public feeRoyalty; +``` + + +### amountPerRound +The max amount of money the agent can spend per round. + + +```solidity +uint256 public amountPerRound; +``` + + +### inventory +The artifacts that the agent has. + + +```solidity +mapping(uint256 round => address[] artifacts) public inventory; +``` + + +### spendings +Amount of money spent on each round. + + +```solidity +mapping(uint256 round => uint256 spending) public spendings; +``` + + +### oraclePurchaseRequests +Oracle requests for each round about item purchases. + +*A taskId of 0 means no request has been made.* + + +```solidity +mapping(uint256 round => uint256 taskId) public oraclePurchaseRequests; +``` + + +### oracleStateRequests +Oracle requests for each round about agent state updates. + +*A taskId of 0 means no request has been made.* + +*A non-zero taskId means a request has been made, but not necessarily processed.* + +*To see if a task is completed, check `isOracleTaskProcessed`.* + + +```solidity +mapping(uint256 round => uint256 taskId) public oracleStateRequests; +``` + + +### isOracleRequestProcessed +Indicates whether a given task has been processed. + +*This is used to prevent double processing of the same task.* + + +```solidity +mapping(uint256 taskId => bool isProcessed) public isOracleRequestProcessed; +``` + + +## Functions +### onlyAuthorized + +Check if the caller is the owner, operator, or Swan. + +*Swan is an operator itself, so the first check handles that as well.* + + +```solidity +modifier onlyAuthorized(); +``` + +### constructor + +Creates an agent. + +*`_feeRoyalty` should be between 1 and max agent fee in the swan market parameters.* + +*All tokens are approved to the oracle coordinator of operator.* + + +```solidity +constructor( + string memory _name, + string memory _description, + uint96 _feeRoyalty, + uint256 _amountPerRound, + address _operator, + address _owner +) Ownable(_owner); +``` + +### minFundAmount + +The minimum amount of money that the agent must leave within the contract. + +*minFundAmount should be `amountPerRound + oracleFee` to be able to make requests.* + + +```solidity +function minFundAmount() public view returns (uint256); +``` + +### oracleResult + +Reads the best performing result for a given task id, and parses it as an array of addresses. + + +```solidity +function oracleResult(uint256 taskId) public view returns (bytes memory); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`taskId`|`uint256`|task id to be read| + + +### oracleStateRequest + +Calls the LLMOracleCoordinator & pays for the oracle fees to make a state update request. + +*Works only in `Withdraw` phase.* + +*Calling again in the same round will overwrite the previous request. +The operator must check that there is no request in beforehand, +so to not overwrite an existing request of the owner.* + + +```solidity +function oracleStateRequest(bytes calldata _input, bytes calldata _models) external onlyAuthorized; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_input`|`bytes`|input to the LLMOracleCoordinator.| +|`_models`|`bytes`|models to be used for the oracle.| + + +### oraclePurchaseRequest + +Calls the LLMOracleCoordinator & pays for the oracle fees to make a purchase request. + +*Works only in `Buy` phase.* + +*Calling again in the same round will overwrite the previous request. +The operator must check that there is no request in beforehand, +so to not overwrite an existing request of the owner.* + + +```solidity +function oraclePurchaseRequest(bytes calldata _input, bytes calldata _models) external onlyAuthorized; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_input`|`bytes`|input to the LLMOracleCoordinator.| +|`_models`|`bytes`|models to be used for the oracle.| + + +### updateState + +Function to update the AI agent state. + +*Works only in `Withdraw` phase.* + +*Can be called multiple times within a single round, although is not expected to be done so.* + + +```solidity +function updateState() external onlyAuthorized; +``` + +### purchase + +Function to buy the artifacts from the Swan. + +*Works only in `Buy` phase.* + +*Can be called multiple times within a single round, although is not expected to be done so.* + +*This is not expected to revert if the oracle works correctly.* + + +```solidity +function purchase() external onlyAuthorized; +``` + +### withdraw + +Function to withdraw the tokens from the contract. + +*If the current phase is `Withdraw` agent owner can withdraw any amount of tokens.* + +*If the current phase is not `Withdraw` agent owner has to leave at least `minFundAmount` in the contract.* + + +```solidity +function withdraw(uint96 _amount) public onlyAuthorized; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_amount`|`uint96`|amount to withdraw.| + + +### treasury + +Alias to get the token balance of AI agent. + + +```solidity +function treasury() public view returns (uint256); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|token balance| + + +### _checkRoundPhase + +Checks that we are in the given phase, and returns both round and phase. + + +```solidity +function _checkRoundPhase(Phase _phase) internal view returns (uint256, Phase); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_phase`|`Phase`|expected phase.| + + +### _computeCycleTime + +Computes cycle time by using intervals from given market parameters. + +*Used in 'computePhase()' function.* + + +```solidity +function _computeCycleTime(SwanMarketParameters memory params) internal pure returns (uint256); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`params`|`SwanMarketParameters`|Market parameters of the Swan.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|the total cycle time that is `listingInterval + buyInterval + withdrawInterval`.| + + +### _computePhase + +Function to compute the current round, phase and time until next phase w.r.t given market parameters. + + +```solidity +function _computePhase(SwanMarketParameters memory params, uint256 elapsedTime) + internal + pure + returns (uint256, Phase, uint256); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`params`|`SwanMarketParameters`|Market parameters of the Swan.| +|`elapsedTime`|`uint256`|Time elapsed that computed in 'getRoundPhase()' according to the timestamps of each round.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|round, phase, time until next phase| +|``|`Phase`|| +|``|`uint256`|| + + +### getRoundPhase + +Function to return the current round, elapsed round and the current phase according to the current time. + +*Each round is composed of three phases in order: Listing, Buy, Withdraw.* + +*Internally, it computes the intervals from market parameters at the creation of this AI agent, until now.* + +*If there are many parameter changes throughout the life of this AI agent, this may cost more GAS.* + + +```solidity +function getRoundPhase() public view returns (uint256, Phase, uint256); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|round, phase, time until next phase| +|``|`Phase`|| +|``|`uint256`|| + + +### setFeeRoyalty + +Function to set feeRoyalty. + +*Only callable by the owner.* + +*Only callable in withdraw phase.* + + +```solidity +function setFeeRoyalty(uint96 newFeeRoyalty) public onlyOwner; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`newFeeRoyalty`|`uint96`|must be between 1 and 100.| + + +### setAmountPerRound + +Function to set the amountPerRound. + +*Only callable by the owner.* + +*Only callable in withdraw phase.* + + +```solidity +function setAmountPerRound(uint256 _amountPerRound) external onlyOwner; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_amountPerRound`|`uint256`|new amountPerRound.| + + +## Events +### StateRequest +Emitted when a state update request is made. + + +```solidity +event StateRequest(uint256 indexed taskId, uint256 indexed round); +``` + +### PurchaseRequest +Emitted when a purchase request is made. + + +```solidity +event PurchaseRequest(uint256 indexed taskId, uint256 indexed round); +``` + +### Purchase +Emitted when a purchase is made. + + +```solidity +event Purchase(uint256 indexed taskId, uint256 indexed round); +``` + +### StateUpdate +Emitted when the state is updated. + + +```solidity +event StateUpdate(uint256 indexed taskId, uint256 indexed round); +``` + +## Errors +### MinFundSubceeded +The `value` is less than `minFundAmount` + + +```solidity +error MinFundSubceeded(uint256 value); +``` + +### InvalidFee +Given fee is invalid, e.g. not within the range. + + +```solidity +error InvalidFee(uint256 fee); +``` + +### BuyLimitExceeded +Price limit exceeded for this round + + +```solidity +error BuyLimitExceeded(uint256 have, uint256 want); +``` + +### InvalidPhase +Invalid phase + + +```solidity +error InvalidPhase(Phase have, Phase want); +``` + +### Unauthorized +Unauthorized caller. + + +```solidity +error Unauthorized(address caller); +``` + +### TaskNotRequested +No task request has been made yet. + + +```solidity +error TaskNotRequested(); +``` + +### TaskAlreadyProcessed +The task was already processed, via `purchase` or `updateState`. + + +```solidity +error TaskAlreadyProcessed(); +``` + +## Enums +### Phase +Phase of the purchase loop. + + +```solidity +enum Phase { + Listing, + Buy, + Withdraw +} +``` + diff --git a/docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md b/docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md new file mode 100644 index 0000000..5a5621f --- /dev/null +++ b/docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md @@ -0,0 +1,22 @@ +# SwanAgentFactory +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanAgent.sol) + +Factory contract to deploy Agent contracts. + +*This saves from contract space for Swan.* + + +## Functions +### deploy + + +```solidity +function deploy( + string memory _name, + string memory _description, + uint96 _feeRoyalty, + uint256 _amountPerRound, + address _owner +) external returns (SwanAgent); +``` + diff --git a/docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md b/docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md new file mode 100644 index 0000000..86f8551 --- /dev/null +++ b/docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md @@ -0,0 +1,40 @@ +# SwanArtifact +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanArtifact.sol) + +**Inherits:** +ERC721, Ownable + +Artifact is an ERC721 token with a single token supply. + + +## State Variables +### createdAt +Creation time of the token + + +```solidity +uint256 public createdAt; +``` + + +### description +Description of the token + + +```solidity +bytes public description; +``` + + +## Functions +### constructor + +Constructor sets properties of the token. + + +```solidity +constructor(string memory _name, string memory _symbol, bytes memory _description, address _owner, address _operator) + ERC721(_name, _symbol) + Ownable(_owner); +``` + diff --git a/docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md b/docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md new file mode 100644 index 0000000..ce0db66 --- /dev/null +++ b/docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md @@ -0,0 +1,20 @@ +# SwanArtifactFactory +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanArtifact.sol) + +Factory contract to deploy Artifact tokens. + +*This saves from contract space for Swan.* + + +## Functions +### deploy + +Deploys a new Artifact token. + + +```solidity +function deploy(string memory _name, string memory _symbol, bytes memory _description, address _owner) + external + returns (SwanArtifact); +``` + diff --git a/docs/src/src/SwanManager.sol/abstract.SwanManager.md b/docs/src/src/SwanManager.sol/abstract.SwanManager.md index bd6ceb1..f7b1f23 100644 --- a/docs/src/src/SwanManager.sol/abstract.SwanManager.md +++ b/docs/src/src/SwanManager.sol/abstract.SwanManager.md @@ -1,5 +1,5 @@ # SwanManager -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/SwanManager.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanManager.sol) **Inherits:** OwnableUpgradeable diff --git a/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md b/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md index 98df9f9..903d2a9 100644 --- a/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md +++ b/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md @@ -1,10 +1,9 @@ # SwanMarketParameters -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/c9444a397017d961972cbbff400b67d973ffe956/src/SwanManager.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanManager.sol) Collection of market-related parameters. -*Prevents stack-too-deep. -TODO: use 256-bit tight-packing here* +*Prevents stack-too-deep.* ```solidity diff --git a/export-abis.sh b/export-abis.sh index 9055e9b..44f2338 100755 --- a/export-abis.sh +++ b/export-abis.sh @@ -1,4 +1,5 @@ #!/bin/bash +forge compile cp ./out/Swan.sol/Swan.json ./abis/Swan.json node ./abis/parseAbi.js ./abis/Swan.json diff --git a/test/contracts/WETH9.sol b/test/contracts/WETH9.sol index c729534..02f8229 100644 --- a/test/contracts/WETH9.sol +++ b/test/contracts/WETH9.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0 // Copyright (C) 2015, 2016, 2017 Dapphub // This program is free software: you can redistribute it and/or modify From 24e0365940f0434545a9c39573dfdf6b9975fc88 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 17:34:41 +0300 Subject: [PATCH 6/8] update docs --- .gas-snapshot | 86 ++++---- .gitignore | 1 + README.md | 120 ++++++----- coverage.sh | 24 ++- deployment/.gitignore | 1 + deployment/31337.json | 26 --- deployment/README.md | 1 + lcov.info | 450 +++++++++++++++++++++--------------------- storage.sh | 9 +- 9 files changed, 366 insertions(+), 352 deletions(-) mode change 100644 => 100755 coverage.sh create mode 100644 deployment/.gitignore delete mode 100644 deployment/31337.json create mode 100644 deployment/README.md mode change 100644 => 100755 storage.sh diff --git a/.gas-snapshot b/.gas-snapshot index c9beae8..2b54bbe 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,44 +1,44 @@ -AIAgentTest:test_InBuyPhase() (gas: 4504153) -AIAgentTest:test_InListingPhase() (gas: 4472120) -AIAgentTest:test_RevertWhen_SetAmountPerRoundInBuyPhase() (gas: 4483655) -AIAgentTest:test_RevertWhen_SetFeeWithInvalidRoyalty() (gas: 4492808) -AIAgentTest:test_RevertWhen_SetRoyaltyInListingPhase() (gas: 4473166) -AIAgentTest:test_RevertWhen_WithdrawByAnotherOwner() (gas: 4504441) -AIAgentTest:test_RevertWhen_WithdrawInBuyPhase() (gas: 4511039) -AIAgentTest:test_SetRoyaltyAndAmountPerRound() (gas: 4494015) -AIAgentTest:test_WithdrawInWithdrawPhase() (gas: 4474361) DeployTest:test_Deploy() (gas: 22076) -InvariantTest:invariant_AgentFeeRoyalty() (runs: 20, calls: 10000, reverts: 8980) -InvariantTest:invariant_ArtifactPriceRange() (runs: 20, calls: 10000, reverts: 9028) -InvariantTest:invariant_MaxArtifactCount() (runs: 20, calls: 10000, reverts: 8998) -InvariantTest:invariant_OwnerIsAnOperator() (runs: 20, calls: 10000, reverts: 8992) -SwanFuzzTest:testFuzz_CalculateRoyalties(uint256,uint256,uint256) (runs: 100, μ: 4478115, ~: 4478236) -SwanFuzzTest:testFuzz_ChangeCycleTime(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 100, μ: 6920555, ~: 6921298) -SwanFuzzTest:testFuzz_ListArtifact(string,string,bytes,uint256,string,string,uint96,uint256) (runs: 100, μ: 3923970, ~: 3924013) -SwanFuzzTest:testFuzz_TransferOwnership(address) (runs: 100, μ: 45356, ~: 45356) -SwanIntervalsTest:test_InBuyPhase() (gas: 4484185) -SwanIntervalsTest:test_InListingPhase() (gas: 4472550) -SwanIntervalsTest:test_InWithdrawPhase() (gas: 4487549) -SwanTest:test_CreateAIAgents() (gas: 5663937) -SwanTest:test_PurchaseAnArtifact() (gas: 11297765) -SwanTest:test_RelistArtifact() (gas: 10251837) -SwanTest:test_RevertWhen_CreateAgentWithInvalidRoyalty() (gas: 1619957) -SwanTest:test_RevertWhen_ListInWithdrawPhase() (gas: 5749933) -SwanTest:test_RevertWhen_ListMoreThanmaxArtifactCount() (gas: 10119397) -SwanTest:test_RevertWhen_PurchaseByAnotherAgent() (gas: 10142029) -SwanTest:test_RevertWhen_PurchaseInListingPhase() (gas: 10116892) -SwanTest:test_RevertWhen_PurchaseMoreThanAmountPerRound() (gas: 11333279) -SwanTest:test_RevertWhen_RelistAlreadyPurchasedArtifact() (gas: 11289853) -SwanTest:test_RevertWhen_RelistByAnotherSeller() (gas: 10127804) -SwanTest:test_RevertWhen_RelistInBuyPhase() (gas: 10163113) -SwanTest:test_RevertWhen_RelistInTheSameRound() (gas: 10119934) -SwanTest:test_RevertWhen_RelistInWithdrawPhase() (gas: 10162737) -SwanTest:test_RevertWhen_RelistMoreThanMaxArtifactCount() (gas: 13983200) -SwanTest:test_RevertWhen_SetMarketParametersWithInvalidFee() (gas: 1539671) -SwanTest:test_RevertWhen_UpgradeByNonOwner() (gas: 1543316) -SwanTest:test_SetAmountPerRound() (gas: 5720733) -SwanTest:test_SetFactories() (gas: 5172184) -SwanTest:test_SetMarketParameters() (gas: 5843554) -SwanTest:test_SetOracleParameters() (gas: 5665825) -SwanTest:test_TransferOwnership() (gas: 55416) -SwanTest:test_UpdateState() (gas: 12066139) \ No newline at end of file +InvariantTest:invariant_AgentFeeRoyalty() (runs: 20, calls: 10000, reverts: 8972) +InvariantTest:invariant_ArtifactPriceRange() (runs: 20, calls: 10000, reverts: 9002) +InvariantTest:invariant_MaxArtifactCount() (runs: 20, calls: 10000, reverts: 8966) +InvariantTest:invariant_OwnerIsAnOperator() (runs: 20, calls: 10000, reverts: 8926) +SwanAgentTest:test_InBuyPhase() (gas: 4504405) +SwanAgentTest:test_InListingPhase() (gas: 4472350) +SwanAgentTest:test_RevertWhen_SetAmountPerRoundInBuyPhase() (gas: 4483903) +SwanAgentTest:test_RevertWhen_SetFeeWithInvalidRoyalty() (gas: 4493071) +SwanAgentTest:test_RevertWhen_SetRoyaltyInListingPhase() (gas: 4473396) +SwanAgentTest:test_RevertWhen_WithdrawByAnotherOwner() (gas: 4504683) +SwanAgentTest:test_RevertWhen_WithdrawInBuyPhase() (gas: 4511301) +SwanAgentTest:test_SetRoyaltyAndAmountPerRound() (gas: 4494282) +SwanAgentTest:test_WithdrawInWithdrawPhase() (gas: 4474615) +SwanFuzzTest:testFuzz_CalculateRoyalties(uint256,uint256,uint256) (runs: 100, μ: 4478317, ~: 4478436) +SwanFuzzTest:testFuzz_ChangeCycleTime(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 100, μ: 6920941, ~: 6921698) +SwanFuzzTest:testFuzz_ListArtifact(string,string,bytes,uint256,string,string,uint96,uint256) (runs: 100, μ: 3924204, ~: 3924238) +SwanFuzzTest:testFuzz_TransferOwnership(address) (runs: 100, μ: 45365, ~: 45365) +SwanIntervalsTest:test_InBuyPhase() (gas: 4484429) +SwanIntervalsTest:test_InListingPhase() (gas: 4472772) +SwanIntervalsTest:test_InWithdrawPhase() (gas: 4487796) +SwanTest:test_CreateSwanAgents() (gas: 5664526) +SwanTest:test_PurchaseAnArtifact() (gas: 11299061) +SwanTest:test_RelistArtifact() (gas: 10252952) +SwanTest:test_RevertWhen_CreateAgentWithInvalidRoyalty() (gas: 1620230) +SwanTest:test_RevertWhen_ListInWithdrawPhase() (gas: 5750553) +SwanTest:test_RevertWhen_ListMoreThanmaxArtifactCount() (gas: 10120420) +SwanTest:test_RevertWhen_PurchaseByAnotherAgent() (gas: 10143076) +SwanTest:test_RevertWhen_PurchaseInListingPhase() (gas: 10117930) +SwanTest:test_RevertWhen_PurchaseMoreThanAmountPerRound() (gas: 11334511) +SwanTest:test_RevertWhen_RelistAlreadyPurchasedArtifact() (gas: 11291127) +SwanTest:test_RevertWhen_RelistByAnotherSeller() (gas: 10128856) +SwanTest:test_RevertWhen_RelistInBuyPhase() (gas: 10164182) +SwanTest:test_RevertWhen_RelistInTheSameRound() (gas: 10120976) +SwanTest:test_RevertWhen_RelistInWithdrawPhase() (gas: 10163806) +SwanTest:test_RevertWhen_RelistMoreThanMaxArtifactCount() (gas: 13984372) +SwanTest:test_RevertWhen_SetMarketParametersWithInvalidFee() (gas: 1539932) +SwanTest:test_RevertWhen_UpgradeByNonOwner() (gas: 1543580) +SwanTest:test_SetAmountPerRound() (gas: 5721328) +SwanTest:test_SetFactories() (gas: 5172520) +SwanTest:test_SetMarketParameters() (gas: 5844131) +SwanTest:test_SetOracleParameters() (gas: 5666393) +SwanTest:test_TransferOwnership() (gas: 55434) +SwanTest:test_UpdateState() (gas: 12067589) \ No newline at end of file diff --git a/.gitignore b/.gitignore index c0dc496..433c961 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ storage/ # Dotenv file .env +.preset.sh # appleeeee .DS_Store diff --git a/README.md b/README.md index 88f7afe..3b6252c 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ First, make sure you have the requirements: Clone the repository: ```sh -git clone git@github.com:firstbatchxyz/swan-contracts.git +git clone git@github.com:firstbatchxyz/dria-oracle-contracts.git ``` Install dependencies with: @@ -52,11 +52,13 @@ forge clean && forge build ### Upgradability -We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library. To make sure upgrades are **safe**, you must do one of the following before you run `forge script` or `forge test` (as per their [docs](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running)): +We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library. To make sure upgrades are **safe**, you must do one of the following (as per their [docs](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running)) before you run `forge script` or `forge test`: - `forge clean` beforehand, e.g. `forge clean && forge test` - include `--force` option when running, e.g. `forge test --force` +> [!NOTE] +> > Note that for some users this may fail (see [issue](https://github.com/firstbatchxyz/dria-oracle-contracts/issues/16)) due to a missing NPM package called `@openzeppelin/upgrades-core`. To fix it, do: > > ```sh @@ -71,67 +73,89 @@ To update contracts to the latest library versions, use: forge update ``` -## Deployment +## Usage -**Step 1.** -Import your `ETHERSCAN_API_KEY` to env file. +### Setup -> [!NOTE] -> -> Foundry expects the API key to be defined as `ETHERSCAN_API_KEY` even though you're using another explorer. +To be able to deploy & use our contracts, we need two things: + +- [Ethereum Wallet](#create-wallet) +- [RPC endpoint](#prepare-rpc-endpoint) -**Step 2.** -Create keystores for deployment. [See more for keystores](https://eips.ethereum.org/EIPS/eip-2335) +### Create Wallet + +We use keystores for wallet management, with the help of [`cast wallet`](https://book.getfoundry.sh/reference/cast/wallet-commands) command. + +Use the command below to create your keystore. The command will prompt for your **private key**, and a **password** to encrypt the keystore itself. ```sh -cast wallet import --interactive +cast wallet import --interactive ``` -You can see your wallets with: +> [!ALERT] +> +> Note that you will need to enter the password when you use this keystore. + +You can see your keystores under the default directory (`~/.foundry/keystores`) with the command: ```sh cast wallet list ``` -> [!NOTE] -> -> Recommended to create keystores on directly on your shell. -> You HAVE to type your password on the terminal to be able to use your keys. (e.g when deploying a contract) +### Prepare RPC Endpoint -**Step 3.** -Enter your private key (associated with your address) and password on terminal. You'll see your address on terminal. +To interact with the blockchain, we require an RPC endpoint. You can get one from: -> [!NOTE] -> -> If you want to deploy contracts on localhost please provide local address for the command above. +- [Alchemy](https://www.alchemy.com/) +- [Infura](https://www.infura.io/) +- [(see more)](https://www.alchemy.com/best/rpc-node-providers) + +You will use this endpoint for the commands that interact with the blockchain, such as deploying and upgrading; or while doing fork tests. + +### Deploy & Verify Contract -**Step 4.** Deploy the contract with: ```sh -forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast +forge clean && forge script ./script/Deploy.s.sol:Deploy \ +--rpc-url \ +--account \ +--broadcast ``` -or for instant verification use: +You can see deployed contract addresses under the `deployment/.json` + +You can verify the contract during deployment by adding the verification arguments as well: ```sh -forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast --verify --verifier --verifier-url +forge clean && forge script ./script/Deploy.s.sol:Deploy \ +--rpc-url \ +--account \ +--broadcast \ +--verify --verifier blockscout \ +--verifier-url ``` -> [!NOTE] > `` should be expolorer's homepage url. Forge reads your `` from .env file so you don't need to add this at the end of ``. -> -> e.g. -> `https://base-sepolia.blockscout.com/api/` for `Base Sepolia Network` +You can verify an existing contract with: -You can see deployed contract addresses under the `deployment/.json` +```sh +forge verify-contract ./src/.sol: \ +--verifier blockscout \ +--verifier-url +``` -## Verify Contract +Note that the `--verifier-url` value should be the target explorer's homepage URL. Some example URLs are: -Verify contract manually with: +- `https://base.blockscout.com/api/` for Base (Mainnet) +- `https://base-sepolia.blockscout.com/api/` for Base Sepolia (Testnet) -```sh -forge verify-contract src/$.sol: --verifier --verifier-url -``` +> [!NOTE] +> +> URL should not contain the API key! Foundry will read your `ETHERSCAN_API_KEY` from environment. + +> [!NOTE] +> +> The `--verifier` can accept any of the following: `etherscan`, `blockscout`, `sourcify`, `oklink`. We are using Blockscout most of the time. ## Testing & Diagnostics @@ -139,6 +163,9 @@ Run tests on local network: ```sh forge clean && forge test + +# or -vvv to show reverts in detail +forge clean && forge test -vvv ``` or fork an existing chain and run the tests on it: @@ -147,31 +174,29 @@ or fork an existing chain and run the tests on it: forge clean && forge test --rpc-url ``` -### Coverage +### Code Coverage -Check coverages with: +We have a script that generates the coverage information as an HTML page. This script requires [`lcov`](https://linux.die.net/man/1/lcov) and [`genhtml`](https://linux.die.net/man/1/genhtml) command line tools. To run, do: ```sh -forge clean && bash coverage.sh +forge clean && ./coverage.sh ``` -or to see summarized coverages on terminal: +Alternatively, you can see a summarized text-only output as well: ```sh forge clean && forge coverage --no-match-coverage "(test|mock|script)" ``` -You can see coverages under the coverage directory. - ### Storage Layout Get storage layout with: ```sh -forge clean && bash storage.sh +./storage.sh ``` -You can see storage layouts under the storage directory. +You can see storage layouts under the [`storage`](./storage/) directory. ### Gas Snapshot @@ -185,16 +210,13 @@ You can see the snapshot `.gas-snapshot` file in the current directory. ## Documentation -We have auto-generated documentation under the [`docs`](./docs) folder, generated with the following command: +We have auto-generated MDBook documentations under the [`docs`](./docs) folder, generated with the following command: ```sh forge doc -``` -We provide an MDBook template over it, which you can open via: - -```sh -cd docs && mdbook serve --open +# serves the book as well +forge doc --serve ``` ## License diff --git a/coverage.sh b/coverage.sh old mode 100644 new mode 100755 index f92532c..15612c1 --- a/coverage.sh +++ b/coverage.sh @@ -3,14 +3,28 @@ # exit on error set -e -# Run forge coverage +# give error if `lcov` is not installed +if ! command -v lcov &> /dev/null +then + echo "lcov could not be found. Please install lcov" + exit +fi + +# give error if `genhtml` is not installed +if ! command -v genhtml &> /dev/null +then + echo "genhtml could not be found. Please install lcov" + exit +fi + +# generate coverage info forge coverage \ --report lcov \ --report summary \ --no-match-coverage "(test|mock|script)" -# Install lcov -brew install lcov +# generate HTML report from lcov.info +genhtml lcov.info -o coverage --branch-coverage --ignore-errors inconsistent,category,corrupt -# Generate HTML report from lcov.info -genhtml lcov.info -o coverage --branch-coverage --ignore-errors inconsistent,category,corrupt \ No newline at end of file +# open report +open coverage/index.html diff --git a/deployment/.gitignore b/deployment/.gitignore new file mode 100644 index 0000000..e6a0926 --- /dev/null +++ b/deployment/.gitignore @@ -0,0 +1 @@ +31337.json diff --git a/deployment/31337.json b/deployment/31337.json deleted file mode 100644 index 3a5adfa..0000000 --- a/deployment/31337.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "AIAgentFactory": { - "addr": "0x34a1d3fff3958843c43ad80f30b94c510645c316" - }, - "LLMOracleRegistry": { - "proxyAddr": "0xbb2180ebd78ce97360503434ed37fcf4a1df61c3", - "implAddr": "0xa8452ec99ce0c64f20701db7dd3abdb607c00496" - }, - "LLMOracleCoordinator": { - "proxyAddr": "0x50eef481cae4250d252ae577a09bf514f224c6c4", - "implAddr": "0xdb8cff278adccf9e9b5da745b44e754fc4ee3c76" - }, - "ArtifactFactory": { - "addr": "0x90193c961a926261b756d1e5bb255e67ff9498a1" - }, - "Swan": { - "proxyAddr": "0xdeb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", - "implAddr": "0x62c20aa1e0272312bc100b4e23b4dc1ed96dd7d1" - }, - "SwanAgentFactory": { - "addr": "0x34a1d3fff3958843c43ad80f30b94c510645c316" - }, - "SwanArtifactFactory": { - "addr": "0x90193c961a926261b756d1e5bb255e67ff9498a1" - } -} \ No newline at end of file diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 0000000..1f5296f --- /dev/null +++ b/deployment/README.md @@ -0,0 +1 @@ +# Deployment Commands diff --git a/lcov.info b/lcov.info index d336526..3a4c8ad 100644 --- a/lcov.info +++ b/lcov.info @@ -1,22 +1,159 @@ TN: -SF:src/AIAgent.sol -DA:12,1251 -FN:12,AIAgentFactory.deploy -FNDA:1251,AIAgentFactory.deploy -DA:19,1251 +SF:src/Swan.sol +DA:117,44 +FN:117,Swan.constructor +FNDA:44,Swan.constructor +DA:118,44 +DA:128,1 +FN:128,Swan._authorizeUpgrade +FNDA:1,Swan._authorizeUpgrade +DA:133,647 +FN:133,Swan.initialize +FNDA:647,Swan.initialize +DA:142,44 +DA:144,44 +BRDA:144,0,0,- +BRDA:144,0,1,44 +DA:147,44 +DA:148,44 +DA:151,44 +DA:152,44 +DA:153,44 +DA:154,44 +DA:157,44 +DA:159,44 +DA:165,700 +FN:165,Swan.transferOwnership +FNDA:700,Swan.transferOwnership +DA:166,102 +BRDA:166,1,0,1 +DA:167,1 +DA:170,101 +DA:173,101 +DA:176,101 +DA:186,1238 +FN:186,Swan.createAgent +FNDA:1238,Swan.createAgent +DA:192,1238 +DA:193,660 +DA:195,660 +DA:204,790 +FN:204,Swan.list +FNDA:790,Swan.list +DA:207,790 +DA:208,790 +DA:211,157 +BRDA:211,2,0,1 +DA:212,1 +DA:215,156 +BRDA:215,3,0,1 +DA:216,1 +DA:219,155 +BRDA:219,4,0,13 +DA:220,13 +DA:224,142 +DA:225,142 +DA:236,142 +DA:239,142 +DA:241,142 +DA:248,595 +FN:248,Swan.relist +FNDA:595,Swan.relist +DA:249,595 +DA:252,595 +BRDA:252,5,0,588 +DA:253,588 +DA:257,7 +BRDA:257,6,0,1 +DA:258,1 +DA:268,6 +DA:269,6 +BRDA:269,7,0,1 +DA:270,1 +DA:274,5 +BRDA:274,8,0,1 +DA:275,1 +DA:279,4 +DA:280,4 +DA:283,4 +BRDA:283,9,0,2 +DA:284,2 +DA:288,2 +DA:289,2 +BRDA:289,10,0,1 +DA:290,1 +DA:294,1 +DA:305,1 +DA:308,1 +DA:310,1 +DA:314,143 +FN:314,Swan.transferRoyalties +FNDA:143,Swan.transferRoyalties +DA:316,143 +DA:317,143 +DA:318,143 +DA:322,143 +DA:325,143 +DA:328,143 +DA:333,677 +FN:333,Swan.purchase +FNDA:677,Swan.purchase +DA:334,677 +DA:337,677 +BRDA:337,11,0,673 +DA:338,673 +DA:342,4 +BRDA:342,12,0,- +DA:343,0 +DA:347,4 +DA:351,4 +DA:352,4 +DA:355,4 +DA:356,4 +DA:358,4 +DA:365,598 +FN:365,Swan.setFactories +FNDA:598,Swan.setFactories +DA:366,1 +DA:367,1 +DA:371,5 +FN:371,Swan.getListingPrice +FNDA:5,Swan.getListingPrice +DA:372,5 +DA:376,125 +FN:376,Swan.getListedArtifacts +FNDA:125,Swan.getListedArtifacts +DA:377,125 +DA:381,141 +FN:381,Swan.getListing +FNDA:141,Swan.getListing +DA:382,141 +FNF:13 +FNH:13 +LF:88 +LH:87 +BRF:14 +BRH:12 +end_of_record +TN: +SF:src/SwanAgent.sol +DA:12,1264 +FN:12,SwanAgentFactory.deploy +FNDA:1264,SwanAgentFactory.deploy +DA:19,1264 DA:121,2 -FN:121,AIAgent.onlyAuthorized -FNDA:2,AIAgent.onlyAuthorized +FN:121,SwanAgent.onlyAuthorized +FNDA:2,SwanAgent.onlyAuthorized DA:123,2 BRDA:123,0,0,1 DA:124,1 -DA:136,1251 -FN:136,AIAgent.constructor -FNDA:1251,AIAgent.constructor -DA:144,1249 -DA:146,1249 -BRDA:146,1,0,5 -DA:147,5 +DA:136,1264 +FN:136,SwanAgent.constructor +FNDA:1264,SwanAgent.constructor +DA:144,1264 +DA:146,1264 +BRDA:146,1,0,13 +DA:147,13 DA:150,660 DA:151,660 DA:152,660 @@ -26,31 +163,31 @@ DA:155,660 DA:159,660 DA:160,660 DA:169,0 -FN:169,AIAgent.minFundAmount -FNDA:0,AIAgent.minFundAmount +FN:169,SwanAgent.minFundAmount +FNDA:0,SwanAgent.minFundAmount DA:170,1 DA:175,0 -FN:175,AIAgent.oracleResult -FNDA:0,AIAgent.oracleResult +FN:175,SwanAgent.oracleResult +FNDA:0,SwanAgent.oracleResult DA:177,5 BRDA:177,2,0,- DA:178,0 DA:181,5 DA:191,2 -FN:191,AIAgent.oracleStateRequest -FNDA:2,AIAgent.oracleStateRequest +FN:191,SwanAgent.oracleStateRequest +FNDA:2,SwanAgent.oracleStateRequest DA:193,1 DA:195,1 DA:198,1 DA:208,4 -FN:208,AIAgent.oraclePurchaseRequest -FNDA:4,AIAgent.oraclePurchaseRequest +FN:208,SwanAgent.oraclePurchaseRequest +FNDA:4,SwanAgent.oraclePurchaseRequest DA:210,4 DA:212,4 DA:215,4 DA:221,2 -FN:221,AIAgent.updateState -FNDA:2,AIAgent.updateState +FN:221,SwanAgent.updateState +FNDA:2,SwanAgent.updateState DA:223,1 DA:226,1 DA:227,0 @@ -61,8 +198,8 @@ DA:233,1 DA:236,1 DA:238,1 DA:245,7 -FN:245,AIAgent.purchase -FNDA:7,AIAgent.purchase +FN:245,SwanAgent.purchase +FNDA:7,SwanAgent.purchase DA:247,6 DA:250,5 DA:251,1 @@ -82,8 +219,8 @@ DA:274,4 DA:278,3 DA:280,3 DA:287,3 -FN:287,AIAgent.withdraw -FNDA:3,AIAgent.withdraw +FN:287,SwanAgent.withdraw +FNDA:3,SwanAgent.withdraw DA:288,2 DA:292,2 BRDA:292,6,0,1 @@ -92,24 +229,24 @@ BRDA:295,7,0,1 DA:296,1 DA:301,1 DA:306,1 -FN:306,AIAgent.treasury -FNDA:1,AIAgent.treasury +FN:306,SwanAgent.treasury +FNDA:1,SwanAgent.treasury DA:307,2 DA:312,19 -FN:312,AIAgent._checkRoundPhase -FNDA:19,AIAgent._checkRoundPhase +FN:312,SwanAgent._checkRoundPhase +FNDA:19,SwanAgent._checkRoundPhase DA:313,19 DA:314,19 BRDA:314,8,0,3 DA:315,3 DA:318,16 DA:325,1319 -FN:325,AIAgent._computeCycleTime -FNDA:1319,AIAgent._computeCycleTime +FN:325,SwanAgent._computeCycleTime +FNDA:1319,SwanAgent._computeCycleTime DA:326,1319 DA:333,1319 -FN:333,AIAgent._computePhase -FNDA:1319,AIAgent._computePhase +FN:333,SwanAgent._computePhase +FNDA:1319,SwanAgent._computePhase DA:338,1319 DA:339,1319 DA:340,1319 @@ -123,8 +260,8 @@ BRDA:347,10,1,24 DA:348,625 DA:350,24 DA:359,798 -FN:359,AIAgent.getRoundPhase -FNDA:798,AIAgent.getRoundPhase +FN:359,SwanAgent.getRoundPhase +FNDA:798,SwanAgent.getRoundPhase DA:360,819 DA:362,819 BRDA:362,11,0,419 @@ -143,16 +280,16 @@ DA:392,400 DA:394,400 DA:396,400 DA:404,4 -FN:404,AIAgent.setFeeRoyalty -FNDA:4,AIAgent.setFeeRoyalty +FN:404,SwanAgent.setFeeRoyalty +FNDA:4,SwanAgent.setFeeRoyalty DA:405,4 DA:407,3 BRDA:407,12,0,2 DA:408,2 DA:410,1 DA:417,3 -FN:417,AIAgent.setAmountPerRound -FNDA:3,AIAgent.setAmountPerRound +FN:417,SwanAgent.setAmountPerRound +FNDA:3,SwanAgent.setAmountPerRound DA:418,3 DA:420,2 FNF:17 @@ -163,18 +300,18 @@ BRF:16 BRH:14 end_of_record TN: -SF:src/Artifact.sol -DA:11,766 -FN:11,ArtifactFactory.deploy -FNDA:766,ArtifactFactory.deploy -DA:15,766 -DA:27,766 -FN:27,Artifact.constructor -FNDA:766,Artifact.constructor -DA:34,766 -DA:35,766 -DA:38,766 -DA:41,766 +SF:src/SwanArtifact.sol +DA:11,764 +FN:11,SwanArtifactFactory.deploy +FNDA:764,SwanArtifactFactory.deploy +DA:15,764 +DA:27,764 +FN:27,SwanArtifact.constructor +FNDA:764,SwanArtifact.constructor +DA:34,764 +DA:35,764 +DA:38,764 +DA:41,761 FNF:2 FNH:2 LF:7 @@ -183,185 +320,48 @@ BRF:0 BRH:0 end_of_record TN: -SF:src/Swan.sol -DA:116,44 -FN:116,Swan.constructor -FNDA:44,Swan.constructor -DA:117,44 -DA:127,1 -FN:127,Swan._authorizeUpgrade -FNDA:1,Swan._authorizeUpgrade -DA:132,666 -FN:132,Swan.initialize -FNDA:666,Swan.initialize -DA:141,44 -DA:143,44 -BRDA:143,0,0,- -BRDA:143,0,1,44 -DA:146,44 -DA:147,44 -DA:150,44 -DA:151,44 -DA:152,44 -DA:153,44 -DA:156,44 -DA:158,44 -DA:164,736 -FN:164,Swan.transferOwnership -FNDA:736,Swan.transferOwnership -DA:165,102 -BRDA:165,1,0,1 -DA:166,1 -DA:169,101 -DA:172,101 -DA:175,101 -DA:185,1271 -FN:185,Swan.createAgent -FNDA:1271,Swan.createAgent -DA:191,1271 -DA:192,660 -DA:194,660 -DA:203,780 -FN:203,Swan.list -FNDA:780,Swan.list -DA:206,780 -DA:207,780 -DA:210,157 -BRDA:210,2,0,1 -DA:211,1 -DA:214,156 -BRDA:214,3,0,1 -DA:215,1 -DA:218,155 -BRDA:218,4,0,13 -DA:219,13 -DA:223,142 -DA:224,142 -DA:235,142 -DA:238,142 -DA:240,142 -DA:247,682 -FN:247,Swan.relist -FNDA:682,Swan.relist -DA:248,682 -DA:251,682 -BRDA:251,5,0,675 -DA:252,675 -DA:256,7 -BRDA:256,6,0,1 -DA:257,1 -DA:267,6 -DA:268,6 -BRDA:268,7,0,1 -DA:269,1 -DA:273,5 -BRDA:273,8,0,1 -DA:274,1 -DA:278,4 -DA:279,4 -DA:282,4 -BRDA:282,9,0,2 -DA:283,2 -DA:287,2 -DA:288,2 -BRDA:288,10,0,1 -DA:289,1 -DA:293,1 -DA:304,1 -DA:307,1 -DA:309,1 -DA:313,143 -FN:313,Swan.transferRoyalties -FNDA:143,Swan.transferRoyalties -DA:315,143 -DA:316,143 -DA:317,143 -DA:321,143 -DA:324,143 -DA:327,143 -DA:332,697 -FN:332,Swan.purchase -FNDA:697,Swan.purchase -DA:333,697 -DA:336,697 -BRDA:336,11,0,693 -DA:337,693 -DA:341,4 -BRDA:341,12,0,- -DA:342,0 -DA:346,4 -DA:350,4 -DA:351,4 -DA:354,4 -DA:355,4 -DA:357,4 -DA:364,606 -FN:364,Swan.setFactories -FNDA:606,Swan.setFactories -DA:365,1 -DA:366,1 -DA:370,5 -FN:370,Swan.getListingPrice -FNDA:5,Swan.getListingPrice -DA:371,5 -DA:375,125 -FN:375,Swan.getListedArtifacts -FNDA:125,Swan.getListedArtifacts -DA:376,125 -DA:380,141 -FN:380,Swan.getListing -FNDA:141,Swan.getListing -DA:381,141 -FNF:13 -FNH:13 -LF:88 -LH:87 -BRF:14 -BRH:12 -end_of_record -TN: SF:src/SwanManager.sol -DA:60,44 -FN:60,SwanManager.constructor +DA:59,44 +FN:59,SwanManager.constructor FNDA:44,SwanManager.constructor -DA:61,44 -DA:69,1679 -FN:69,SwanManager.getMarketParameters +DA:60,44 +DA:68,1679 +FN:68,SwanManager.getMarketParameters FNDA:1679,SwanManager.getMarketParameters -DA:70,1679 -DA:74,6 -FN:74,SwanManager.getOracleParameters +DA:69,1679 +DA:73,6 +FN:73,SwanManager.getOracleParameters FNDA:6,SwanManager.getOracleParameters -DA:75,6 -DA:81,796 -FN:81,SwanManager.setMarketParameters -FNDA:796,SwanManager.setMarketParameters -DA:82,202 -BRDA:82,0,0,1 -BRDA:82,0,1,201 +DA:74,6 +DA:80,872 +FN:80,SwanManager.setMarketParameters +FNDA:872,SwanManager.setMarketParameters +DA:81,202 +BRDA:81,0,0,1 +BRDA:81,0,1,201 +DA:82,201 DA:83,201 -DA:84,201 -DA:90,658 -FN:90,SwanManager.setOracleParameters -FNDA:658,SwanManager.setOracleParameters -DA:91,1 -DA:96,1 -FN:96,SwanManager.getOracleFee +DA:89,654 +FN:89,SwanManager.setOracleParameters +FNDA:654,SwanManager.setOracleParameters +DA:90,1 +DA:95,1 +FN:95,SwanManager.getOracleFee FNDA:1,SwanManager.getOracleFee +DA:96,1 DA:97,1 -DA:98,1 -DA:109,584 -FN:109,SwanManager.addOperator -FNDA:584,SwanManager.addOperator -DA:110,0 -DA:117,665 -FN:117,SwanManager.removeOperator -FNDA:665,SwanManager.removeOperator -DA:118,0 -DA:123,1366 -FN:123,SwanManager.getCurrentMarketParameters +DA:108,569 +FN:108,SwanManager.addOperator +FNDA:569,SwanManager.addOperator +DA:109,0 +DA:116,654 +FN:116,SwanManager.removeOperator +FNDA:654,SwanManager.removeOperator +DA:117,0 +DA:122,1366 +FN:122,SwanManager.getCurrentMarketParameters FNDA:1366,SwanManager.getCurrentMarketParameters -DA:124,1828 +DA:123,1828 FNF:9 FNH:9 LF:21 diff --git a/storage.sh b/storage.sh old mode 100644 new mode 100755 index cfe6a75..2637c5b --- a/storage.sh +++ b/storage.sh @@ -1,12 +1,13 @@ #!/bin/bash OUTPUT_PATH=${1:-storage} -EXCLUDE="test|mock|script" +EXCLUDE="test|mock|script|" +# FIXME: what does IFS do here? IFS=$'\n' CONTRACT_FILES=($(find ./src -type f)) unset IFS -echo "Generating layouts in $OUTPUT_PATH" +echo "Outputting storage layouts to: $OUTPUT_PATH" mkdir -p $OUTPUT_PATH for file in "${CONTRACT_FILES[@]}"; @@ -16,6 +17,6 @@ do fi contract=$(basename "$file" .sol) - echo "Generating storage layout of $contract" + echo "Generating storage layout for: $contract" forge inspect "$contract" storage --pretty > "$OUTPUT_PATH/$contract.md" -done \ No newline at end of file +done From 4fabf2e48a6c333cded31802397b8aacf885f526 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 17:35:53 +0300 Subject: [PATCH 7/8] update contract docs --- docs/src/README.md | 120 +++++++++++------- docs/src/src/Swan.sol/constants.Swan.md | 2 +- docs/src/src/Swan.sol/contract.Swan.md | 2 +- .../src/SwanAgent.sol/contract.SwanAgent.md | 2 +- .../contract.SwanAgentFactory.md | 2 +- .../SwanArtifact.sol/contract.SwanArtifact.md | 2 +- .../contract.SwanArtifactFactory.md | 2 +- .../SwanManager.sol/abstract.SwanManager.md | 2 +- .../struct.SwanMarketParameters.md | 2 +- 9 files changed, 79 insertions(+), 57 deletions(-) diff --git a/docs/src/README.md b/docs/src/README.md index 88f7afe..3b6252c 100644 --- a/docs/src/README.md +++ b/docs/src/README.md @@ -35,7 +35,7 @@ First, make sure you have the requirements: Clone the repository: ```sh -git clone git@github.com:firstbatchxyz/swan-contracts.git +git clone git@github.com:firstbatchxyz/dria-oracle-contracts.git ``` Install dependencies with: @@ -52,11 +52,13 @@ forge clean && forge build ### Upgradability -We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library. To make sure upgrades are **safe**, you must do one of the following before you run `forge script` or `forge test` (as per their [docs](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running)): +We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library. To make sure upgrades are **safe**, you must do one of the following (as per their [docs](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running)) before you run `forge script` or `forge test`: - `forge clean` beforehand, e.g. `forge clean && forge test` - include `--force` option when running, e.g. `forge test --force` +> [!NOTE] +> > Note that for some users this may fail (see [issue](https://github.com/firstbatchxyz/dria-oracle-contracts/issues/16)) due to a missing NPM package called `@openzeppelin/upgrades-core`. To fix it, do: > > ```sh @@ -71,67 +73,89 @@ To update contracts to the latest library versions, use: forge update ``` -## Deployment +## Usage -**Step 1.** -Import your `ETHERSCAN_API_KEY` to env file. +### Setup -> [!NOTE] -> -> Foundry expects the API key to be defined as `ETHERSCAN_API_KEY` even though you're using another explorer. +To be able to deploy & use our contracts, we need two things: + +- [Ethereum Wallet](#create-wallet) +- [RPC endpoint](#prepare-rpc-endpoint) -**Step 2.** -Create keystores for deployment. [See more for keystores](https://eips.ethereum.org/EIPS/eip-2335) +### Create Wallet + +We use keystores for wallet management, with the help of [`cast wallet`](https://book.getfoundry.sh/reference/cast/wallet-commands) command. + +Use the command below to create your keystore. The command will prompt for your **private key**, and a **password** to encrypt the keystore itself. ```sh -cast wallet import --interactive +cast wallet import --interactive ``` -You can see your wallets with: +> [!ALERT] +> +> Note that you will need to enter the password when you use this keystore. + +You can see your keystores under the default directory (`~/.foundry/keystores`) with the command: ```sh cast wallet list ``` -> [!NOTE] -> -> Recommended to create keystores on directly on your shell. -> You HAVE to type your password on the terminal to be able to use your keys. (e.g when deploying a contract) +### Prepare RPC Endpoint -**Step 3.** -Enter your private key (associated with your address) and password on terminal. You'll see your address on terminal. +To interact with the blockchain, we require an RPC endpoint. You can get one from: -> [!NOTE] -> -> If you want to deploy contracts on localhost please provide local address for the command above. +- [Alchemy](https://www.alchemy.com/) +- [Infura](https://www.infura.io/) +- [(see more)](https://www.alchemy.com/best/rpc-node-providers) + +You will use this endpoint for the commands that interact with the blockchain, such as deploying and upgrading; or while doing fork tests. + +### Deploy & Verify Contract -**Step 4.** Deploy the contract with: ```sh -forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast +forge clean && forge script ./script/Deploy.s.sol:Deploy \ +--rpc-url \ +--account \ +--broadcast ``` -or for instant verification use: +You can see deployed contract addresses under the `deployment/.json` + +You can verify the contract during deployment by adding the verification arguments as well: ```sh -forge clean && forge script ./script/Deploy.s.sol:Deploy --rpc-url --account --sender --broadcast --verify --verifier --verifier-url +forge clean && forge script ./script/Deploy.s.sol:Deploy \ +--rpc-url \ +--account \ +--broadcast \ +--verify --verifier blockscout \ +--verifier-url ``` -> [!NOTE] > `` should be expolorer's homepage url. Forge reads your `` from .env file so you don't need to add this at the end of ``. -> -> e.g. -> `https://base-sepolia.blockscout.com/api/` for `Base Sepolia Network` +You can verify an existing contract with: -You can see deployed contract addresses under the `deployment/.json` +```sh +forge verify-contract ./src/.sol: \ +--verifier blockscout \ +--verifier-url +``` -## Verify Contract +Note that the `--verifier-url` value should be the target explorer's homepage URL. Some example URLs are: -Verify contract manually with: +- `https://base.blockscout.com/api/` for Base (Mainnet) +- `https://base-sepolia.blockscout.com/api/` for Base Sepolia (Testnet) -```sh -forge verify-contract src/$.sol: --verifier --verifier-url -``` +> [!NOTE] +> +> URL should not contain the API key! Foundry will read your `ETHERSCAN_API_KEY` from environment. + +> [!NOTE] +> +> The `--verifier` can accept any of the following: `etherscan`, `blockscout`, `sourcify`, `oklink`. We are using Blockscout most of the time. ## Testing & Diagnostics @@ -139,6 +163,9 @@ Run tests on local network: ```sh forge clean && forge test + +# or -vvv to show reverts in detail +forge clean && forge test -vvv ``` or fork an existing chain and run the tests on it: @@ -147,31 +174,29 @@ or fork an existing chain and run the tests on it: forge clean && forge test --rpc-url ``` -### Coverage +### Code Coverage -Check coverages with: +We have a script that generates the coverage information as an HTML page. This script requires [`lcov`](https://linux.die.net/man/1/lcov) and [`genhtml`](https://linux.die.net/man/1/genhtml) command line tools. To run, do: ```sh -forge clean && bash coverage.sh +forge clean && ./coverage.sh ``` -or to see summarized coverages on terminal: +Alternatively, you can see a summarized text-only output as well: ```sh forge clean && forge coverage --no-match-coverage "(test|mock|script)" ``` -You can see coverages under the coverage directory. - ### Storage Layout Get storage layout with: ```sh -forge clean && bash storage.sh +./storage.sh ``` -You can see storage layouts under the storage directory. +You can see storage layouts under the [`storage`](./storage/) directory. ### Gas Snapshot @@ -185,16 +210,13 @@ You can see the snapshot `.gas-snapshot` file in the current directory. ## Documentation -We have auto-generated documentation under the [`docs`](./docs) folder, generated with the following command: +We have auto-generated MDBook documentations under the [`docs`](./docs) folder, generated with the following command: ```sh forge doc -``` -We provide an MDBook template over it, which you can open via: - -```sh -cd docs && mdbook serve --open +# serves the book as well +forge doc --serve ``` ## License diff --git a/docs/src/src/Swan.sol/constants.Swan.md b/docs/src/src/Swan.sol/constants.Swan.md index 2fbe3a3..2c07fa3 100644 --- a/docs/src/src/Swan.sol/constants.Swan.md +++ b/docs/src/src/Swan.sol/constants.Swan.md @@ -1,5 +1,5 @@ # Constants -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/Swan.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/Swan.sol) ### SwanAgentPurchaseOracleProtocol *Protocol string for Swan Purchase CRONs, checked in the Oracle.* diff --git a/docs/src/src/Swan.sol/contract.Swan.md b/docs/src/src/Swan.sol/contract.Swan.md index 1c97fa6..a8f7fba 100644 --- a/docs/src/src/Swan.sol/contract.Swan.md +++ b/docs/src/src/Swan.sol/contract.Swan.md @@ -1,5 +1,5 @@ # Swan -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/Swan.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/Swan.sol) **Inherits:** [SwanManager](/src/SwanManager.sol/abstract.SwanManager.md), UUPSUpgradeable diff --git a/docs/src/src/SwanAgent.sol/contract.SwanAgent.md b/docs/src/src/SwanAgent.sol/contract.SwanAgent.md index 17b1eba..344ad85 100644 --- a/docs/src/src/SwanAgent.sol/contract.SwanAgent.md +++ b/docs/src/src/SwanAgent.sol/contract.SwanAgent.md @@ -1,5 +1,5 @@ # SwanAgent -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanAgent.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/SwanAgent.sol) **Inherits:** Ownable diff --git a/docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md b/docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md index 5a5621f..7b614c6 100644 --- a/docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md +++ b/docs/src/src/SwanAgent.sol/contract.SwanAgentFactory.md @@ -1,5 +1,5 @@ # SwanAgentFactory -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanAgent.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/SwanAgent.sol) Factory contract to deploy Agent contracts. diff --git a/docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md b/docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md index 86f8551..881dbfc 100644 --- a/docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md +++ b/docs/src/src/SwanArtifact.sol/contract.SwanArtifact.md @@ -1,5 +1,5 @@ # SwanArtifact -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanArtifact.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/SwanArtifact.sol) **Inherits:** ERC721, Ownable diff --git a/docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md b/docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md index ce0db66..21c8c98 100644 --- a/docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md +++ b/docs/src/src/SwanArtifact.sol/contract.SwanArtifactFactory.md @@ -1,5 +1,5 @@ # SwanArtifactFactory -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanArtifact.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/SwanArtifact.sol) Factory contract to deploy Artifact tokens. diff --git a/docs/src/src/SwanManager.sol/abstract.SwanManager.md b/docs/src/src/SwanManager.sol/abstract.SwanManager.md index f7b1f23..3e67e6d 100644 --- a/docs/src/src/SwanManager.sol/abstract.SwanManager.md +++ b/docs/src/src/SwanManager.sol/abstract.SwanManager.md @@ -1,5 +1,5 @@ # SwanManager -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanManager.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/SwanManager.sol) **Inherits:** OwnableUpgradeable diff --git a/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md b/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md index 903d2a9..b5f3273 100644 --- a/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md +++ b/docs/src/src/SwanManager.sol/struct.SwanMarketParameters.md @@ -1,5 +1,5 @@ # SwanMarketParameters -[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/d7951743b0ff97c2f6e978aeabb850c0310d76f3/src/SwanManager.sol) +[Git Source](https://github.com/firstbatchxyz/swan-contracts/blob/24e0365940f0434545a9c39573dfdf6b9975fc88/src/SwanManager.sol) Collection of market-related parameters. From ea3c9682f9f07473093800ae1beac8af0028a4ee Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 18 Dec 2024 17:43:20 +0300 Subject: [PATCH 8/8] update swan --- deployment/84532.json | 22 ++++++++++------------ script/Deploy.s.sol | 22 ---------------------- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/deployment/84532.json b/deployment/84532.json index 656339a..66a943e 100644 --- a/deployment/84532.json +++ b/deployment/84532.json @@ -1,22 +1,20 @@ { "LLMOracleRegistry": { - "proxyAddr": "0xbb2180ebd78ce97360503434ed37fcf4a1df61c3", - "implAddr": "0xa8452ec99ce0c64f20701db7dd3abdb607c00496" + "proxyAddr": "0x408d245A853137e44A2465D5C66061f97582eae9", + "implAddr": "0x17b183f44eF3062eED2EdeE4578f3ce749F32e5E" }, "LLMOracleCoordinator": { - "proxyAddr": "0x50eef481cae4250d252ae577a09bf514f224c6c4", - "implAddr": "0xdb8cff278adccf9e9b5da745b44e754fc4ee3c76" + "proxyAddr": "0x13F977BdE221B470D3ae055cde7E1F84DEBFe202", + "implAddr": "0x71dEE43753227298727d78225977925012873B45" }, "Swan": { - "proxyAddr": "0xdeb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", - "implAddr": "0x62c20aa1e0272312bc100b4e23b4dc1ed96dd7d1" + "proxyAddr": "0x98871ebf85184d80caba6ec681d04765efc24ae4", + "implAddr": "0x2fa2446dc2dcc805e1cf7d433413ca96c130ee42" }, - "BuyerAgentFactory": "0xc48af3ef03d91af34b891688ade004ad36c8c39a", - "SwanAssetFactory": "0xebb2c54b2a20e0e25b2fb168c8a657e1c966911f", - "AIAgentFactory": { - "addr": "0x34a1d3fff3958843c43ad80f30b94c510645c316" + "SwanAgentFactory": { + "addr": "0x0baac4a81d52da48c0987854bc68cf8ba5a63050" }, - "ArtifactFactory": { - "addr": "0x90193c961a926261b756d1e5bb255e67ff9498a1" + "SwanArtifactFactory": { + "addr": "0x49347ff2c7b5031d79af7ef7106afb9662ff2d12" } } \ No newline at end of file diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 5d9c48d..90ff36b 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -7,32 +7,10 @@ import {Script} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; import {HelperConfig} from "./HelperConfig.s.sol"; -import {LLMOracleRegistry} from "@firstbatch/dria-oracle-contracts/LLMOracleRegistry.sol"; -import { - LLMOracleCoordinator, LLMOracleTaskParameters -} from "@firstbatch/dria-oracle-contracts/LLMOracleCoordinator.sol"; import {SwanAgentFactory} from "../src/SwanAgent.sol"; import {SwanArtifactFactory} from "../src/SwanArtifact.sol"; import {Swan, SwanMarketParameters} from "../src/Swan.sol"; -contract DeployLLMOracleRegistry is Script { - HelperConfig public config; - - function run() external returns (address proxy, address impl) { - config = new HelperConfig(); - (proxy, impl) = config.deployLLMOracleRegistry(); - } -} - -contract DeployLLMOracleCoordinator is Script { - HelperConfig public config; - - function run() external returns (address proxy, address impl) { - config = new HelperConfig(); - (proxy, impl) = config.deployLLMOracleCoordinator(); - } -} - contract DeploySwanAgentFactory is Script { HelperConfig public config;