{"id":21850498,"url":"https://github.com/circlefin/perimeter-protocol","last_synced_at":"2025-07-24T00:37:57.120Z","repository":{"id":197244799,"uuid":"531906143","full_name":"circlefin/perimeter-protocol","owner":"circlefin","description":"Official repository for the Perimeter Protocol","archived":false,"fork":false,"pushed_at":"2024-06-28T22:36:26.000Z","size":2386,"stargazers_count":67,"open_issues_count":7,"forks_count":20,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-06T21:42:09.164Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/circlefin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audit/ChainSecurity_Circle_Perimeter_audit.pdf","citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-02T11:55:04.000Z","updated_at":"2025-04-06T04:02:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"90543f26-8f20-4427-b132-fdb0d3b5e4e4","html_url":"https://github.com/circlefin/perimeter-protocol","commit_stats":null,"previous_names":["circlefin/perimeter-protocol"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/circlefin/perimeter-protocol","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fperimeter-protocol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fperimeter-protocol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fperimeter-protocol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fperimeter-protocol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/circlefin","download_url":"https://codeload.github.com/circlefin/perimeter-protocol/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fperimeter-protocol/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266774799,"owners_count":23982247,"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","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-28T00:17:49.325Z","updated_at":"2025-07-24T00:37:57.095Z","avatar_url":"https://github.com/circlefin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Perimeter Protocol\n\nThis repository contains an audited, open-source reference implementation for the Perimeter Protocol that anyone can freely use to build unique credit applications using USDC.\n\n## About Perimeter\n\nA project by [Circle Research](https://www.circle.com/en/circle-research), Perimeter offers several important features, such as the ability to delegate loan management and monitoring, integration with [open identity standards](https://www.circle.com/en/verite), and the flexibility to accommodate different types of credit instruments. Perimeter stands out for not relying on a protocol token and its adaptability to various scenarios. Please read more about Perimeter [in the whitepaper](https://www.circle.com/hubfs/Circle%20Research/Whitepapers/Perimeter_Protocol_Circle_Research.pdf).\n\nPlease note: Perimeter Protocol is a Proof-of-Concept by Circle Research and is provided “as-is” as an open-source contribution. As a research project, it has not been productionized nor does Circle have intentions to productionize it. Anyone using or extending Perimeter Protocol does so at their own risk, and should carefully consider whether additional security audits, reviews, or testing are needed before production use.\n\n## Smart Contract Architecture\n\nPerimeter consists of a number of smart contracts including lending pools, loan constructs, and permissioning helpers.\n\n![](./img/smart_contract_architecture.png)\n\n- Protocol participants include protocol administrators, Pool Admins, Borrowers, and Lenders.\n\n- Global protocol administrative roles (`Admin`, `Pauser`, `Deployer`, `Operator`) are defined through the singleton `ServiceConfiguration` contract.\n\n- PoolAdmins create [ERC-4626](https://eips.ethereum.org/EIPS/eip-4626) compliant lending pools through a `PoolFactory`. Pools manage the accounting related to deposits, withdrawals, loan funding, loan payments, and defaults.\n\n- Borrowers create loans through a `LoanFactory`, which are tied to a pool. Each loan is self-contained, with its own lifecycle and maturation process according to its unique schedule and terms. Both open and fixed-term loans are available.\n\n- Lenders deposit into pools to receive pool tokens at an exchange rate determined by the Pool and based on the Pool's current Net Asset Value (NAV). The NAV is computed based on the available liquidity, liquidity outstanding (deployed to loans), and expected interest at that given block.\n\nThe Perimeter architecture was designed with modularity in mind, allowing new `PoolFactory` and `LoanFactory` instances to be attached to the protocol through the global `ServiceConfiguration`, potentially creating Pools and Loans with new features.\n\n### Upgradeability\n\nPerimeter allows upgrades to be performed unilaterally by the global `Deployer` role. The following contracts are upgradeable by the `Deployer`:\n\n- \"Singleton\" contracts like the `ServiceConfiguration`, `PoolAdminAccessControl`, and `ToSAcceptance` can be individually upgraded in-place through the [UUPS](https://docs.openzeppelin.com/contracts/4.x/api/proxy#transparent-vs-uups) pattern.\n\n- The \"1-to-N\" contracts emitted by factories (`Pool`, `Loan`, `WithdrawController`, `Vault`, `PoolController`) are implemented as Beacon proxies, allowing a single transaction to update an implementation across all proxies simultaneously.\n\n### Permissioning\n\nAs noted in the diagram, there are several layers of permissioning, which utilize a combination of [Verite](https://www.circle.com/en/verite)-based, privacy-preserving, decentralized identity credentials and standard allowlists, allowing Pool Admins to determine the appropriate permissioning strategy for their pools.\n\nSpecifically, for handling identity credentials, Perimeter follows a verifier pattern, in which trusted verifiers are registered with the protocol and can attest to verifying the privacy-preserving credentials off-chain. This verification result is then recorded on-chain, granting access for a period of time.\n\nPerimeter applies permissioning in several places:\n\n- Permissioning which accounts can create new Pools. This is gated through the `PoolAdminAccessControl`, a singleton contract which maintains a registry of Verite credential attestations for Pool Admins. The specific allowed credential schemas and trusted verifiers can be configured through the protocol `Operator`. Additionally, consenting to the protocol-wide Terms of Service is required, managed through the `ToSAcceptanceRegistry`.\n\n- Permissioning lender access to Pools: a flexible `PoolAccessControl` contract allows individual Pool Admins to specify either a credential-based approach to permissioning or an allow list-based approach (or both) for their given Pool. Prior to enabling access, lenders must first mark their consent to the `ToSAcceptanceRegistry`.\n\n## Getting started\n\nPerimeter is written as a basic [Hardhat](https://hardhat.org/) project. To get started, install the dependencies:\n\n```sh\nnpm install\n```\n\nCopy .env.example and update with appropriate values:\n\n```sh\ncp .env.example .env\n```\n\n## Running a localhost node\n\nFor local dev, it's helpful to test scripts against a network running locally.\n\n```sh\nnpx hardhat node\nnpx hardhat run scripts/deploy.ts\n```\n\n## Generating Docs\n\nDocumentation is generated by [solidity-docgen](https://github.com/OpenZeppelin/solidity-docgen)\n\n```sh\nnpm run docs\n\n# or\n\nnpx hardhat docgen\n```\n\n## Testing\n\n```sh\nnpm test\n\n# or\n\nnpx hardhat test\n```\n\n### Gas usage reports\n\n```sh\nnpm run test:gas\n\n# or\n\nREPORT_GAS=true npx hardhat test\n```\n\n### Code Coverage\n\n```sh\nnpm run test:coverage\n\n# or\n\nnpx hardhat coverage\n```\n\n## Hardhat Tasks\n\nThere are several hardhat tasks to allow for easy modification of the contracts.\n\nUpdating the ServiceConfiguration:\n\n- setPaused\n- setLiquidityAsset\n- setLoanFactory\n- setTosAcceptanceRegistry\n\nYou can find complete instructions for how to run each command by running the following:\n\n```sh\nnpx hardhat setPaused --help\n```\n\nHere is an example command to pause a hypothetical contract:\n\n```sh\nnpx hardhat setPaused --address 0x869076ca72531B5474F9182d735a3e3F2e365fc6 --paused true\n```\n\n## Getting a Verite Verification Result\n\nUpdate the config in `scripts/verite-verify.ts` with the appropriate values, then run\n\n```sh\nnpx hardhat run scripts/verite-verify.ts\n```\n\nThis will print out a verification result that can be send to the `verify()` method on the given contract.\n\n## Etherscan Verification\n\nContract source can be uploaded and verified to Etherscan. Update `.env` to include your Etherscan API key.\n\nFor each deployed contract, run the following:\n\n```\nnpx hardhat verify --network goerli CONTRACT_ADDRESS\n```\n\nThere are three contracts that require constructor arguments:\n\n- WithdrawControllerFactory\n- PoolControllerFactory\n- PoolFactory\n\n```\nnpx hardhat verify --network goerli CONTRACT_ADDRESS arg1 arg2 arg3\n```\n\n## Deployment\n\nThere are several deployment scripts available (see `scripts/deploy.ts`). These require a number of values to be set in an `.env` file in the root of the repository.\n\n## Contributing\n\nWe welcome contributions, bug fixes, and feature suggestions to Perimeter. Please open an issue or a pull request with your ideas!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fperimeter-protocol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcirclefin%2Fperimeter-protocol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fperimeter-protocol/lists"}