{"id":24418802,"url":"https://github.com/firstbatchxyz/swan-contracts","last_synced_at":"2026-05-19T01:39:53.671Z","repository":{"id":268904404,"uuid":"890219963","full_name":"firstbatchxyz/swan-contracts","owner":"firstbatchxyz","description":"Simulated Worlds with AI Narratives","archived":false,"fork":false,"pushed_at":"2025-03-12T16:03:23.000Z","size":645,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-12T17:20:03.280Z","etag":null,"topics":["agents","foundry","oracle","solidity"],"latest_commit_sha":null,"homepage":"https://swan.my/","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/firstbatchxyz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audits/CodeHawks-28-11-2024.pdf","citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-18T07:44:47.000Z","updated_at":"2025-03-03T07:14:36.000Z","dependencies_parsed_at":"2025-01-27T22:26:23.837Z","dependency_job_id":"e0593113-29b4-4d8b-bbab-dd43bf38c622","html_url":"https://github.com/firstbatchxyz/swan-contracts","commit_stats":null,"previous_names":["firstbatchxyz/swan-contracts"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fswan-contracts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fswan-contracts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fswan-contracts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fswan-contracts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/firstbatchxyz","download_url":"https://codeload.github.com/firstbatchxyz/swan-contracts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243410723,"owners_count":20286474,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","foundry","oracle","solidity"],"created_at":"2025-01-20T09:13:51.546Z","updated_at":"2026-05-19T01:39:53.657Z","avatar_url":"https://github.com/firstbatchxyz.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/firstbatchxyz/.github/refs/heads/master/branding/swan-logo-square.svg\" alt=\"logo\" width=\"168\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ch1 align=\"center\"\u003e\n    Swan Protocol\n  \u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ci\u003eSimulated Worlds with AI Narratives.\u003c/i\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://opensource.org/licenses/Apache-2-0\" target=\"_blank\"\u003e\n        \u003cimg alt=\"License: Apache 2.0\" src=\"https://img.shields.io/badge/license-Apache_2.0-7CB9E8.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"./.github/workflows/test.yml\" target=\"_blank\"\u003e\n        \u003cimg alt=\"Workflow: Tests\" src=\"https://github.com/firstbatchxyz/dria-oracle-contracts/actions/workflows/test.yml/badge.svg?branch=master\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://discord.gg/dria\" target=\"_blank\"\u003e\n        \u003cimg alt=\"Discord\" src=\"https://dcbadge.vercel.app/api/server/dria?style=flat\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n## Installation\n\nFirst, make sure you have the requirements:\n\n- We are using [Foundry](https://book.getfoundry.sh/), so make sure you [install](https://book.getfoundry.sh/getting-started/installation) it first.\n- Upgradable contracts make use of [NodeJS](https://nodejs.org/en), so you should [install](https://nodejs.org/en/download/package-manager) that as well.\n\nClone the repository:\n\n```sh\ngit clone git@github.com:firstbatchxyz/dria-oracle-contracts.git\n```\n\nInstall dependencies with:\n\n```sh\nforge install\n```\n\nCompile the contracts with:\n\n```sh\nforge build\n```\n\n\u003e [!NOTE]\n\u003e\n\u003e We are using [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) library, which [requires](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#before-running) clean-up per compilation to ensure upgrades are done safely. We use `force = true` option in `foundry.toml` for this, which may increase build times.\n\u003e\n\u003e 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, you can install the package manually:\n\u003e\n\u003e ```sh\n\u003e npm install @openzeppelin/upgrades-core@latest -g\n\u003e ```\n\n\u003e [!TIP]\n\u003e\n\u003e If at any point the submodules become \"dirty\" (e.g. there are local changes that you are unaware of) you can do:\n\u003e\n\u003e ```sh\n\u003e git submodule deinit -f .\n\u003e git submodule update --init --recursive --checkout\n\u003e ```\n\n### Updates\n\nTo update contracts to the latest library versions, use:\n\n```sh\nforge update\n```\n\n## Usage\n\n### Setup\n\nTo be able to deploy \u0026 use our contracts, we need two things:\n\n- [Ethereum Wallet](#create-wallet)\n- [RPC endpoint](#prepare-rpc-endpoint)\n\n### Create Wallet\n\nWe use keystores for wallet management, with the help of [`cast wallet`](https://book.getfoundry.sh/reference/cast/wallet-commands) command.\n\nUse the command below to create your keystore. The command will prompt for your **private key**, and a **password** to encrypt the keystore itself.\n\n```sh\ncast wallet import \u003cWALLET_NAME\u003e --interactive\n```\n\n\u003e [!WARNING]\n\u003e\n\u003e Note that you will need to enter the password when you use this keystore.\n\nYou can see your keystores under the default directory (`~/.foundry/keystores`) with the command:\n\n```sh\ncast wallet list\n```\n\n### Prepare RPC Endpoint\n\nTo interact with the blockchain, we require an RPC endpoint. You can get one from:\n\n- [Alchemy](https://www.alchemy.com/)\n- [Infura](https://www.infura.io/)\n- [(see more)](https://www.alchemy.com/best/rpc-node-providers)\n\nYou will use this endpoint for the commands that interact with the blockchain, such as deploying and upgrading; or while doing fork tests.\n\n### Deploy Contract\n\nDeploy the contract with:\n\n```sh\nforge script ./script/Deploy.s.sol:Deploy\u003cCONTRACT_NAME\u003e \\\n--rpc-url \u003cRPC_URL\u003e \\\n--account \u003cWALLET_NAME\u003e \\\n--broadcast\n```\n\nYou can see deployed contract addresses under the [`deployments/\u003cchainid\u003e.json`](./deployments/) folder.\n\nYou will need the contract ABIs to interact with them as well, thankfully there is a nice short-hand command to export that:\n\n```sh\nforge inspect \u003cCONTRACT_NAME\u003e abi \u003e ./deployments/abis/\u003cCONTRACT_NAME\u003e.json\n```\n\n### Verify Contract\n\nVerification requires the following values, based on which provider you are using:\n\n- **Provider**: can accept any of `etherscan`, `blockscout`, `sourcify`, `oklink` or `custom` for more fine-grained stuff.\n- **URL**: based on the chosen provider, its URL, e.g. `https://base-sepolia.blockscout.com/api/` for `blockscout` on Base Sepolia\n- **API Key**: an API key from the chosen provider, must be stored as `ETHERSCAN_API_KEY` in environment no matter whicih provider it is!.\n\nYou can actually verify the contract during deployment by adding the verification arguments as well:\n\n```sh\nforge script ./script/Deploy.s.sol:Deploy\u003cCONTRACT_NAME\u003e \\\n--rpc-url \u003cRPC_URL\u003e \\\n--account \u003cWALLET_NAME\u003e \\\n--broadcast \\\n--verify --verifier blockscout \\\n--verifier-url \u003cVERIFIER_URL\u003e \\\n--chain-id 8453\n```\n\nAlternatively, you can verify an existing contract (perhaps deployed from a factory) with the following command:\n\n```sh\nforge verify-contract \u003cCONTRACT_ADDRESS\u003e ./src/\u003cCONTRACT_NAME\u003e.sol:\u003cCONTRACT_NAME\u003e \\\n--verifier blockscout --verifier-url \u003cVERIFIER_URL\u003e \\\n--etherscan-api-key \u003cAPI_KEY\u003e --chain-id 8453\n```\n\nThe chain ID is 8453 for Base Mainnet, and 84532 for Base Sepolia.\n\n### Upgrade Contract\n\n#### Using single-sig wallet\nUpgrading an existing contract is done as per the instructions in [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) repository.\n\nFirst, we create a new contract with its name as `ContractNameV2`, and then we execute the following command:\n\n```sh\nforge script ./script/Deploy.s.sol:Upgrade\u003cCONTRACT_NAME\u003e \\\n--rpc-url \u003cRPC_URL\u003e \\\n--account \u003cWALLET_NAME\u003e --broadcast \\\n--sender \u003cWALLET_ADDRESS\u003e \\\n--verify --verifier blockscout \\\n--verifier-url \u003cVERIFIER_URL\u003e\n```\n\n\u003e [!NOTE]\n\u003e\n\u003e The `--sender \u003cADDRESS\u003e` field is mandatory when deploying a contract, it can be obtained with the command below, which will prompt for keystore password:\n\u003e\n\u003e ```sh\n\u003e cast wallet address --account \u003cWALLET_NAME\u003e\n\u003e ```\n\n#### Using multisig wallet (Our currrent approach with Gnosis Safe multisig)\n\nTo upgrade your Swan UUPS contract via a Gnosis multisig, follow these steps:\n\n1. **Deploy the new implementation contract**\n   Execute the deployment script to get the new implementation address:\n\n   ```sh\n   forge script ./script/Deploy.s.sol:DeploySwanImpl \\\n   --rpc-url \u003cRPC_URL\u003e \\\n   --account \u003cWALLET_NAME\u003e --broadcast \\\n   --sender \u003cWALLET_ADDRESS\u003e \\\n   --verify --verifier blockscout \\\n   --verifier-url \u003cVERIFIER_URL\u003e\n   ```\n\n2. **Generate upgrade calldata**\n\n   Once you have the new implementation address, generate the calldata for the Gnosis multisig:\n\n   ```sh\n   cast calldata \"upgradeToAndCall(address,bytes)\" 0xNewImplementationAddress 0x\n   ```\n\n   This will output something like:\n   ```\n      0x4f1ef28600000000000000000000000017b6d1eddcd5f9ca19bb2ffed2f3deb6bd74bd2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000\n   ```\n\n3. **Submit transaction to Gnosis Safe**\n\n   Create a new transaction in the Gnosis Safe interface with:\n   - **To**: Your Swan proxy address\n   - **Value**: 0 ETH\n   - **Data**: The calldata generated in step 2\n\n4. **Execute the transaction**\n\n   Have the required signers approve the transaction, then execute it to complete the upgrade.\n\n## Testing \u0026 Diagnostics\n\nRun tests on local network:\n\n```sh\nFOUNDRY_PROFILE=test forge test\n\n# or -vvv to show reverts in detail\nFOUNDRY_PROFILE=test forge test -vvv\n```\n\nor fork an existing chain and run the tests on it:\n\n```sh\nFOUNDRY_PROFILE=test forge test --rpc-url \u003cRPC_URL\u003e\n```\n\n### Code Coverage\n\nWe 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:\n\n```sh\n./coverage.sh\n```\n\nAlternatively, you can see a summarized text-only output as well:\n\n```sh\nforge coverage --no-match-coverage \"(test|mock|script)\"\n```\n\n### Gas Snapshot\n\nYou can examine the gas usage metrics using the command:\n\n```sh\nFOUNDRY_PROFILE=test forge snapshot --snap ./test/.gas-snapshot\n```\n\nYou can see the snapshot `.gas-snapshot` file in the current directory.\n\n### Styling\n\nYou can format the contracts with:\n\n```sh\nforge fmt ./src/**/*.sol ./script/**/*.sol\n```\n\nIf you have solhint installed, you can lint all contracts with:\n\n```sh\nsolhint 'src/**/*.sol' 'script/**/*.sol'\n```\n\n## Documentation\n\nWe have auto-generated MDBook documentations under the [`docs`](./docs) folder, generated with the following command:\n\n```sh\nforge doc\n\n# serves the book as well\nforge doc --serve\n```\n\n## License\n\nWe are using [Apache-2.0](./LICENSE) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirstbatchxyz%2Fswan-contracts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffirstbatchxyz%2Fswan-contracts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirstbatchxyz%2Fswan-contracts/lists"}