ethereum: Implement shutdown for all 3 contracts (fixes #1937)
These are stripped down versions of the original contracts that can be dropped in place via an upgrade to disable core functionality. Governance features are still enabled, which means it's possible to upgrade back to a working implementation.
This commit is contained in:
parent
648b361623
commit
effde7f756
|
@ -0,0 +1,31 @@
|
|||
// contracts/Shutdown.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./Governance.sol";
|
||||
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
|
||||
|
||||
/**
|
||||
* @title Shutdown
|
||||
* @notice This contract implements a stripped-down version of the Wormhole core
|
||||
* messaging protocol that is a drop-in replacement for Wormhole's
|
||||
* implementation contract, effectively disabling all non-governance
|
||||
* functionality.
|
||||
* In particular, outgoing messages are disabled, but the contract
|
||||
* remains upgradeable through governance.
|
||||
*/
|
||||
contract Shutdown is Governance {
|
||||
|
||||
function initialize() public {
|
||||
address implementation = ERC1967Upgrade._getImplementation();
|
||||
setInitialized(implementation);
|
||||
|
||||
// this function needs to be exposed for an upgrade to pass
|
||||
// NOTE: leave this function empty! It specifically does not have an
|
||||
// 'initializer' modifier, to allow this contract to be upgraded to
|
||||
// multiple times.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// contracts/BridgeShutdown.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./BridgeGovernance.sol";
|
||||
|
||||
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
|
||||
|
||||
/**
|
||||
* @title BridgeShutdown
|
||||
* @notice This contract implements a stripped-down version of the token bridge
|
||||
* asset transfer protocol that is a drop-in replacement for the Bridge
|
||||
* implementation contract, effectively disabling all non-governance
|
||||
* functionality.
|
||||
* In particular, sending and receiving assets is disabled, but the
|
||||
* contract remains upgradeable through governance.
|
||||
* @dev Technically the ReentrancyGuard is not used in this contract,
|
||||
* but it adds a storage variable, so as a matter of principle, we
|
||||
* inherit that here too in order keep the storage layout identical to
|
||||
* the actual implementation contract (which does use the reentrancy
|
||||
* guard).
|
||||
*/
|
||||
contract BridgeShutdown is BridgeGovernance, ReentrancyGuard {
|
||||
|
||||
function initialize() public {
|
||||
address implementation = ERC1967Upgrade._getImplementation();
|
||||
setInitialized(implementation);
|
||||
|
||||
// this function needs to be exposed for an upgrade to pass
|
||||
// NOTE: leave this function empty! It specifically does not have an
|
||||
// 'initializer' modifier, to allow this contract to be upgraded to
|
||||
// multiple times.
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// contracts/Bridge.sol
|
||||
// contracts/NFTBridge.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
@ -241,7 +241,7 @@ contract NFTBridge is NFTBridgeGovernance {
|
|||
|
||||
transfer.tokenID = encoded.toUint256(index);
|
||||
index += 32;
|
||||
|
||||
|
||||
// Ignore length due to malformatted payload
|
||||
index += 1;
|
||||
transfer.uri = string(encoded.slice(index, encoded.length - index - 34));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// contracts/Getters.sol
|
||||
// contracts/NFTBridgeGetters.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// contracts/Bridge.sol
|
||||
// contracts/NFTBridgeGovernance.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// contracts/Implementation.sol
|
||||
// contracts/NFTBridgeImplementation.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// contracts/Setters.sol
|
||||
// contracts/NFTBridgeSetters.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// contracts/BridgeSetup.sol
|
||||
// contracts/NFTBridgeSetup.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// contracts/NFTBridgeShutdown.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./NFTBridgeGovernance.sol";
|
||||
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
|
||||
|
||||
/**
|
||||
* @title BridgeShutdown
|
||||
* @notice This contract implements a stripped-down version of the NFT bridge
|
||||
* asset transfer protocol that is a drop-in replacement for the
|
||||
* NFTBridge implementation contract, effectively disabling all
|
||||
* non-governance functionality.
|
||||
* In particular, sending and receiving assets is disabled, but the
|
||||
* contract remains upgradeable through governance.
|
||||
*/
|
||||
contract NFTBridgeShutdown is NFTBridgeGovernance {
|
||||
|
||||
function initialize() public {
|
||||
address implementation = ERC1967Upgrade._getImplementation();
|
||||
setInitialized(implementation);
|
||||
|
||||
// this function needs to be exposed for an upgrade to pass
|
||||
// NOTE: leave this function empty! It specifically does not have an
|
||||
// 'initializer' modifier, to allow this contract to be upgraded to
|
||||
// multiple times.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
const Shutdown = artifacts.require("Shutdown");
|
||||
module.exports = async function(callback) {
|
||||
try {
|
||||
const contract = (await Shutdown.new());
|
||||
console.log('tx: ' + contract.transactionHash);
|
||||
console.log('Shutdown address: ' + contract.address);
|
||||
callback();
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
const Shutdown = artifacts.require("NFTBridgeShutdown");
|
||||
module.exports = async function(callback) {
|
||||
try {
|
||||
const contract = (await Shutdown.new());
|
||||
console.log('tx: ' + contract.transactionHash);
|
||||
console.log('NFTBridgeShutdown address: ' + contract.address);
|
||||
callback();
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
const Shutdown = artifacts.require("BridgeShutdown");
|
||||
module.exports = async function(callback) {
|
||||
try {
|
||||
const contract = (await Shutdown.new());
|
||||
console.log('tx: ' + contract.transactionHash);
|
||||
console.log('Bridge address: ' + contract.address);
|
||||
callback();
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
};
|
|
@ -15,7 +15,7 @@ function usage() {
|
|||
cat <<EOF >&2
|
||||
Usage:
|
||||
|
||||
$(basename "$0") [-h] [-m s] [-c s] [-x] [-k] [-d] [-a s] [-l s] -- Simulate an upgrade on a fork of mainnet, and check for any errors.
|
||||
$(basename "$0") [-h] [-m s] [-c s] [-x] [-k] [-d] [-a s] [-l s] [-s] -- Simulate an upgrade on a fork of mainnet, and check for any errors.
|
||||
|
||||
where:
|
||||
-h show this help text
|
||||
|
@ -24,8 +24,9 @@ Usage:
|
|||
-x run anvil
|
||||
-d don't compile contract first
|
||||
-k keep anvil alive
|
||||
-l file to loge to (by default creates a new tmp file)
|
||||
-l file to log to (by default creates a new tmp file)
|
||||
-a new code address (by default it builds the most recent contract in the repository)
|
||||
-s shutdown
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
@ -40,8 +41,9 @@ chain_name=""
|
|||
run_anvil=false
|
||||
skip_compile=false
|
||||
keepalive_anvil=false
|
||||
shutdown=false
|
||||
anvil_out=$(mktemp)
|
||||
while getopts ':hm:c:a:xkdl:' option; do
|
||||
while getopts ':hm:c:a:xkdl:s' option; do
|
||||
case "$option" in
|
||||
h) usage
|
||||
;;
|
||||
|
@ -60,6 +62,8 @@ while getopts ':hm:c:a:xkdl:' option; do
|
|||
k) keepalive_anvil=true
|
||||
run_anvil=true
|
||||
;;
|
||||
s) shutdown=true
|
||||
;;
|
||||
:) printf "missing argument for -%s\n" "$OPTARG" >&2
|
||||
usage
|
||||
;;
|
||||
|
@ -111,15 +115,27 @@ SCRIPT=""
|
|||
case "$module" in
|
||||
bridge|core)
|
||||
MODULE=Core
|
||||
SCRIPT="scripts/deploy_core_bridge.js"
|
||||
if [[ $shutdown = true ]]; then
|
||||
SCRIPT="scripts/deploy_core_bridge_shutdown.js"
|
||||
else
|
||||
SCRIPT="scripts/deploy_core_bridge.js"
|
||||
fi
|
||||
;;
|
||||
token_bridge)
|
||||
MODULE=TokenBridge
|
||||
SCRIPT="scripts/deploy_token_bridge.js"
|
||||
if [[ $shutdown = true ]]; then
|
||||
SCRIPT="scripts/deploy_token_bridge_shutdown.js"
|
||||
else
|
||||
SCRIPT="scripts/deploy_token_bridge.js"
|
||||
fi
|
||||
;;
|
||||
nft_bridge)
|
||||
MODULE=NFTBridge
|
||||
SCRIPT="scripts/deploy_nft_bridge.js"
|
||||
if [[ $shutdown = true ]]; then
|
||||
SCRIPT="scripts/deploy_nft_bridge_shutdown.js"
|
||||
else
|
||||
SCRIPT="scripts/deploy_nft_bridge.js"
|
||||
fi
|
||||
;;
|
||||
*) echo "unknown module $module" >&2
|
||||
usage
|
||||
|
|
|
@ -28,17 +28,23 @@ ANVIL_PID=$!
|
|||
# Sleep for 10 seconds here to give some time for the fork to complete.
|
||||
sleep 10
|
||||
|
||||
echo "========================= Updating core contract #1 ============================"
|
||||
echo "========================= Updating core contract ============================"
|
||||
./simulate_upgrade -m bridge -c $chain -d
|
||||
echo "========================= Updating core contract #2 ============================"
|
||||
echo "========================= Shutting down core contract ======================="
|
||||
./simulate_upgrade -m bridge -c $chain -d -s
|
||||
echo "========================= Re-enabling core contract ========================="
|
||||
./simulate_upgrade -m bridge -c $chain -d
|
||||
|
||||
echo "===================== Updating token bridge contract #1 ========================"
|
||||
echo "===================== Updating token bridge contract ========================"
|
||||
./simulate_upgrade -m token_bridge -c $chain -d
|
||||
echo "===================== Updating token bridge contract #2 ========================"
|
||||
echo "===================== Shutting down token bridge contract ==================="
|
||||
./simulate_upgrade -m token_bridge -c $chain -d -s
|
||||
echo "===================== Re-enabling token bridge contract ====================="
|
||||
./simulate_upgrade -m token_bridge -c $chain -d
|
||||
|
||||
echo "====================== Updating NFT bridge contract #1 ========================="
|
||||
echo "====================== Updating NFT bridge contract ========================="
|
||||
./simulate_upgrade -m nft_bridge -c $chain -d
|
||||
echo "====================== Updating NFT bridge contract #2 ========================="
|
||||
echo "====================== Shutting down NFT bridge contract ===================="
|
||||
./simulate_upgrade -m nft_bridge -c $chain -d -s
|
||||
echo "====================== Re-enabling NFT bridge contract ======================"
|
||||
./simulate_upgrade -m nft_bridge -c $chain -d
|
||||
|
|
Loading…
Reference in New Issue