{"id":19107550,"url":"https://github.com/smartcontractkit/ccip-liquidation-protector","last_synced_at":"2025-09-08T06:30:51.734Z","repository":{"id":182282100,"uuid":"665354472","full_name":"smartcontractkit/ccip-liquidation-protector","owner":"smartcontractkit","description":"This project demonstrates how to automate preventing DeFi liquidations \u0026 optimizing interest rates on multiple blockchains using Chainlink CCIP, Chainlink Automation and Chainlink Functions","archived":false,"fork":false,"pushed_at":"2023-07-20T10:07:43.000Z","size":1867,"stargazers_count":10,"open_issues_count":1,"forks_count":5,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-11-09T04:12:57.127Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smartcontractkit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-07-12T03:01:13.000Z","updated_at":"2024-10-30T06:33:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"fb36e322-7f88-4ae9-9b1e-a83e1c8c57ee","html_url":"https://github.com/smartcontractkit/ccip-liquidation-protector","commit_stats":null,"previous_names":["smartcontractkit/ccip-liquidation-protector"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-liquidation-protector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-liquidation-protector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-liquidation-protector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-liquidation-protector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smartcontractkit","download_url":"https://codeload.github.com/smartcontractkit/ccip-liquidation-protector/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232282926,"owners_count":18499331,"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":[],"created_at":"2024-11-09T04:12:58.928Z","updated_at":"2025-01-03T03:13:49.249Z","avatar_url":"https://github.com/smartcontractkit.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CCIP Liquidation Protector\n\n\u003e **Note**\n\u003e\n\u003e _This repository represents an example of using a Chainlink product or service. It is provided to help you understand how to interact with Chainlink’s systems so that you can integrate them into your own. This template is provided \"AS IS\" without warranties of any kind, has not been audited, and may be missing key checks or error handling to make the usage of the product more clear. Take everything in this repository as an example and not something to be copy pasted into a production ready service._\n\nThis project demonstrates how to automate preventing DeFi liquidations \u0026 optimizing interest rates on multiple blockchains using Chainlink CCIP, Chainlink Automation and Chainlink Functions.\n\n## Prerequisites\n\n- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)\n- [Current LTS Node.js version](https://nodejs.org/en/about/releases/)\n\nVerify installation by typing:\n\n```shell\nnode -v\n```\n\nand\n\n```shell\nnpm -v\n```\n\n## Getting Started\n\n1. Install packages\n\n```\nnpm install\n```\n\n2. Compile contracts\n\n```\nnpx hardhat compile\n```\n\n## What is Chainlink CCIP?\n\n**Chainlink Cross-Chain Interoperability Protocol (CCIP)** provides a single, simple, and elegant interface through which dApps and web3 entrepreneurs can securely meet all their cross-chain needs, including token transfers and arbitrary messaging.\n\n![basic-architecture](./img/basic-architecture.png)\n\nWith Chainlink CCIP, one can:\n\n- Transfer supported tokens\n- Send messages (any data)\n- Send messages and tokens\n\nCCIP receiver can be:\n\n- Smart contract that implements `CCIPReceiver.sol`\n- EOA\n\n**Note**: If you send a message and token(s) to EOA, only tokens will arrive\n\nTo use this project, you can consider CCIP as a \"black-box\" component and be aware of the Router contract only. If you want to dive deep into it, check the [Official Chainlink Documentation](https://docs.chain.link/ccip).\n\n## What are we building?\n\nManaging multiple DeFi positions is hard. Managing multiple DeFi positions on multiple protocols is even harder. Managing multiple DeFi positions across multiple blockchains was impossible. Until now! Meet the cross-chain liquidation protection and interest rate optimizer powered by Chainlink CCIP.\n\n\u003e **Note**\n\u003e This project is for educational purposes only and is not ready for production usage.\n\nEnd-user has debt positions on multiple protocols/chains (e.g. Benqi on Avalanche, Compound on Polygon, etc…).\nThey keep all their liquidity safely in a vault on one chain (e.g. Aave on Ethereum).\nOn each chain where the user has a debt position (e.g. Avalanche and Polygon), Automation monitors the debt ratio.\nIf Automation detects that any of their loans approaches the liquidation threshold (e.g. Benqi on Avalanche), then Automation sends a CCIP message to the user’s liquidity chain (e.g. Ethereum) to request remediating action (Send funds. Fast!).\n\nWhen the user’s contract on the liquidity chain receives the CCIP message, it withdraws liquidity from Aave and sends a new CCIP message back to Avalanche with the funds.\nThat message includes enough information and tokens to fund the right position and avoid liquidation.\n\nResult: The User can have debt positions on multiple chains while still keeping liquidity on a single chain.\n\nThe User needs to:\nDeploy a liquidation protection smart contract (LPSC) on the liquidity chain.\nCreate an Automation job on each chain where they have debt, by deploying the Monitor contract.\n\nOptionally the User can run a Functions job with JavaScript that checks interest rates on all major lending protocols on all chains, using the `executeRequest` function of the LPSC smart contract. If it detects that the User is overpaying interest, it will try to pay back the loan and refinance somewhere else.\n\nThere is only one liquidity chain on which we are deploying the LPSC. It is set by default to `ethereumSepolia` but you can change it by adjusting the `defaultNetwork` property of the `config` object in the `hardhat.config.ts` file:\n\n```ts\nconst config: HardhatUserConfig = {\n  defaultNetwork: 'ethereumSepolia', // Liquidity Chain\n  ...\n}\n```\n\n## Usage\n\nThere are several Hardhat tasks available for deployment and interaction with this project. But before that, you need to set up some environment variables.\n\nWe are going to use the [`@chainlink/env-enc`](https://www.npmjs.com/package/@chainlink/env-enc) package for extra security. It encrypts sensitive data instead of storing them as plain text in the `.env` file, by creating a new, `.env.enc` file. Although it's not recommended to push this file online, if that accidentally happens your secrets will still be encrypted.\n\n1. Set a password for encrypting and decrypting the environment variable file. You can change it later by typing the same command.\n\n```shell\nnpx env-enc set-pw\n```\n\n2. Now set the following environment variables: `PRIVATE_KEY`, Source Blockchain RPC URL, Destination Blockchain RPC URL. You can see available options in the `.env.example` file:\n\n```shell\nPRIVATE_KEY=\"\"\nETHEREUM_SEPOLIA_RPC_URL=\"\"\nOPTIMISM_GOERLI_RPC_URL=\"\"\nARBITRUM_TESTNET_RPC_URL=\"\"\nAVALANCHE_FUJI_RPC_URL=\"\"\nPOLYGON_MUMBAI_RPC_URL=\"\"\n```\n\nTo set these variables, type the following command and follow the instructions in the terminal:\n\n```shell\nnpx env-enc set\n```\n\nAfter you are done, the `.env.enc` file will be automatically generated.\n\nIf you want to validate your inputs you can always run the next command:\n\n```shell\nnpx env-enc view\n```\n\n### Preparing the mock scenario\n\nTo test this project before the actual usage, there are a couple of mock contracts, the two most notable are [`MockVault.sol`](./contracts/mocks/MockVault.sol) and [`MockLending.sol`](./contracts/mocks/MockLending.sol). MockVault represents the protocol on the liquidity chain where the User stores its funds such as Aave for example, while MockLending represents a protocol on other chains where the User can open debt positions, such as Aave, Compound, Benqi and such.\n\n1. To deploy the [`MockVault.sol`](./contracts/mocks/MockVault.sol) smart contract you can use the `deploy-mock-vault` task, by running:\n\n```shell\nnpx hardhat deploy-mock-vault\n```\n\n2. To deploy the [`MockLending.sol`](./contracts/mocks/MockLending.sol) smart contract you can use the `deploy-mock-lending` task, by running:\n\n```shell\nnpx hardhat deploy-mock-lending --network \u003cNETWORK\u003e\n```\n\nWhere \u003cNETWORK\u003e can be:\n\n- ethereumSepolia\n- polygonMumbai\n- optimismGoerli\n- arbitrumTestnet\n- avalancheFuji\n\n### Deployment\n\n3. To deploy the [`LPSC.sol`](./contracts/LPSC.sol) smart contract you can use the `deploy-lpsc` task:\n\n```shell\nnpx hardhat deploy-lpsc\n--router \u003cCCIP_ROUTER_ADDRESS\u003e\n--vault \u003cVAULT_CONTRACT_ADDRESS\u003e\n```\n\nFor example, to deploy the [`LPSC.sol`](./contracts/LPSC.sol) smart contract to the Liquidity Chain (`defaultNetwork: 'ethereumSepolia'`) run:\n\n```shell\nnpx hardhat deploy-lpsc --router 0xD0daae2231E9CB96b94C8512223533293C3693Bf --vault \u003cMOCK_VAULT_ADDRESS\u003e\n```\n\n4. To deploy the [`MonitorMockLending.sol`](./contracts/monitors/MonitorMockLending.sol) smart contract you can use `deploy-monitor-mock-lending` task:\n\n```shell\nnpx hardhat deploy-monitor-mock-lending\n--min-health-factor \u003cMIN_HEALTH_FACTOR_BEFORE_LIQUIDATION_SAVING_IS_TRIGGERED\u003e\n--router \u003cCCIP_ROUTER_ADDRESS\u003e\n--lending-address \u003cMOCK_LENDING_ADDRESS\u003e\n--token-address \u003cREPAY_TOKEN_ADDRESS\u003e\n--on-behalf-of \u003cYOUR_EOA_ADDRESS\u003e\n--lpsc \u003cLPSC_CONTRACT_ADDRESS\u003e\n--liquidation-chain-selector \u003cLIQUIDATION_CHAIN_SELECTOR\u003e\n--link \u003cLINK_TOKEN_ADDRESS\u003e # Optional\n```\n\n### Fee Management\n\n5. Chainlink CCIP fees are being paid in LINK tokens. Contracts that send CCIP Cross-Chain Messages need to be funded. In our project, those are [`LPSC.sol`](./contracts/LPSC.sol) and each of the Monitor contracts deployed. To fund them you can either manually send LINK tokens to their addresses from your wallet or use the `fund` task:\n\n```shell\nnpx hardhat fund\n--receiver \u003cRECEIVER_CONTRACT_ADDRESS\u003e\n--amount \u003cAMOUNT_IN_JUELS_TO_SEND\u003e\n--link \u003cLINK_TOKEN_ADDRESS\u003e # Optional\n```\n\nFor example, to fund the [`LPSC.sol`](./contracts/LPSC.sol) smart contract with 0.1 Sepolia LINK, run:\n\n```shell\nnpx hardhat fund --receiver \u003cLPSC_CONTRACT_ADDRESS\u003e --amount 100000000000000000\n```\n\nTo fund the [`MonitorMockLending.sol`](./contracts/monitors/MonitorMockLending.sol) smart contract with 0.1 Fuji LINK, run:\n\n```shell\nnpx hardhat fund --receiver \u003cMONITOR_MOCK_LENDING_CONTRACT_ADDRESS\u003e --amount 100000000000000000 --network avalancheFuji\n```\n\n### Triggering Liquidation Saving\n\n6. Register a Custom Logic [Chainlink Automation](https://chain.link/automation) Upkeep by following the [guide from the Official Chainlink Documentation](https://docs.chain.link/chainlink-automation/register-upkeep)\n\n![automation](./img/automation.png)\n\nSince all Monitors contracts are Chainlink Automation Compatible, once that is set up, it will start monitoring if any positions need to be saved from liquidation, and you can sit back and relax since from that moment the project is officially set up to auto-pilot mode.\n\nFor the purpose of testing, you can manually trigger the mock liquidation-saving process, by running the following command:\n\n```shell\nnpx hardhat trigger --monitor \u003cMONITOR_MOCK_LENDING_CONTRACT_ADDRESS\u003e --network avalancheFuji\n```\n\n### Triggering Interest Rate Optimizing\n\n7. Optionally, you can move your funds on the liquidation chain from one protocol to another using [Chainlink Functions](https://chain.link/functions)\n\nTo simulate doing that, run the following command:\n\n```shell\nnpx hardhat functions-simulate --network hardhat\n```\n\nTo expand this functionality to multiple chains, to find better yield resources, or to add more features, use the [Chainlink Functions Playground](https://functions.chain.link/playground) for the development of the JavaScript code of [`Functions-request-source.js`](./Functions-request-source.js) file.\n\n![img](./img/functions-playground.png)\n\n### Troubleshooting\n\nThere is always a possibility that this fully automated process throws an error, most likely because you don't have enough funds to perform the liquidation saving. If that happens, don't panic, LPSC has a system to trigger certain actions manually from the `owner` account.\n\nMost likely, the failure is because you are low on liquidity to cover debt(s), but there are other possible errors. Once you figure out the cause of failure \u0026 fix it, you have two options to manually complete the execution:\n\n#### Option 1)\n\nGo to [CCIP Explorer](https://ccip.chain.link/), search for a failed transaction, connect your wallet and click the 'Trigger Manual Execution' button.\n\n![trigger-manual-execution](./img/trigger-manual-execution.png)\n\n#### Option 2)\n\nNavigate to the 'Source Transaction Hash' from the [CCIP Explorer](https://ccip.chain.link/) and try to locate the CCIP Message ID from the event logs\n\n![event-log](./img/event-log.png)\n\nAnd then call the `reply()` function on the [`LPSC.sol`](./contracts/LPSC.sol) smart contract, using the `reply` task:\n\n```shell\nnpx hardhat reply\n--lpsc \u003cLPSC_ADDRESS_ON_SEPOLIA\u003e\n--requested-token-address \u003cREQUESTED_TOKEN_ADDRESS_ON_SOURCE_CHAIN\u003e # Avalanche Fuji in our example\n--amount \u003cAMOUNT_REQUESTED\u003e\n--source-chain-selector \u003cSOURCE_CHAIN_CHAIN_SELECTOR\u003e # 14767482510784806043 for Avalanche Fuji in our example\n--monitor-address \u003cMONITOR_BOT_ADDRESS_ON_SOURCE_CHAIN\u003e\n--message-id \u003cID_OF_THE_CCIP_MESSAGE_THAT_FAILED_TO_EXECUTE_ON_SEPOLIA\u003e # from the logs\n```\n\nTo manually trigger it for our mock example, run:\n\n```shell\nnpx hardhat reply --lpsc \u003cLPSC_ADDRESS\u003e --requested-token-address 0xD21341536c5cF5EB1bcb58f6723cE26e8D8E90e4 --amount 1000000000000000000 --source-chain-selector 14767482510784806043 --monitor-address \u003cMONITOR_MOCK_LENDING_ADDRESS\u003e --message-id \u003cCCIP_MESSAGE_ID\u003e\n```\n\nWhere [0xD21341536c5cF5EB1bcb58f6723cE26e8D8E90e4](https://testnet.snowtrace.io/address/0xD21341536c5cF5EB1bcb58f6723cE26e8D8E90e4) is the CCIP_BnM token address on Avalanche Fuji blockchain.\n\n### Monitor Bots\n\nOther monitor bot smart contracts can be deployed and configured using Chainlink Automation. Currently available are:\n\n- [`MonitorAaveV2`](./contracts/monitors/MonitorAaveV2.sol)\n- [`MonitorAaveV3`](./contracts/monitors/MonitorAaveV3.sol)\n- [`MonitorCompoundV2`](./contracts/monitors/MonitorCompoundV2.sol)\n- [`MonitorCompoundV3`](./contracts/monitors/MonitorCompoundV3.sol)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Fccip-liquidation-protector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmartcontractkit%2Fccip-liquidation-protector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Fccip-liquidation-protector/lists"}