diff --git a/.env.example b/.env.example index 544add783..0f0a948d9 100644 --- a/.env.example +++ b/.env.example @@ -74,5 +74,8 @@ GAS_MULTIPLIER=110 ################################ # Miscellaneous Configurations # ################################ +# The file name from which to read the list of addresses to blacklist +BLACKLIST_FILE_NAME=blacklist.remote.json + # [OPTIONAL] The API key to an Etherscan flavor block explorer. # ETHERSCAN_KEY= diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 648bdabf0..b25ca126f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: run: yarn contract-size - name: Run forge tests - run: forge test + run: forge test -vvv - name: Generate gas report run: yarn gas-report @@ -97,7 +97,9 @@ jobs: scan: if: github.event_name == 'pull_request' - uses: circlefin/circle-public-github-workflows/.github/workflows/pr-scan.yaml@v1 + uses: circlefin/circle-public-github-workflows/.github/workflows/pr-scan.yaml@v1.2.0 + with: + allow-reciprocal-licenses: false release-sbom: if: github.event_name == 'push' diff --git a/.licenseignore b/.licenseignore index 45cef508b..342eb3d7e 100644 --- a/.licenseignore +++ b/.licenseignore @@ -1,3 +1,36 @@ pkg:npm/pako pkg:npm/highlightjs-solidity pkg:npm/ethereum-ens +pkg:npm/%40ethereumjs/rlp@4.0.1 +pkg:npm/%40ethereumjs/util@8.1.0 +pkg:npm/%40nomicfoundation/ethereumjs-block@5.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-blockchain@7.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-ethash@3.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-evm@2.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-rlp@5.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-statemanager@2.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-trie@6.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-tx@5.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-util@9.0.2 +pkg:npm/%40nomicfoundation/ethereumjs-vm@7.0.2 +pkg:npm/web3@1.10.1 +pkg:npm/web3-bzz@1.10.1 +pkg:npm/web3-core@1.10.1 +pkg:npm/web3-core-helpers@1.10.1 +pkg:npm/web3-core-method@1.10.1 +pkg:npm/web3-core-promievent@1.10.1 +pkg:npm/web3-core-requestmanager@1.10.1 +pkg:npm/web3-core-subscriptions@1.10.1 +pkg:npm/web3-eth@1.10.1 +pkg:npm/web3-eth-abi@1.10.1 +pkg:npm/web3-eth-accounts@1.10.1 +pkg:npm/web3-eth-contract@1.10.1 +pkg:npm/web3-eth-ens@1.10.1 +pkg:npm/web3-eth-iban@1.10.1 +pkg:npm/web3-eth-personal@1.10.1 +pkg:npm/web3-net@1.10.1 +pkg:npm/web3-providers-http@1.10.1 +pkg:npm/web3-providers-ipc@1.10.1 +pkg:npm/web3-providers-ws@1.10.1 +pkg:npm/web3-shh@1.10.1 +pkg:npm/web3-utils@1.10.1 diff --git a/foundry.toml b/foundry.toml index 853f16d2e..d80a8a9f0 100644 --- a/foundry.toml +++ b/foundry.toml @@ -28,7 +28,10 @@ remappings = [ "forge-std/=lib/forge-std/src", "@openzeppelin/=node_modules/@openzeppelin/", ] -fs_permissions = [{ access = "read-write", path = "blacklist.remote.json"}] # https://book.getfoundry.sh/cheatcodes/fs +fs_permissions = [ + { access = "read-write", path = "blacklist.remote.json"}, + { access = "read-write", path = "test.blacklist.remote.json"} +] # https://book.getfoundry.sh/cheatcodes/fs [rpc_endpoints] testnet = "${TESTNET_RPC_URL}" diff --git a/scripts/deploy/ScriptUtils.sol b/scripts/deploy/ScriptUtils.sol new file mode 100644 index 000000000..e3db1c094 --- /dev/null +++ b/scripts/deploy/ScriptUtils.sol @@ -0,0 +1,40 @@ +/** + * Copyright 2024 Circle Internet Financial, LTD. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376 + +import { Script } from "forge-std/Script.sol"; + +/** + * Shared utilities for scripts. It inherits the Script contract in order + * to access vm cheatcodes. + */ +contract ScriptUtils is Script { + /** + * @notice helper function that loads local json + */ + function _loadAccountsToBlacklist(string memory blacklistFileName) + internal + view + returns (address[] memory) + { + string memory json = vm.readFile(blacklistFileName); + return vm.parseJsonAddressArray(json, ""); + } +} diff --git a/scripts/deploy/deploy-impl-and-upgrader.s.sol b/scripts/deploy/deploy-impl-and-upgrader.s.sol index 82a62f281..ad58ee4dd 100644 --- a/scripts/deploy/deploy-impl-and-upgrader.s.sol +++ b/scripts/deploy/deploy-impl-and-upgrader.s.sol @@ -20,6 +20,7 @@ pragma solidity 0.6.12; import "forge-std/console.sol"; // solhint-disable no-global-import, no-console import { Script } from "forge-std/Script.sol"; +import { ScriptUtils } from "./ScriptUtils.sol"; import { DeployImpl } from "./DeployImpl.sol"; import { FiatTokenProxy } from "../../contracts/v1/FiatTokenProxy.sol"; import { FiatTokenV2_2 } from "../../contracts/v2/FiatTokenV2_2.sol"; @@ -29,8 +30,9 @@ import { V2_2Upgrader } from "../../contracts/v2/upgrader/V2_2Upgrader.sol"; * A utility script to deploy the latest fiat token implementation and * an upgrader contract that updates fiat token use the latest implementation */ -contract DeployImplAndUpgrader is Script, DeployImpl { +contract DeployImplAndUpgrader is Script, DeployImpl, ScriptUtils { string private newTokenSymbol; + string private blacklistFileName; address private impl; address payable private proxyContractAddress; address private proxyAdmin; @@ -55,7 +57,8 @@ contract DeployImplAndUpgrader is Script, DeployImpl { vm.envAddress("OWNER_ADDRESS") ); - accountsToBlacklist = loadAccountsToBlacklist(); + blacklistFileName = vm.envString("BLACKLIST_FILE_NAME"); + accountsToBlacklist = _loadAccountsToBlacklist(blacklistFileName); deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY"); @@ -64,19 +67,7 @@ contract DeployImplAndUpgrader is Script, DeployImpl { console.log("FIAT_TOKEN_PROXY_ADDRESS: '%s'", proxyContractAddress); console.log("PROXY_ADMIN_ADDRESS: '%s'", proxyAdmin); console.log("LOST_AND_FOUND_ADDRESS: '%s'", lostAndFound); - } - - /** - * @notice helper function that loads local json - */ - function loadAccountsToBlacklist() - internal - view - returns (address[] memory) - { - string memory path = "blacklist.remote.json"; - string memory json = vm.readFile(path); - return vm.parseJsonAddressArray(json, ""); + console.log("BLACKLIST_FILE_NAME: '%s'", blacklistFileName); } /** diff --git a/test.blacklist.remote.json b/test.blacklist.remote.json new file mode 100644 index 000000000..0fed0f822 --- /dev/null +++ b/test.blacklist.remote.json @@ -0,0 +1,4 @@ +[ + "0x04DBA1194ee10112fE6C3207C0687DEf0e78baCf", + "0xb6f5ec1A0a9cd1526536D3F0426c429529471F40" +] diff --git a/test/scripts/deploy/TestUtils.sol b/test/scripts/deploy/TestUtils.sol index 64528196b..e67cf4580 100644 --- a/test/scripts/deploy/TestUtils.sol +++ b/test/scripts/deploy/TestUtils.sol @@ -29,15 +29,31 @@ import { contract TestUtils is Test { uint256 internal deployerPrivateKey = 1; + uint256 internal proxyAdminPrivateKey = 2; + uint256 internal masterMinterOwnerPrivateKey = 3; + uint256 internal ownerPrivateKey = 4; + uint256 internal pauserPrivateKey = 5; + uint256 internal blacklisterPrivateKey = 6; + uint256 internal lostAndFoundPrivateKey = 7; + + address internal deployer = vm.addr(deployerPrivateKey); + address internal proxyAdmin = vm.addr(proxyAdminPrivateKey); + address internal masterMinterOwner = vm.addr(masterMinterOwnerPrivateKey); + address internal owner = vm.addr(ownerPrivateKey); + address internal pauser = vm.addr(pauserPrivateKey); + address internal blacklister = vm.addr(blacklisterPrivateKey); + address internal lostAndFound = vm.addr(lostAndFoundPrivateKey); + + uint8 internal decimals = 6; string internal tokenName = "USDC"; string internal tokenSymbol = "USDC"; - address internal proxyAdmin = vm.addr(2); - address internal masterMinterOwner = vm.addr(3); - address internal owner = vm.addr(4); - address internal pauser = vm.addr(5); - address internal blacklister = vm.addr(6); - address internal lostAndFound = vm.addr(7); - address[] internal accountsToBlacklist = new address[](0); + + string internal blacklistFileName = "test.blacklist.remote.json"; + + address[] internal accountsToBlacklist = [ + 0x04DBA1194ee10112fE6C3207C0687DEf0e78baCf, + 0xb6f5ec1A0a9cd1526536D3F0426c429529471F40 + ]; function setUp() public virtual { vm.setEnv("TOKEN_NAME", tokenName); @@ -56,12 +72,13 @@ contract TestUtils is Test { vm.setEnv("LOST_AND_FOUND_ADDRESS", vm.toString(lostAndFound)); // Deploy an instance of proxy contract to configure contract address in env + vm.startPrank(deployer); FiatTokenV1 v1 = new FiatTokenV1(); FiatTokenProxy proxy = new FiatTokenProxy(address(v1)); + vm.stopPrank(); vm.setEnv("FIAT_TOKEN_PROXY_ADDRESS", vm.toString(address(proxy))); - // Write accountsToBlacklist to local blacklist.remote.json - vm.writeJson("[]", "blacklist.remote.json"); + vm.setEnv("BLACKLIST_FILE_NAME", blacklistFileName); } function validateImpl(FiatTokenV1 impl) internal { diff --git a/test/scripts/deploy/deploy-fiat-token.t.sol b/test/scripts/deploy/deploy-fiat-token.t.sol index 223f0873f..2c81c96fb 100644 --- a/test/scripts/deploy/deploy-fiat-token.t.sol +++ b/test/scripts/deploy/deploy-fiat-token.t.sol @@ -34,6 +34,8 @@ contract DeployFiatTokenTest is TestUtils { function setUp() public override { TestUtils.setUp(); + + vm.prank(deployer); deployScript = new DeployFiatToken(); deployScript.setUp(); } @@ -51,6 +53,7 @@ contract DeployFiatTokenTest is TestUtils { } function test_deployFiatTokenWithPredeployedImpl() public { + vm.prank(deployer); FiatTokenV2_2 predeployedImpl = new FiatTokenV2_2(); (, MasterMinter masterMinter, FiatTokenProxy proxy) = deployScript diff --git a/test/scripts/deploy/deploy-impl-and-upgrader.t.sol b/test/scripts/deploy/deploy-impl-and-upgrader.t.sol index 71d14bc5f..35f460680 100644 --- a/test/scripts/deploy/deploy-impl-and-upgrader.t.sol +++ b/test/scripts/deploy/deploy-impl-and-upgrader.t.sol @@ -29,14 +29,17 @@ import { V2_2Upgrader } from "../../../contracts/v2/upgrader/V2_2Upgrader.sol"; // solhint-disable func-name-mixedcase contract DeployImplAndUpgraderTest is TestUtils { + DeployImplAndUpgrader private deployScript; + function setUp() public override { TestUtils.setUp(); - } - function test_DeployImplAndUpgraderWithAllEnvConfigured() public { - DeployImplAndUpgrader deployScript = new DeployImplAndUpgrader(); + vm.prank(deployer); + deployScript = new DeployImplAndUpgrader(); deployScript.setUp(); + } + function test_DeployImplAndUpgraderWithAllEnvConfigured() public { (FiatTokenV2_2 v2_2, V2_2Upgrader upgrader) = deployScript.run(); validateImpl(v2_2); @@ -48,9 +51,8 @@ contract DeployImplAndUpgraderTest is TestUtils { } function test_DeployImplAndUpgraderWithPredeployedImpl() public { + vm.prank(deployer); FiatTokenV2_2 predeployedImpl = new FiatTokenV2_2(); - DeployImplAndUpgrader deployScript = new DeployImplAndUpgrader(); - deployScript.setUp(); (, V2_2Upgrader upgrader) = deployScript.deploy( address(predeployedImpl) diff --git a/test/scripts/deploy/deploy-master-minter.t.sol b/test/scripts/deploy/deploy-master-minter.t.sol index 822e2d8c2..9278f3c28 100644 --- a/test/scripts/deploy/deploy-master-minter.t.sol +++ b/test/scripts/deploy/deploy-master-minter.t.sol @@ -32,11 +32,13 @@ contract DeployMasterMinterTest is TestUtils { function setUp() public override { TestUtils.setUp(); - } - function test_deployMasterMinter() public { + vm.prank(deployer); deployScript = new DeployMasterMinter(); deployScript.setUp(); + } + + function test_deployMasterMinter() public { MasterMinter masterMinter = deployScript.run(); validateMasterMinter(