{"id":16321226,"url":"https://github.com/beeb/lp-rescue-contract","last_synced_at":"2025-10-31T18:30:26.065Z","repository":{"id":59368322,"uuid":"536200673","full_name":"beeb/lp-rescue-contract","owner":"beeb","description":"Contract to add liquidity to a Uniswap v2 or PancakeSwap v2 LP which is stuck due to a non-zero balance","archived":false,"fork":false,"pushed_at":"2023-08-09T19:56:45.000Z","size":861,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-25T19:23:59.939Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://lp-rescue.beeb.li","language":"Solidity","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/beeb.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-13T15:52:40.000Z","updated_at":"2022-09-30T19:14:30.000Z","dependencies_parsed_at":"2024-12-25T19:22:58.912Z","dependency_job_id":"a0d09d36-b700-469c-bd90-cb838b0c5957","html_url":"https://github.com/beeb/lp-rescue-contract","commit_stats":{"total_commits":85,"total_committers":2,"mean_commits":42.5,"dds":0.04705882352941182,"last_synced_commit":"5016ee935e87484f9abd3647e2ffab8b3f0e2382"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeb%2Flp-rescue-contract","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeb%2Flp-rescue-contract/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeb%2Flp-rescue-contract/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeb%2Flp-rescue-contract/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beeb","download_url":"https://codeload.github.com/beeb/lp-rescue-contract/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239221175,"owners_count":19602380,"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-10-10T22:47:03.469Z","updated_at":"2025-10-31T18:30:26.024Z","avatar_url":"https://github.com/beeb.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"![LP-Rescue](https://github.com/beeb/lp-rescue-frontend/raw/main/logo-readme.svg)\n\n# LP Rescue Contract\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/beeb/lp-rescue-contract/actions/workflows/ci.yml\"\u003e\n    \u003cimg src=\"https://github.com/beeb/lp-rescue-contract/actions/workflows/ci.yml/badge.svg\" /\u003e\n  \u003c/a\u003e -\n  \u003ca href=\"https://github.com/beeb/lp-rescue-frontend\"\u003eFront-end dApp\u003c/a\u003e\n\u003c/p\u003e\n\nThis contract allows to add liquidity to a Uniswap v2 or PancakeSwap v2 LP contract which was exploited by sending\nsome tokens and calling the `sync` function, effectively setting one of the reserves to a non-zero value.\n\nThe Router contract will refuse to add liquidity to such a pool, so `LPRescue` can be used to add liquidity instead.\n\n[Live contract on BSC for PcS v2 pools](https://bscscan.com/address/0xbaB1e26127D601407A1E29F55C848BCAB33f6258)\n\n## Description of the problem\n\nWhen calling the `sync` function on an AMM pair contract when one of the balances is zero and the other is non-zero,\nthe contract will modify the reserve state variables so that they match the balances.\n\nAs such, if some `token0` was sent to the pair, and afterwards (before `skim` is called by another actor, for instance)\nthe `sync` function is called (usually in the same transaction), the contract will set the `reserve0` state variable\nto the balance of `token0` in the contract, and `reserve1` will be equal to zero.\n\nIn such a situation, the `addLiquidity` or `addLiquidityETH` of the DEX router will revert.\n\n## Description of the solution\n\nThe solution is to handle this particular case (one reserve is non-zero and the other is zero) with fewer checks\nthan the regular `addLiquidity` function.\n\nThis contract, in essence, sends the missing amount of tokens to reach the desired liquidity ratio, and then calls\nthe `mint` function of the pair in the same transaction, effectively resetting reserves and creating liquidity tokens.\n\nIn our case, the `mint` function was never called before, because it would revert if one of the balances was zero.\nIf both balances are non-zero, then LP tokens can be minted, the balances `sync`ed and `LPRescue` would not be needed.\n\n## Additional notes\n\nDue to how the pair contract is coded, when minting liquidity tokens, the pre-existing reserve value will be subtracted\nfrom the pair's balance when calculating the invariant (and amount of LP tokens). This is usually insignificant as\nmalicious actors send a very small amount of tokens to get the pair in this stuck state, since those tokens are lost\nto them.\n\n## Forge/NPM commands\n\nSince the self-deployed Uniswap pair contracts have a different bytecode than the deployed version, the Uniswap V2\nLibrary function that calculates the pair address deterministically without external calls is not working locally.\n\nTo fix this, the library is patched when the dependencies are installed with `npm i`.\n\n```shell\n$ npm i\n$ forge install\n$ forge test -vvv\n$ ./utils/deploy_pcs_testnet.sh\n$ ./utils/deploy_pcs_mainnet.sh\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeeb%2Flp-rescue-contract","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeeb%2Flp-rescue-contract","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeeb%2Flp-rescue-contract/lists"}