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 4 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
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": "0x48BF2f96E4fEdEd569595BB1e015A747c2B35EEa",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-07-22 08:34:11",
"CONSTRUCTOR_ARGS": "0x00000000000000000000000029dacdf7ccadf4ee67c923b4c22255a4b2494ed7",
"SALT": "",
"VERIFIED": "true"
}
]
}
}
}
}
8 changes: 4 additions & 4 deletions deployments/bsc.diamond.staging.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@
"Name": "GenericSwapFacet",
"Version": "1.0.0"
},
"0xA269cb81E6bBB86683558e449cb1bAFFdb155Bfc": {
"Name": "",
"Version": ""
},
"0xE871874D8AC30E8aCD0eC67529b4a5dDD73Bf0d6": {
"Name": "GenericSwapFacetV3",
"Version": "1.0.1"
},
"0x48BF2f96E4fEdEd569595BB1e015A747c2B35EEa": {
"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": "0x48BF2f96E4fEdEd569595BB1e015A747c2B35EEa"
}
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");
}
}
64 changes: 59 additions & 5 deletions script/helperFunctions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2047,7 +2047,7 @@ function checkFailure() {
# >>>>> output to console
function echoDebug() {
# read function arguments into variables
MESSAGE=$1
local MESSAGE=$1

# write message to console if debug flag is set to true
if [[ $DEBUG == "true" ]]; then
Expand All @@ -2060,6 +2060,9 @@ function error() {
function warning() {
printf '\033[33m[warning] %s\033[0m\n' "$1"
}
function success() {
printf '\033[0;32m[success] %s\033[0m\n' "$1"
}
0xDEnYO marked this conversation as resolved.
Show resolved Hide resolved
# <<<<< output to console

# >>>>> Reading and manipulation of target state JSON file
Expand Down Expand Up @@ -2882,7 +2885,7 @@ function getCreate3FactoryAddress() {

echo $CREATE3_FACTORY
}


function printDeploymentsStatus() {
# read function arguments into variables
Expand Down Expand Up @@ -3296,6 +3299,56 @@ function compareAddresses() {
return 1
fi
}
function sendMessageToDiscordSmartContractsChannel() {
# read function arguments into variable
local MESSAGE=$1

if [ -z "$DISCORD_WARNING_WEBHOOK_URL" ]; then
echo ""
warning "Discord webhook URL for dev-smartcontracts is missing. Cannot send log message."
echo ""
return 1
fi

echo ""
echoDebug "sending the following message to Discord webhook ('dev-smartcontracts' channel):"
echoDebug "$MESSAGE"
echo ""

# Send the message
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\": \"$MESSAGE\"}" \
$DISCORD_WARNING_WEBHOOK_URL

echoDebug "Log message sent to Discord"

return 0


}
0xDEnYO marked this conversation as resolved.
Show resolved Hide resolved

function getUserInfo() {
# log local username
local USERNAME=$(whoami)

# log Github email address
EMAIL=$(git config --global user.email)
if [ -z "$EMAIL" ]; then
EMAIL=$(git config --local user.email)
fi

# return collected info
echo "Username: $USERNAME, Github email: $EMAIL"
0xDEnYO marked this conversation as resolved.
Show resolved Hide resolved

}
0xDEnYO marked this conversation as resolved.
Show resolved Hide resolved
function cleanupBackgroundJobs() {
echo "Cleaning up..."
# Kill all background jobs
pkill -P $$
echo "All background jobs killed. Script execution aborted."
exit 1
}
0xDEnYO marked this conversation as resolved.
Show resolved Hide resolved
# <<<<<< miscellaneous

# >>>>>> helpers to set/update deployment files/logs/etc
Expand Down Expand Up @@ -3642,13 +3695,14 @@ function test_tmp() {
ENVIRONMENT="production"
VERSION="2.0.0"
DIAMOND_CONTRACT_NAME="LiFiDiamondImmutable"
ARGS="0x000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666"

ARGS="0x00000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666"
RPC_URL=$(getRPCUrl "$NETWORK" "$ENVIRONMENT")
# ADDRESS=$(getContractOwner "$NETWORK" "$ENVIRONMENT" "ERC20Proxy");
# if [[ "$ADDRESS" != "$ZERO_ADDRESS" ]]; then
# error "ERC20Proxy ownership was not transferred to address(0)"
# exit 1
# fi
#getPeripheryAddressFromDiamond "$NETWORK" "0x9b11bc9FAc17c058CAB6286b0c785bE6a65492EF" "RelayerCelerIM"
verifyContract "$NETWORK" "$CONTRACT" "$ADDRESS" "$ARGS"
# verifyContract "$NETWORK" "$CONTRACT" "$ADDRESS" "$ARGS"
}
# test_tmp
Loading
Loading