Skip to content

Commit

Permalink
Added L2VotingPowerPaused and L2GovernorPaused contract with test cas…
Browse files Browse the repository at this point in the history
…es (#165)

* Added L2VotingPowerPaused and L2GovernorPaused contract with test cases

* Add deployment script

* Update git submodules

* Add foundry.toml

* Change version function to be independent

* Update comments

* Update gitsubmodule, added Custom Errors

* Rearrange functions according to requirements

* pump forge-std to 1.8.2

* Add onReceive ERC721 and ERC1155 check

* Test adjustVotingPower is unpaused

* Add deployPausedDAO.sh

* Add forge clean to deploy script

* Clean before every forge script runs

* Used `../../` to navigate paused script

* rename assertInitParamsEq
  • Loading branch information
Phanco authored and matjazv committed Jun 21, 2024
1 parent 96058e2 commit 9f95eac
Show file tree
Hide file tree
Showing 14 changed files with 778 additions and 5 deletions.
5 changes: 4 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/openzeppelin-foundry-upgrades"]
path = lib/openzeppelin-foundry-upgrades
url = https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades
9 changes: 8 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@ remappings = [
'ds-test/=lib/forge-std/lib/ds-test/src/',
'erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/',
'forge-std/=lib/forge-std/src/',
'@openzeppelin/=lib/openzeppelin-contracts/',
'@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/',
'openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/',
'openzeppelin-contracts/=lib/openzeppelin-contracts/',
'@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/',
'openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/',
'solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/',
]
deny_warnings = true

ffi = true
ast = true
build_info = true
extra_output = ["storageLayout"]

[fmt]
line_length = 120
multiline_func_header = 'all'
Expand Down
1 change: 1 addition & 0 deletions lib/openzeppelin-foundry-upgrades
53 changes: 53 additions & 0 deletions script/contracts/L2/paused/L2GovernorPaused.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.23;

import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { Upgrades } from "openzeppelin-foundry-upgrades/Upgrades.sol";
import { Options } from "openzeppelin-foundry-upgrades/Options.sol";
import { Script, console2 } from "forge-std/Script.sol";
import { L2GovernorPaused } from "src/L2/paused/L2GovernorPaused.sol";
import "script/contracts/Utils.sol";

/// @title L2GovernorPausedScript - L2GovernorPaused contract deployment script
/// @notice This contract is used to deploy L2GovernorPaused contract and write its address to JSON file.
contract L2GovernorPausedScript is Script {
/// @notice Utils contract which provides functions to read and write JSON files containing L1 and L2 addresses.
Utils utils;

function setUp() public {
utils = new Utils();
}

/// @notice This function deploys L2GovernorPaused contract and writes its address to JSON file.
function run() public {
// Deployer's private key. This key is used to deploy the contract.
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");

// Validate L2GovernorPaused contract if it is implemented correctly so that it may be used as new
// implementation for the proxy contract.
Options memory opts;
opts.referenceContract = "L2Governor.sol";
opts.unsafeAllow = "constructor";
Upgrades.validateUpgrade("L2GovernorPaused.sol", opts);

console2.log("Deploying L2GovernorPaused contract...");

// deploy L2GovernorPaused contract
vm.startBroadcast(deployerPrivateKey);
L2GovernorPaused l2GovernorPaused = new L2GovernorPaused();
vm.stopBroadcast();

assert(address(l2GovernorPaused) != address(0));

// ERC1967Utils: keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
assert(l2GovernorPaused.proxiableUUID() == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));

console2.log("L2GovernorPaused contract successfully deployed!");
console2.log("L2GovernorPaused (Implementation) address: %s", address(l2GovernorPaused));

// write L2GovernorPaused address to l2addresses.json
Utils.L2AddressesConfig memory l2AddressesConfig = utils.readL2AddressesFile();
l2AddressesConfig.L2GovernorPaused = address(l2GovernorPaused);
utils.writeL2AddressesFile(l2AddressesConfig);
}
}
56 changes: 56 additions & 0 deletions script/contracts/L2/paused/L2VotingPowerPaused.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.23;

