diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 600c7ea..6818a08 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,6 @@ - [Code Style](#code-style) - [Interfaces](#interfaces) - [NatSpec \& Comments](#natspec--comments) -- [Versioning](#versioning) - [Testing](#testing) - [Gas Metering](#gas-metering) - [Deployment](#deployment) @@ -45,15 +44,15 @@ This section outlines the branching strategy of this repo. ### Main -The main branch is supposed to reflect the deployed state on all networks. Any pull requests into this branch MUST come from the staging branch. The main branch is protected and requires a separate code review by the security team. Whenever the main branch is updated, a new release is created with the latest version. For more information on versioning, check [here](#versioning). +The main branch is supposed to reflect the deployed state on all networks. Any pull requests into this branch MUST come from the staging branch. ### Staging -The staging branch reflects new code complete deployments or upgrades containing fixes and/or features. Any pull requests into this branch MUST come from the dev branch. The staging branch is used for security audits and deployments. Once the deployment is complete and deployment log files are generated, the branch can be merged into main. For more information on the deployment and log file generation check [here](#deployment--versioning). +The staging branch reflects new code complete deployments or upgrades containing fixes and/or features. Any pull requests into this branch MUST come from the dev branch. The staging branch is used for security audits and deployments. Once the deployment is complete and verified as well as deployment log files are generated, the branch can be merged into main. For more information on the deployment and log file generation check [here](#deployment). ### Dev -This is the active development branch. All pull requests into this branch MUST come from fix or feature branches. Upon code completion this branch is merged into staging for auditing and deployment. +This is the active development branch. All pull requests into this branch MUST come from fix or feature branches. Upon code completion this branch is merged into staging for auditing and deployment. PRs into this branch should squash all commits into a single commit. ### Feature @@ -114,12 +113,6 @@ Every contract MUST implement their corresponding interface that includes all ex Interfaces should be the entrypoint for all contracts. When exploring the a contract within the repository, the interface MUST contain all relevant information to understand the functionality of the contract in the form of NatSpec comments. This includes all externally callable functions, errors and events. The NatSpec documentation MUST be added to the functions, errors and events within the interface. This allows a reader to understand the functionality of a function before moving on to the implementation. The implementing functions MUST point to the NatSpec documentation in the interface using `@inheritdoc`. Internal and private functions shouldn't have NatSpec documentation except for `@dev` comments, whenever more context is needed. Additional comments within a function should only be used to give more context to more complex operations, otherwise the code should be kept readable and self-explanatory. -## Versioning - -This repo utilizes [semantic versioning](https://semver.org/) for smart contracts. An `IVersioned` interface is included in the [interfaces directory](src/interface/IVersioned.sol) exposing a unified versioning interface for all contracts. This version MUST be included in all contracts, whether they are upgradeable or not, to be able to easily match deployed versions. For example, in the case of a non-upgradeable contract one version could be deployed to a network and later a new version might be deployed to another network. The exposed `version()` function is also used by the [Deployment Log Generator](https://github.com/0xPolygon/forge-chronicles#readme) to extract information about the version. - -Whenever contracts are modified, only the version of the changed contracts should be updated. Unmodified contracts should remain on the version of their last change. - ## Testing The following testing practices should be followed when writing unit tests for new code. All functions, lines and branches should be tested to result in 100% testing coverage. Fuzz parameters and conditions whenever possible. Extremes should be tested in dedicated edge case and corner case tests. Invariants should be tested in dedicated invariant tests. @@ -140,7 +133,7 @@ When adding new functionality, a new gas snapshot should be added, preferably us ## Deployment -This repo utilizes versioned deployments. Any changes to a contract should update the version of this specific contract. A script is provided that extracts deployment information from the `run-latest.json` file within the `broadcast` directory generated while the forge script runs. From this information a JSON and markdown file is generated containing various information about the deployment itself as well as past deployments. +After deployments are executed a script is provided that extracts deployment information from the `run-latest.json` file within the `broadcast` directory generated while the forge script runs. From this information a JSON and markdown file is generated using the [Forge Chronicles](https://github.com/0xPolygon/forge-chronicles) library containing various information about the deployment itself as well as past deployments. ### Deployment diff --git a/docs/autogen/src/README.md b/docs/autogen/src/README.md index b37b8a2..2f046dc 100644 --- a/docs/autogen/src/README.md +++ b/docs/autogen/src/README.md @@ -1,6 +1,5 @@ ## Template Repo (Foundry) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![CI Status](../../actions/workflows/test.yaml/badge.svg)](../../actions) This template repo is a quick and easy way to get started with a new Solidity project. It comes with a number of features that are useful for developing and deploying smart contracts. Such as: @@ -14,7 +13,6 @@ This template repo is a quick and easy way to get started with a new Solidity pr - [Deployment](#deployment) - [Docs](#docs) - [Contributing](#contributing) -- [License](#license) ## Setup diff --git a/docs/autogen/src/SUMMARY.md b/docs/autogen/src/SUMMARY.md index 1c37b0f..332e1a1 100644 --- a/docs/autogen/src/SUMMARY.md +++ b/docs/autogen/src/SUMMARY.md @@ -3,5 +3,4 @@ # src - [❱ interface](src/interface/README.md) - [ICounter](src/interface/ICounter.sol/interface.ICounter.md) - - [IVersioned](src/interface/IVersioned.sol/interface.IVersioned.md) - [Counter](src/Counter.sol/contract.Counter.md) diff --git a/docs/autogen/src/src/Counter.sol/contract.Counter.md b/docs/autogen/src/src/Counter.sol/contract.Counter.md index 812857a..0366122 100644 --- a/docs/autogen/src/src/Counter.sol/contract.Counter.md +++ b/docs/autogen/src/src/Counter.sol/contract.Counter.md @@ -1,8 +1,8 @@ # Counter -[Git Source](https://github.com/gretzke/foundry-template/blob/952489c408f511dc764c05d3a2a21ded78da224f/src/Counter.sol) +[Git Source](https://github.com/Uniswap/foundry-template/blob/6ed2d53f10b4739f84426a12bef01482d7a2e669/src/Counter.sol) **Inherits:** -[ICounter](/src/interface/ICounter.sol/interface.ICounter.md), Initializable +[ICounter](/src/interface/ICounter.sol/interface.ICounter.md) ## State Variables @@ -18,14 +18,7 @@ uint256 public number; ```solidity -constructor(); -``` - -### initialize - - -```solidity -function initialize(uint256 initialNumber) public initializer; +constructor(uint256 initialNumber); ``` ### setNumber @@ -52,16 +45,3 @@ Increments the number by 1 function increment() public; ``` -### version - - -```solidity -function version() external pure returns (string memory); -``` -**Returns** - -|Name|Type|Description| -|----|----|-----------| -|``|`string`|The version of the contract| - - diff --git a/docs/autogen/src/src/interface/ICounter.sol/interface.ICounter.md b/docs/autogen/src/src/interface/ICounter.sol/interface.ICounter.md index c93d387..98a74ba 100644 --- a/docs/autogen/src/src/interface/ICounter.sol/interface.ICounter.md +++ b/docs/autogen/src/src/interface/ICounter.sol/interface.ICounter.md @@ -1,8 +1,5 @@ # ICounter -[Git Source](https://github.com/gretzke/foundry-template/blob/952489c408f511dc764c05d3a2a21ded78da224f/src/interface/ICounter.sol) - -**Inherits:** -[IVersioned](/src/interface/IVersioned.sol/interface.IVersioned.md) +[Git Source](https://github.com/Uniswap/foundry-template/blob/6ed2d53f10b4739f84426a12bef01482d7a2e669/src/interface/ICounter.sol) ## Functions diff --git a/docs/autogen/src/src/interface/README.md b/docs/autogen/src/src/interface/README.md index b060352..c06ad63 100644 --- a/docs/autogen/src/src/interface/README.md +++ b/docs/autogen/src/src/interface/README.md @@ -2,4 +2,3 @@ # Contents - [ICounter](ICounter.sol/interface.ICounter.md) -- [IVersioned](IVersioned.sol/interface.IVersioned.md) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index aa12e13..eba43ad 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.23; import "forge-std/Script.sol"; -import "script/deployers/CounterDeployer.s.sol"; -contract Deploy is Script, CounterDeployer { +import {Counter} from "src/Counter.sol"; + +contract Deploy is Script { using stdJson for string; function run() public { - address proxyAdmin = address(1); uint256 initialNumber = 5; - deployCounterTransparent(proxyAdmin, initialNumber); + new Counter(initialNumber); } } diff --git a/script/deployers/CounterDeployer.s.sol b/script/deployers/CounterDeployer.s.sol deleted file mode 100644 index a99f915..0000000 --- a/script/deployers/CounterDeployer.s.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -//////////////////////////////////////////////////// -// AUTOGENERATED - DO NOT EDIT THIS FILE DIRECTLY // -//////////////////////////////////////////////////// - -import "forge-std/Script.sol"; - -import "src/Counter.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy, ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -abstract contract CounterDeployer is Script { - Counter internal counter; - ProxyAdmin internal counterProxyAdmin; - address internal counterImplementation; - - function deployCounterTransparent(address proxyAdminOwner, uint256 initialNumber) - internal - returns (address implementation, address proxyAdmin, address proxy) - { - bytes memory initData = abi.encodeCall(Counter.initialize, (initialNumber)); - - vm.startBroadcast(vm.envUint("PRIVATE_KEY")); - - counterImplementation = address(new Counter()); - counter = Counter(address(new TransparentUpgradeableProxy(counterImplementation, proxyAdminOwner, initData))); - - vm.stopBroadcast(); - - counterProxyAdmin = - ProxyAdmin(address(uint160(uint256(vm.load(address(counter), hex"b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"))))); - - return (counterImplementation, address(counterProxyAdmin), address(counter)); - } - - function deployCounterImplementation() internal returns (address implementation) { - vm.startBroadcast(vm.envUint("PRIVATE_KEY")); - implementation = address(new Counter()); - vm.stopBroadcast(); - } -} diff --git a/src/Counter.sol b/src/Counter.sol index cd8a490..971baf7 100644 --- a/src/Counter.sol +++ b/src/Counter.sol @@ -1,17 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.23; -import {ICounter, IVersioned} from "./interface/ICounter.sol"; -import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {ICounter} from "./interface/ICounter.sol"; -contract Counter is ICounter, Initializable { +contract Counter is ICounter { uint256 public number; - constructor() { - _disableInitializers(); - } - - function initialize(uint256 initialNumber) public initializer { + constructor(uint256 initialNumber) { number = initialNumber; } @@ -24,9 +19,4 @@ contract Counter is ICounter, Initializable { function increment() public { number++; } - - /// @inheritdoc IVersioned - function version() external pure returns (string memory) { - return "1.0.0"; - } } diff --git a/src/interface/ICounter.sol b/src/interface/ICounter.sol index fdc0001..709181b 100644 --- a/src/interface/ICounter.sol +++ b/src/interface/ICounter.sol @@ -1,9 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.23; -import {IVersioned} from "./IVersioned.sol"; - -interface ICounter is IVersioned { +interface ICounter { /// @return The current number function number() external view returns (uint256); diff --git a/src/interface/IVersioned.sol b/src/interface/IVersioned.sol deleted file mode 100644 index 0e4eecf..0000000 --- a/src/interface/IVersioned.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.23; - -interface IVersioned { - /// @return The version of the contract - function version() external pure returns (string memory); -} diff --git a/test/Counter.t.sol b/test/Counter.t.sol index 384fb47..12eb00d 100644 --- a/test/Counter.t.sol +++ b/test/Counter.t.sol @@ -4,43 +4,22 @@ pragma solidity 0.8.23; import "forge-std/Test.sol"; import "test/util/TestHelpers.sol"; -import "script/deployers/CounterDeployer.s.sol"; +import {Counter} from "src/Counter.sol"; -abstract contract BeforeScript is Test, TestHelpers, CounterDeployer { - function setUp() public virtual { - counter = Counter(deployCounterImplementation()); - } -} - -contract CounterTest_Zero is BeforeScript { - function test_InitialState() public { - assertEq(counter.number(), 0); - } - - function test_RevertsOnInitialization(uint256 number) public { - vm.expectRevert(Initializable.InvalidInitialization.selector); - counter.initialize(number); - } -} +abstract contract Deployed is Test, TestHelpers { + Counter counter; -abstract contract AfterScript is Test, TestHelpers, CounterDeployer { function setUp() public virtual { - address proxyAdmin = makeAddr("alice"); uint256 initialNumber = 10; - deployCounterTransparent(proxyAdmin, initialNumber); + counter = new Counter(initialNumber); } } -contract CounterTest_Initialized is AfterScript { +contract CounterTest_Deployed is Deployed { function test_IsInitialized() public { assertEq(counter.number(), 10); } - function test_RevertsIf_InitializedAgain() public { - vm.expectRevert(Initializable.InvalidInitialization.selector); - counter.initialize(1); - } - function test_IncrementsNumber() public { counter.increment(); assertEq(counter.number(), 11); @@ -50,8 +29,4 @@ contract CounterTest_Initialized is AfterScript { counter.setNumber(x); assertEq(counter.number(), x); } - - function test_ReturnsVersion() public { - assertEq(counter.version(), "1.0.0"); - } }