Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduces a killswitch for the diamond (EmergencyPauseFacet v1.0.0) #715

Merged
merged 44 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9a26718
feat: adds EmergencyPauseFacet
0xDEnYO Jul 23, 2024
136b8bb
removes unused diamond cut code
0xDEnYO Jul 23, 2024
69cf5f4
introduces LibDiamondLoupe to avoid external calls for loupe functions
0xDEnYO Jul 23, 2024
70843f1
cleanup
0xDEnYO Jul 23, 2024
9ea09d5
registered EmergencyPauseFacet in BSC staging diamond
0xDEnYO Jul 25, 2024
7cc58e4
adds github action that allows to manually pause the diamond from Git…
0xDEnYO Jul 26, 2024
9e5f6c1
Merge branch 'main' of github.com:lifinance/contracts into EmergencyP…
0xDEnYO Jul 26, 2024
bca51af
add team membership verification to git action
0xDEnYO Jul 26, 2024
c99541a
Merge branch 'main' of github.com:lifinance/contracts into EmergencyP…
0xDEnYO Aug 21, 2024
77441a0
remove push event trigger from git action
0xDEnYO Aug 21, 2024
d5c7244
removes unused imports (audit issue#2)
0xDEnYO Sep 9, 2024
e6cbae6
optimizes modifier (audit issue#3)
0xDEnYO Sep 9, 2024
111a2e4
adds indexed keyword to events (audit issue#5)
0xDEnYO Sep 9, 2024
7ea4c75
inlines a helper function that is only used once (audit issue#6)
0xDEnYO Sep 9, 2024
8effe9a
removes unused helper function (audit issue#7)
0xDEnYO Sep 9, 2024
54d4142
removes unnecessary delete statement (audit issue#11)
0xDEnYO Sep 9, 2024
d70d09b
adds check to prevent accidental removal of EmergencyPauseFacet
0xDEnYO Sep 9, 2024
b3b4710
Merge branch 'main' of github.com:lifinance/contracts into EmergencyP…
0xDEnYO Sep 9, 2024
7709442
adds a check to prevent accidental removal of DiamondCutFacet while u…
0xDEnYO Sep 9, 2024
124fd68
adds test to increase test coverage to 100% (audit issue #15)
0xDEnYO Sep 10, 2024
519a8da
removes duplicate function in helperFunctions.sh
0xDEnYO Sep 10, 2024
0def5d6
minor fixes
0xDEnYO Sep 10, 2024
be2a3bc
adds a test case that checks how many facets we can pause
0xDEnYO Sep 11, 2024
ab63a64
Merge branch 'main' of github.com:lifinance/contracts into EmergencyP…
0xDEnYO Sep 11, 2024
79ad7c2
remove playground.sh (accidentally committed before)
0xDEnYO Sep 11, 2024
72e39cd
removes TODO and adds comment
0xDEnYO Sep 12, 2024
af6b003
adds a check to prevent pausing twice
0xDEnYO Sep 12, 2024
7fcf186
used diamondCut function to remove facets so events get emitted (audi…
0xDEnYO Sep 12, 2024
b0b40f2
audit report added and log updated
0xDEnYO Sep 16, 2024
0366dda
Merge branch 'main' of github.com:lifinance/contracts into EmergencyP…
0xDEnYO Oct 8, 2024
c575c59
emergencyPause script updates and staging deployments
0xDEnYO Oct 8, 2024
80519d6
Update script/tasks/diamondEMERGENCYPause.sh
0xDEnYO Oct 8, 2024
24960d6
remove placeholder git action
0xDEnYO Oct 8, 2024
a609417
Merge branch 'EmergencyPause' of github.com:lifinance/contracts into …
0xDEnYO Oct 8, 2024
36c3852
minor fixes from coderabbit reviews
0xDEnYO Oct 8, 2024
3e532ef
add fake audit entry to make PR mergable
0xDEnYO Oct 8, 2024
9e67824
add 2nd fake audit entry to make PR mergable
0xDEnYO Oct 8, 2024
778f7cd
update warning message text
0xDEnYO Oct 8, 2024
48e8704
test
0xDEnYO Oct 8, 2024
668ad84
Merge branch 'main' into EmergencyPause
0xDEnYO Oct 8, 2024
df210d0
Merge branch 'EmergencyPause' of github.com:lifinance/contracts into …
0xDEnYO Oct 8, 2024
3e1a64c
test
0xDEnYO Oct 8, 2024
6acbdd6
test
0xDEnYO Oct 8, 2024
3d7dcd2
revert changes
0xDEnYO Oct 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions .github/workflows/diamondEmergencyPause.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Pause PRODUCTION diamond (CAREFUL)

on:
push:
workflow_dispatch:
inputs:
Warning:
description: 'By clicking the next button you are pausing all PROD diamonds. Please proceed with caution'
required: false

jobs:
diamond-emergency-pause:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3

# Keeping this code for now until team member authentication has been tested successfully
# - name: Authenticate user
# id: check_user
# run: |
# ALLOWED_USERS=("0xDEnYO" "maxklenk" "ezynda3")
# USER=${{ github.actor }}
# if [[ ! " ${ALLOWED_USERS[@]} " =~ " $USER " ]]; then
# echo "User $USER is not allowed to run this workflow. Only the following users are:"
# echo "$ALLOWED_USERS"
# exit 1
# else
# echo "User $USER is allowed to run this workflow."
# fi
# shell: bash

- name: Authenticate git user (check membership in 'DiamondPauser' group)
id: authenticate-user
uses: tspascoal/get-user-teams-membership@v3
with:
username: ${{ github.actor }}
organization: lifinance
team: diamondpauser
GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }}

- name: Check team membership
run: |
if [[ "${{ steps.authenticate-user.outputs.isTeamMember }}" != "true" ]]; then
echo "User ${{ github.actor }} is not a member of the DiamondPauser team. Please ask one of the team members to execute this action:"
echo "https://github.com/orgs/lifinance/teams/diamondpauser/members"
exit 1
else
echo "User is a member of the DiamondPauser team and may execute this action"
fi

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Pause Diamond
run: |
./script/tasks/diamondEMERGENCYPauseGitHub.sh
env:
ETH_NODE_URI_MAINNET: ${{ secrets.ETH_NODE_URI_MAINNET }}
ETH_NODE_URI_ARBITRUM: ${{ secrets.ETH_NODE_URI_ARBITRUM }}
ETH_NODE_URI_AURORA: ${{ secrets.ETH_NODE_URI_AURORA }}
ETH_NODE_URI_AVALANCHE: ${{ secrets.ETH_NODE_URI_AVALANCHE }}
ETH_NODE_URI_BASE: ${{ secrets.ETH_NODE_URI_BASE }}
ETH_NODE_URI_BLAST: ${{ secrets.ETH_NODE_URI_BLAST }}
ETH_NODE_URI_BOBA: ${{ secrets.ETH_NODE_URI_BOBA }}
ETH_NODE_URI_BSC: ${{ secrets.ETH_NODE_URI_BSC }}
ETH_NODE_URI_CELO: ${{ secrets.ETH_NODE_URI_CELO }}
ETH_NODE_URI_FANTOM: ${{ secrets.ETH_NODE_URI_FANTOM }}
ETH_NODE_URI_FRAXTAL: ${{ secrets.ETH_NODE_URI_FRAXTAL }}
ETH_NODE_URI_FUSE: ${{ secrets.ETH_NODE_URI_FUSE }}
ETH_NODE_URI_GNOSIS: ${{ secrets.ETH_NODE_URI_GNOSIS }}
ETH_NODE_URI_LINEA: ${{ secrets.ETH_NODE_URI_LINEA }}
ETH_NODE_URI_MANTLE: ${{ secrets.ETH_NODE_URI_MANTLE }}
ETH_NODE_URI_METIS: ${{ secrets.ETH_NODE_URI_METIS }}
ETH_NODE_URI_MODE: ${{ secrets.ETH_NODE_URI_MODE }}
ETH_NODE_URI_MOONBEAM: ${{ secrets.ETH_NODE_URI_MOONBEAM }}
ETH_NODE_URI_MOONRIVER: ${{ secrets.ETH_NODE_URI_MOONRIVER }}
ETH_NODE_URI_OPTIMISM: ${{ secrets.ETH_NODE_URI_OPTIMISM }}
ETH_NODE_URI_POLYGON: ${{ secrets.ETH_NODE_URI_POLYGON }}
ETH_NODE_URI_POLYGONZKEVM: ${{ secrets.ETH_NODE_URI_POLYGONZKEVM }}
ETH_NODE_URI_ROOTSTOCK: ${{ secrets.ETH_NODE_URI_ROOTSTOCK }}
ETH_NODE_URI_SCROLL: ${{ secrets.ETH_NODE_URI_SCROLL }}
ETH_NODE_URI_SEI: ${{ secrets.ETH_NODE_URI_SEI }}
ETH_NODE_URI_ZKSYNC: ${{ secrets.ETH_NODE_URI_ZKSYNC }}
PRIVATE_KEY_PAUSER_WALLET: ${{ secrets.TEST_PRIV_KEY_SECRET }}

- name: Send Discord message
uses: Ilshidur/[email protected]
with:
args: 'ATTENTION - the emergency diamond pause action was just executed by ${{ github.actor }}'
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_DEV_SMARTCONTRACTS }}
1 change: 1 addition & 0 deletions config/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"withdrawWallet": "0x08647cc950813966142A416D40C382e2c5DB73bB",
"lifuelRebalanceWallet": "0xC71284231A726A18ac85c94D75f9fe17A185BeAF",
"deployerWallet": "0x11F1022cA6AdEF6400e5677528a80d49a069C00c",
"pauserWallet": "0x29DaCdF7cCaDf4eE67c923b4C22255A4B2494eD7",
"approvedSigsForRefundWallet": [
{
"sig": "0x0d19e519",
Expand Down
38 changes: 34 additions & 4 deletions deployments/_deployments_log_file.json
Original file line number Diff line number Diff line change
Expand Up @@ -762,12 +762,12 @@
"staging": {
"1.0.0": [
{
"ADDRESS": "0x8938CEa23C3c5eAABb895765f5B0b2b07D680402",
"ADDRESS": "0x47a0bD7A824291040BB7bD8cdBBd7d63bA1B81C9",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2023-06-27 16:56:48",
"TIMESTAMP": "2024-07-21 16:02:40",
"CONSTRUCTOR_ARGS": "0x",
"SALT": "27062023",
"VERIFIED": "true"
"SALT": "",
"VERIFIED": "false"
}
]
}
Expand Down Expand Up @@ -20552,5 +20552,35 @@
]
}
}
},
"EmergencyPauseFacet": {
"polygon": {
"staging": {
"1.0.0": [
{
"ADDRESS": "0x6DCDA5EEb0eb10D61eB9AAF93C3B89704955dA42",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-07-21 15:50:57",
"CONSTRUCTOR_ARGS": "0x00000000000000000000000029dacdf7ccadf4ee67c923b4c22255a4b2494ed7",
"SALT": "",
"VERIFIED": "false"
}
]
}
},
"bsc": {
"staging": {
"1.0.0": [
{
"ADDRESS": "0xf03AFcA857918BE01EBD6C6800Fc2974b8a9eBA2",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-07-25 15:21:33",
"CONSTRUCTOR_ARGS": "0x00000000000000000000000029dacdf7ccadf4ee67c923b4c22255a4b2494ed7",
"SALT": "",
"VERIFIED": "false"
}
]
}
}
}
}
12 changes: 8 additions & 4 deletions deployments/bsc.diamond.staging.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"LiFiDiamond": {
"Facets": {
"0xE871874D8AC30E8aCD0eC67529b4a5dDD73Bf0d6": {
"Name": "GenericSwapFacetV3",
"Version": "1.0.1"
},
"0x06045F5FA6EA7c6AcEb104b55BcD6C3dE3a08831": {
"Name": "DiamondCutFacet",
"Version": "1.0.0"
Expand Down Expand Up @@ -69,13 +73,13 @@
"Name": "GenericSwapFacet",
"Version": "1.0.0"
},
"0xA269cb81E6bBB86683558e449cb1bAFFdb155Bfc": {
"0x089153117bffd37CBbE0c604dAE8e493D4743fA8": {
"Name": "",
"Version": ""
},
"0xE871874D8AC30E8aCD0eC67529b4a5dDD73Bf0d6": {
"Name": "GenericSwapFacetV3",
"Version": "1.0.1"
"0xf03AFcA857918BE01EBD6C6800Fc2974b8a9eBA2": {
"Name": "EmergencyPauseFacet",
"Version": "1.0.0"
}
},
"Periphery": {
Expand Down
3 changes: 2 additions & 1 deletion deployments/bsc.staging.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"AmarokFacetPacked": "0x7ac3EB2D191EBAb9E925CAbFD4F8155be066b3aa",
"MayanBridgeFacet": "0x5Ba4FeD1DAd2fD057A9f687B399B8e4cF2368214",
"MayanFacet": "0xd596C903d78870786c5DB0E448ce7F87A65A0daD",
"GenericSwapFacetV3": "0xE871874D8AC30E8aCD0eC67529b4a5dDD73Bf0d6"
"GenericSwapFacetV3": "0xE871874D8AC30E8aCD0eC67529b4a5dDD73Bf0d6",
"EmergencyPauseFacet": "0xf03AFcA857918BE01EBD6C6800Fc2974b8a9eBA2"
}
4 changes: 4 additions & 0 deletions deployments/polygon.diamond.staging.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"LiFiDiamond": {
"Facets": {
"0x6DCDA5EEb0eb10D61eB9AAF93C3B89704955dA42": {
"Name": "EmergencyPauseFacet",
"Version": "1.0.0"
},
"0x06045F5FA6EA7c6AcEb104b55BcD6C3dE3a08831": {
"Name": "DiamondCutFacet",
"Version": "1.0.0"
Expand Down
5 changes: 3 additions & 2 deletions deployments/polygon.staging.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"DiamondCutFacet": "0x06045F5FA6EA7c6AcEb104b55BcD6C3dE3a08831",
"DiamondLoupeFacet": "0x8938CEa23C3c5eAABb895765f5B0b2b07D680402",
"DiamondLoupeFacet": "0x47a0bD7A824291040BB7bD8cdBBd7d63bA1B81C9",
"OwnershipFacet": "0x53d4Bcd5BEa4e863376b7eA43D7465351a4d71B0",
"DexManagerFacet": "0xB94Fd26F6b138E1bE6CfEa5Ec4F67C5573F5d6AD",
"AccessManagerFacet": "0x1A841931913806FB7570B43bcD64A487A8E7A50c",
Expand Down Expand Up @@ -39,5 +39,6 @@
"TokenWrapper": "0xfb4A1eAC23CF91043C5C8f85993ce153B863ed61",
"GasRebateDistributor": "0x3116B8F099D7eFA6e24f39F80146Aac423365EB9",
"GenericSwapFacetV3": "0x4b904ad5Ca7601595277575824B080e078e2E812",
"StargateFacetV2": "0xeb3f9490d8cbD0C34C0642a8d0495e5E0B0745AA"
"StargateFacetV2": "0xeb3f9490d8cbD0C34C0642a8d0495e5E0B0745AA",
"EmergencyPauseFacet": "0x6DCDA5EEb0eb10D61eB9AAF93C3B89704955dA42"
}
14 changes: 14 additions & 0 deletions docs/EmergencyPauseFacet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# EmergencyPauseFacet

## How it works

The EmergencyPauseFacet is an admin-only facet. Its purpose is to provide a fast yet secure way to respond to suspicious transactions and smart contract activity by either pausing the whole diamond or by removing one specific facet. This can be done from a non-multisig account (i.e.: the 'PauserWallet') to ensure fast execution. The unpausing of the contract as well as adding any new facets is still only possible through the multisig owner wallet for added security.

## Public Methods

- `function removeFacet(address _facetAddress)`
- Removes the given facet from the diamond
- `function pauseDiamond()`
- Pauses the diamond by redirecting all function selectors to EmergencyPauseFacet
- `function unpauseDiamond(address[] calldata _blacklist)`
- Unpauses the diamond by reactivating all formerly registered facets except for the facets in '\_blacklist'
0xDEnYO marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 5 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
- [DEX Manager Facet](./DexManagerFacet.md)
- [DiamondCut Facet](./DiamondCutFacet.md)
- [DiamondLoupe Facet](./DiamondLoupeFacet.md)
- [Emergency Pause Facet](./EmergencyPauseFacet.md)
- [Generic Swap Facet](./GenericSwapFacet.md)
- [Generic Swap FacetV3](./GenericSwapFacetV3.md)
- [Gnosis Bridge Facet](./GnosisBridgeFacet.md)
- [Hop Facet](./HopFacet.md)
- [Hop Facet Packed](./HopFacetPacked.md)
Expand All @@ -30,6 +32,7 @@
- [Squid Facet](./SquidFacet.md)
- [Standardized Call Facet](./StandardizedCallFacet.md)
- [Stargate Facet](./StargateFacet.md)
- [Stargate FacetV2](./StargateFacetV2.md)
- [Synapse Bridge Facet](./SynapseBridgeFacet.md)
- [ThorSwap Facet](./ThorSwapFacet.md)
- [Withdraw Facet](./WithdrawFacet.md)
Expand All @@ -54,5 +57,7 @@
- [ERC20Proxy](./ERC20Proxy.md)
- [Executor](./Executor.md)
- [FeeCollector](./FeeCollector.md)
- [LiFuelFeeCollector](./LiFuelFeeCollector.md)
- [Receiver](./Receiver.md)
- [ReceiverStargateV2](./ReceiverStargateV2.md)
- [RelayerCelerIM](./RelayerCelerIM.md)
32 changes: 32 additions & 0 deletions script/deploy/facets/DeployEmergencyPauseFacet.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import { DeployScriptBase } from "./utils/DeployScriptBase.sol";
import { stdJson } from "forge-std/Script.sol";
import { EmergencyPauseFacet } from "lifi/Facets/EmergencyPauseFacet.sol";

contract DeployScript is DeployScriptBase {
using stdJson for string;

constructor() DeployScriptBase("EmergencyPauseFacet") {}

function run()
public
returns (EmergencyPauseFacet deployed, bytes memory constructorArgs)
{
constructorArgs = getConstructorArgs();

deployed = EmergencyPauseFacet(
deploy(type(EmergencyPauseFacet).creationCode)
);
}

function getConstructorArgs() internal override returns (bytes memory) {
string memory path = string.concat(root, "/config/global.json");
string memory json = vm.readFile(path);

address pauserWallet = json.readAddress(".pauserWallet");

return abi.encode(pauserWallet);
}
}
17 changes: 17 additions & 0 deletions script/deploy/facets/UpdateEmergencyPauseFacet.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import { UpdateScriptBase } from "./utils/UpdateScriptBase.sol";
import { stdJson } from "forge-std/StdJson.sol";
import { EmergencyPauseFacet } from "lifi/Facets/EmergencyPauseFacet.sol";

contract DeployScript is UpdateScriptBase {
using stdJson for string;

function run()
public
returns (address[] memory facets, bytes memory cutData)
{
return update("EmergencyPauseFacet");
}
}
Loading
Loading