import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { Upgrades } from "openzeppelin-foundry-upgrades/Upgrades.sol";
import { Options } from "openzeppelin-foundry-upgrades/Options.sol";
import { Script, console2 } from "forge-std/Script.sol";
import { L2VotingPowerPaused } from "src/L2/paused/L2VotingPowerPaused.sol";
import "script/contracts/Utils.sol";

/// @title L2VotingPowerPausedScript - L2VotingPowerPaused contract deployment script
/// @notice This contract is used to deploy L2VotingPowerPaused contract and write its address to JSON file.
contract L2VotingPowerPausedScript is Script {
/// @notice Utils contract which provides functions to read and write JSON files containing L1 and L2 addresses.
Utils utils;

function setUp() public {
utils = new Utils();
}

/// @notice This function deploys L2VotingPowerPaused contract and writes its address to JSON file.
function run() public {
// Deployer's private key. This key is used to deploy the contract.
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");

// Validate L2VotingPowerPaused contract if it is implemented correctly so that it may be used as new
// implementation for the proxy contract.
Options memory opts;
opts.referenceContract = "L2VotingPower.sol";
opts.unsafeAllow = "constructor";
Upgrades.validateUpgrade("L2VotingPowerPaused.sol", opts);

console2.log("Deploying L2VotingPowerPaused contract...");

// deploy L2VotingPowerPaused contract
vm.startBroadcast(deployerPrivateKey);
L2VotingPowerPaused l2VotingPowerPausedImplementation = new L2VotingPowerPaused();
vm.stopBroadcast();

assert(address(l2VotingPowerPausedImplementation) != address(0));

// ERC1967Utils: keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
assert(
l2VotingPowerPausedImplementation.proxiableUUID()
== bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)
);

console2.log("L2VotingPowerPaused contract successfully deployed!");
console2.log("L2VotingPowerPaused (Implementation) address: %s", address(l2VotingPowerPausedImplementation));

// write L2VotingPowerPaused address to l2addresses.json
Utils.L2AddressesConfig memory l2AddressesConfig = utils.readL2AddressesFile();
l2AddressesConfig.L2VotingPowerPaused = address(l2VotingPowerPausedImplementation);
utils.writeL2AddressesFile(l2AddressesConfig);
}
}
16 changes: 14 additions & 2 deletions script/contracts/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ contract Utils is Script {
address L2Governor;
/// @notice The Current implementation of L2 Governor Contract.
address L2GovernorImplementation;
/// @notice The Current implementation of L2GovernorPaused Contract.
address L2GovernorPaused;
/// @notice L2 Lisk token address.
address L2LiskToken;
/// @notice L2 Locking Position contract (in Proxy), which users interact with.
Expand All @@ -51,6 +53,8 @@ contract Utils is Script {
address L2VotingPower;
/// @notice The Current implementation of L2 Voting Power Contract.
address L2VotingPowerImplementation;
/// @notice The Current implementation of L2VotingPowerPaused Contract.
address L2VotingPowerPaused;
}

/// @notice This struct is used to read MerkleRoot from JSON file.
Expand Down Expand Up @@ -174,6 +178,10 @@ contract Utils is Script {
l2AddressesConfig.L2GovernorImplementation = l2GovernorImplementation;
} catch { }

try vm.parseJsonAddress(addressJson, ".L2GovernorPaused") returns (address l2GovernorPaused) {
l2AddressesConfig.L2GovernorPaused = l2GovernorPaused;
} catch { }

try vm.parseJsonAddress(addressJson, ".L2LiskToken") returns (address l2LiskToken) {
l2AddressesConfig.L2LiskToken = l2LiskToken;
} catch { }
Expand Down Expand Up @@ -223,6 +231,9 @@ contract Utils is Script {
) {
l2AddressesConfig.L2VotingPowerImplementation = l2VotingPowerImplementation;
} catch { }
try vm.parseJsonAddress(addressJson, ".L2VotingPowerPaused") returns (address l2VotingPowerPaused) {
l2AddressesConfig.L2VotingPowerPaused = l2VotingPowerPaused;
} catch { }

return l2AddressesConfig;
}
Expand All @@ -237,6 +248,7 @@ contract Utils is Script {
vm.serializeAddress(json, "L2ClaimImplementation", cfg.L2ClaimImplementation);
vm.serializeAddress(json, "L2Governor", cfg.L2Governor);
vm.serializeAddress(json, "L2GovernorImplementation", cfg.L2GovernorImplementation);
vm.serializeAddress(json, "L2GovernorPaused", cfg.L2GovernorPaused);
vm.serializeAddress(json, "L2LiskToken", cfg.L2LiskToken);
vm.serializeAddress(json, "L2LockingPosition", cfg.L2LockingPosition);
vm.serializeAddress(json, "L2LockingPositionImplementation", cfg.L2LockingPositionImplementation);
Expand All @@ -247,8 +259,8 @@ contract Utils is Script {
vm.serializeAddress(json, "L2TimelockController", cfg.L2TimelockController);
vm.serializeAddress(json, "L2VestingWalletImplementation", cfg.L2VestingWalletImplementation);
vm.serializeAddress(json, "L2VotingPower", cfg.L2VotingPower);
string memory finalJson =
vm.serializeAddress(json, "L2VotingPowerImplementation", cfg.L2VotingPowerImplementation);
vm.serializeAddress(json, "L2VotingPowerImplementation", cfg.L2VotingPowerImplementation);
string memory finalJson = vm.serializeAddress(json, "L2VotingPowerPaused", cfg.L2VotingPowerPaused);

finalJson.write(string.concat("deployment/", network, "/l2addresses.json"));
}
Expand Down
68 changes: 68 additions & 0 deletions script/paused/deployPausedDAO.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash

echo "Instructing the shell to exit immediately if any command returns a non-zero exit status..."
set -e
echo "Done."

echo "Navigating to the root directory of the project..."
cd ../../
echo "Done."

echo "Setting environment variables..."
source .env
echo "Done."

echo "Creating $NETWORK directory inside deployment directory..."
if [ -z "$NETWORK" ]
then
echo "NETWORK variable inside .env file is not set. Please set NETWORK environment variable."
exit 1
else
if [ -d "deployment/$NETWORK" ]
then
echo "Directory deployment/$NETWORK already exists."
else
mkdir deployment/$NETWORK
fi
fi
echo "Done."

echo "Cleaning up the build artifacts to be able to deploy the contract..."
forge clean
echo "Done."

echo "Deploying and if enabled verifying L2GovernorPaused smart contract..."
if [ -z "$CONTRACT_VERIFIER" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/contracts/L2/paused/L2GovernorPaused.s.sol:L2GovernorPausedScript
else
if [ $CONTRACT_VERIFIER = "blockscout" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier blockscout --verifier-url $L2_VERIFIER_URL -vvvv script/contracts/L2/paused/L2GovernorPaused.s.sol:L2GovernorPausedScript
fi
if [ $CONTRACT_VERIFIER = "etherscan" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier etherscan --etherscan-api-key="$L2_ETHERSCAN_API_KEY" -vvvv script/contracts/L2/paused/L2GovernorPaused.s.sol:L2GovernorPausedScript
fi
fi
echo "Done."

echo "Cleaning up the build artifacts to be able to deploy the contract..."
forge clean
echo "Done."

echo "Deploying and if enabled verifying L2VotingPowerPaused smart contract..."
if [ -z "$CONTRACT_VERIFIER" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/contracts/L2/paused/L2VotingPowerPaused.s.sol:L2VotingPowerPausedScript
else
if [ $CONTRACT_VERIFIER = "blockscout" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier blockscout --verifier-url $L2_VERIFIER_URL -vvvv script/contracts/L2/paused/L2VotingPowerPaused.s.sol:L2VotingPowerPausedScript
fi
if [ $CONTRACT_VERIFIER = "etherscan" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier etherscan --etherscan-api-key="$L2_ETHERSCAN_API_KEY" -vvvv script/contracts/L2/paused/L2VotingPowerPaused.s.sol:L2VotingPowerPausedScript
fi
fi
echo "Done."
Loading

0 comments on commit 9f95eac

Please sign in to comment.