From bc0f251748afb9da8c2217316406c3840906b018 Mon Sep 17 00:00:00 2001 From: excaliborr Date: Mon, 6 May 2024 07:37:14 -0400 Subject: [PATCH 1/4] chore: initial repo setup --- script/Deploy.sol | 27 +------ src/contracts/Greeter.sol | 59 -------------- src/contracts/OpUSDCBridgeAdapter.sol | 6 ++ src/contracts/OpUSDCFactory.sol | 6 ++ src/contracts/OpUSDCLockbox.sol | 6 ++ src/interfaces/IGreeter.sol | 74 ----------------- src/interfaces/IOpUSDCBridgeAdapter.sol | 4 + src/interfaces/IOpUSDCFactory.sol | 4 + src/interfaces/IOpUSDCLockbox.sol | 4 + test/integration/Greeter.t.sol | 16 ---- test/integration/IntegrationBase.sol | 17 +--- test/unit/Greeter.t.sol | 101 ------------------------ test/unit/OpUSDCLockbox.t.sol | 10 +++ 13 files changed, 43 insertions(+), 291 deletions(-) delete mode 100644 src/contracts/Greeter.sol create mode 100644 src/contracts/OpUSDCBridgeAdapter.sol create mode 100644 src/contracts/OpUSDCFactory.sol create mode 100644 src/contracts/OpUSDCLockbox.sol delete mode 100644 src/interfaces/IGreeter.sol create mode 100644 src/interfaces/IOpUSDCBridgeAdapter.sol create mode 100644 src/interfaces/IOpUSDCFactory.sol create mode 100644 src/interfaces/IOpUSDCLockbox.sol delete mode 100644 test/integration/Greeter.t.sol delete mode 100644 test/unit/Greeter.t.sol create mode 100644 test/unit/OpUSDCLockbox.t.sol diff --git a/script/Deploy.sol b/script/Deploy.sol index b636a6af..c177cf47 100644 --- a/script/Deploy.sol +++ b/script/Deploy.sol @@ -1,33 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.23; -import {Greeter} from 'contracts/Greeter.sol'; import {Script} from 'forge-std/Script.sol'; -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; contract Deploy is Script { - struct DeploymentParams { - string greeting; - IERC20 token; - } - - /// @notice Deployment parameters for each chain - mapping(uint256 _chainId => DeploymentParams _params) internal _deploymentParams; - - function setUp() public { - // Mainnet - _deploymentParams[1] = DeploymentParams('Hello, Mainnet!', IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)); - - // Sepolia - _deploymentParams[11_155_111] = - DeploymentParams('Hello, Sepolia!', IERC20(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6)); - } - - function run() public { - DeploymentParams memory _params = _deploymentParams[block.chainid]; - - vm.startBroadcast(); - new Greeter(_params.greeting, _params.token); - vm.stopBroadcast(); - } +// TODO: Setup } diff --git a/src/contracts/Greeter.sol b/src/contracts/Greeter.sol deleted file mode 100644 index d6c85bb1..00000000 --- a/src/contracts/Greeter.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {IGreeter} from 'interfaces/IGreeter.sol'; -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; - -contract Greeter is IGreeter { - /** - * @notice Empty string for revert checks - * @dev result of doing keccak256(bytes('')) - */ - bytes32 internal constant _EMPTY_STRING = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; - - /// @inheritdoc IGreeter - address public immutable OWNER; - - /// @inheritdoc IGreeter - string public greeting; - - /// @inheritdoc IGreeter - IERC20 public token; - - /** - * @notice Reverts in case the function was not called by the owner of the contract - */ - modifier onlyOwner() { - if (msg.sender != OWNER) { - revert Greeter_OnlyOwner(); - } - _; - } - - /** - * @notice Defines the owner to the msg.sender and sets the initial greeting - * @param _greeting Initial greeting - * @param _token Initial token - */ - constructor(string memory _greeting, IERC20 _token) { - OWNER = msg.sender; - token = _token; - setGreeting(_greeting); - } - - /// @inheritdoc IGreeter - function greet() external view returns (string memory _greeting, uint256 _balance) { - _greeting = greeting; - _balance = token.balanceOf(msg.sender); - } - - /// @inheritdoc IGreeter - function setGreeting(string memory _greeting) public onlyOwner { - if (keccak256(bytes(_greeting)) == _EMPTY_STRING) { - revert Greeter_InvalidGreeting(); - } - - greeting = _greeting; - emit GreetingSet(_greeting); - } -} diff --git a/src/contracts/OpUSDCBridgeAdapter.sol b/src/contracts/OpUSDCBridgeAdapter.sol new file mode 100644 index 00000000..9196146a --- /dev/null +++ b/src/contracts/OpUSDCBridgeAdapter.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +import {IOpUSDCBridgeAdapter} from 'interfaces/IOpUSDCBridgeAdapter.sol'; + +contract OpUSDCBridgeAdapter is IOpUSDCBridgeAdapter {} diff --git a/src/contracts/OpUSDCFactory.sol b/src/contracts/OpUSDCFactory.sol new file mode 100644 index 00000000..8e78df65 --- /dev/null +++ b/src/contracts/OpUSDCFactory.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +import {IOpUSDCLockbox} from 'interfaces/IOpUSDCLockbox.sol'; + +contract OpUSDCFactory is IOpUSDCLockbox {} diff --git a/src/contracts/OpUSDCLockbox.sol b/src/contracts/OpUSDCLockbox.sol new file mode 100644 index 00000000..720d0322 --- /dev/null +++ b/src/contracts/OpUSDCLockbox.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +import {IOpUSDCLockbox} from 'interfaces/IOpUSDCLockbox.sol'; + +contract OpUSDCLockbox is IOpUSDCLockbox {} diff --git a/src/interfaces/IGreeter.sol b/src/interfaces/IGreeter.sol deleted file mode 100644 index 9d75d4be..00000000 --- a/src/interfaces/IGreeter.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; - -/** - * @title Greeter Contract - * @author Wonderland - * @notice This is a basic contract created in order to portray some - * best practices and foundry functionality. - */ -interface IGreeter { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Greeting has changed - * @param _greeting The new greeting - */ - event GreetingSet(string _greeting); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Throws if the function was called by someone else than the owner - */ - error Greeter_OnlyOwner(); - - /** - * @notice Throws if the greeting set is invalid - * @dev Empty string is an invalid greeting - */ - error Greeter_InvalidGreeting(); - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the owner of the contract - * @dev The owner will always be the deployer of the contract - * @return _owner The owner of the contract - */ - function OWNER() external view returns (address _owner); - - /** - * @notice Returns the previously set greeting - * @return _greet The greeting - */ - function greeting() external view returns (string memory _greet); - - /** - * @notice Returns the token used to greet callers - * @return _token The address of the token - */ - function token() external view returns (IERC20 _token); - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - /** - * @notice Sets a new greeting - * @dev Only callable by the owner - * @param _newGreeting The new greeting to be set - */ - function setGreeting(string memory _newGreeting) external; - - /** - * @notice Greets the caller - * @return _greeting The greeting - * @return _balance Current token balance of the caller - */ - function greet() external view returns (string memory _greeting, uint256 _balance); -} diff --git a/src/interfaces/IOpUSDCBridgeAdapter.sol b/src/interfaces/IOpUSDCBridgeAdapter.sol new file mode 100644 index 00000000..ca1d3bc6 --- /dev/null +++ b/src/interfaces/IOpUSDCBridgeAdapter.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +interface IOpUSDCBridgeAdapter {} diff --git a/src/interfaces/IOpUSDCFactory.sol b/src/interfaces/IOpUSDCFactory.sol new file mode 100644 index 00000000..61e5a2ab --- /dev/null +++ b/src/interfaces/IOpUSDCFactory.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +interface IOpUSDCFactory {} diff --git a/src/interfaces/IOpUSDCLockbox.sol b/src/interfaces/IOpUSDCLockbox.sol new file mode 100644 index 00000000..e3dbe072 --- /dev/null +++ b/src/interfaces/IOpUSDCLockbox.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +interface IOpUSDCLockbox {} diff --git a/test/integration/Greeter.t.sol b/test/integration/Greeter.t.sol deleted file mode 100644 index b0e3799d..00000000 --- a/test/integration/Greeter.t.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {IntegrationBase} from 'test/integration/IntegrationBase.sol'; - -contract IntegrationGreeter is IntegrationBase { - function test_Greet() public { - uint256 _whaleBalance = _dai.balanceOf(_daiWhale); - - vm.prank(_daiWhale); - (string memory _greeting, uint256 _balance) = _greeter.greet(); - - assertEq(_whaleBalance, _balance); - assertEq(_initialGreeting, _greeting); - } -} diff --git a/test/integration/IntegrationBase.sol b/test/integration/IntegrationBase.sol index 6aabed61..9d35dbed 100644 --- a/test/integration/IntegrationBase.sol +++ b/test/integration/IntegrationBase.sol @@ -1,23 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.23; -import {Greeter, IGreeter} from 'contracts/Greeter.sol'; import {Test} from 'forge-std/Test.sol'; -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; contract IntegrationBase is Test { - uint256 internal constant _FORK_BLOCK = 18_920_905; + // TODO: Setup - string internal _initialGreeting = 'hola'; - address internal _user = makeAddr('user'); - address internal _owner = makeAddr('owner'); - address internal _daiWhale = 0x42f8CA49E88A8fd8F0bfA2C739e648468b8f9dec; - IERC20 internal _dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); - IGreeter internal _greeter; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), _FORK_BLOCK); - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _dai); - } + function setUp() public {} } diff --git a/test/unit/Greeter.t.sol b/test/unit/Greeter.t.sol deleted file mode 100644 index a06dc74c..00000000 --- a/test/unit/Greeter.t.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {Greeter, IGreeter} from 'contracts/Greeter.sol'; -import {Test} from 'forge-std/Test.sol'; -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; - -abstract contract Base is Test { - address internal _owner = makeAddr('owner'); - - IERC20 internal _token = IERC20(makeAddr('token')); - string internal _initialGreeting = 'hola'; - bytes32 internal _emptyString = keccak256(bytes('')); - Greeter internal _greeter; - - function setUp() public virtual { - vm.etch(address(_token), new bytes(0x1)); // etch bytecode to avoid address collision problems - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _token); - } -} - -contract UnitGreeterConstructor is Base { - function test_OwnerSet(address _owner) public { - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _token); - - assertEq(_greeter.OWNER(), _owner); - } - - function test_TokenSet(IERC20 _token) public { - _greeter = new Greeter(_initialGreeting, _token); - - assertEq(address(_greeter.token()), address(_token)); - } - - function test_GreetingSet(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - - _greeter = new Greeter(_greeting, _token); - assertEq(_greeting, _greeter.greeting()); - } -} - -contract UnitGreeterSetGreeting is Base { - event GreetingSet(string _greeting); - - function setUp() public override { - super.setUp(); - vm.startPrank(_owner); - } - - function test_RevertIfNotOwner(address _caller, string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - vm.assume(_caller != _owner); - - vm.stopPrank(); - vm.prank(_caller); - - vm.expectRevert(IGreeter.Greeter_OnlyOwner.selector); - _greeter.setGreeting(_greeting); - } - - function test_RevertIfEmptyGreeting() public { - vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); - _greeter.setGreeting(''); - } - - function test_SetGreeting(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - _greeter.setGreeting(_greeting); - - assertEq(_greeting, _greeter.greeting()); - } - - function test_EmitEvent(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - - vm.expectEmit(true, true, true, true, address(_greeter)); - emit GreetingSet(_greeting); - - _greeter.setGreeting(_greeting); - } -} - -contract UnitGreeterGreet is Base { - function test_GetGreeting() public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(0)); - - (string memory _greeting,) = _greeter.greet(); - assertEq(_initialGreeting, _greeting); - } - - function test_GetTokenBalance(address _caller, uint256 _balance) public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector, _caller), abi.encode(_balance)); - - vm.prank(_caller); - (, uint256 _greetBalance) = _greeter.greet(); - assertEq(_balance, _greetBalance); - } -} diff --git a/test/unit/OpUSDCLockbox.t.sol b/test/unit/OpUSDCLockbox.t.sol new file mode 100644 index 00000000..5e2c3598 --- /dev/null +++ b/test/unit/OpUSDCLockbox.t.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +import {Test} from 'forge-std/Test.sol'; + +abstract contract Base is Test { + // TODO: Setup + + function setUp() public virtual {} +} From 6764ca455c0c06dba2cb3a39362cc8699bc0527b Mon Sep 17 00:00:00 2001 From: excaliborr Date: Mon, 6 May 2024 07:40:24 -0400 Subject: [PATCH 2/4] chore: package.json --- package.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 6f9c2477..ec1f8e16 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,7 @@ { - "name": "solidity-foundry-boilerplate", + "name": "op-usdc", "version": "1.0.0", - "description": "Production ready Solidity boilerplate with Foundry", - "homepage": "https://github.com/defi-wonderland/solidity-foundry-boilerplate#readme", - "repository": { - "type": "git", - "url": "git+https://github.com/defi-wonderland/solidity-foundry-boilerplate.git" - }, + "description": "opUSDC, a USDC bridge for any op-chain's canonical bridge", "license": "MIT", "author": "Wonderland", "scripts": { From 6b846d2606833b51f4cd75606d3f87db7612eaaa Mon Sep 17 00:00:00 2001 From: excaliborr Date: Mon, 6 May 2024 07:45:34 -0400 Subject: [PATCH 3/4] fix: workflow --- test/unit/OpUSDCLockbox.t.sol | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/unit/OpUSDCLockbox.t.sol b/test/unit/OpUSDCLockbox.t.sol index 5e2c3598..21cc0a43 100644 --- a/test/unit/OpUSDCLockbox.t.sol +++ b/test/unit/OpUSDCLockbox.t.sol @@ -8,3 +8,18 @@ abstract contract Base is Test { function setUp() public virtual {} } + +// TODO: Delete this, it needs to be here for workflow to pass for now +contract UnitTest is Base { + function testTest() public { + uint256 _num = 1; + assertEq(_num, _num); + } +} + +contract IntegrationTest is Base { + function testTest() public { + uint256 _num = 1; + assertEq(_num, _num); + } +} From 9477a02c8abb99ea62dc8f32127eb73f70c17b4e Mon Sep 17 00:00:00 2001 From: excaliborr Date: Mon, 6 May 2024 08:55:31 -0400 Subject: [PATCH 4/4] chore: version bump --- foundry.toml | 2 +- script/Deploy.sol | 2 +- src/contracts/OpUSDCBridgeAdapter.sol | 2 +- src/contracts/OpUSDCFactory.sol | 2 +- src/contracts/OpUSDCLockbox.sol | 2 +- src/interfaces/IOpUSDCBridgeAdapter.sol | 2 +- src/interfaces/IOpUSDCFactory.sol | 2 +- src/interfaces/IOpUSDCLockbox.sol | 2 +- test/integration/IntegrationBase.sol | 2 +- test/unit/OpUSDCLockbox.t.sol | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/foundry.toml b/foundry.toml index 36091d8b..992a4c89 100644 --- a/foundry.toml +++ b/foundry.toml @@ -9,7 +9,7 @@ multiline_func_header = 'params_first' sort_imports = true [profile.default] -solc_version = '0.8.23' +solc_version = '0.8.25' libs = ['node_modules'] optimizer_runs = 10_000 diff --git a/script/Deploy.sol b/script/Deploy.sol index c177cf47..fbbb810c 100644 --- a/script/Deploy.sol +++ b/script/Deploy.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; import {Script} from 'forge-std/Script.sol'; diff --git a/src/contracts/OpUSDCBridgeAdapter.sol b/src/contracts/OpUSDCBridgeAdapter.sol index 9196146a..aa9776ea 100644 --- a/src/contracts/OpUSDCBridgeAdapter.sol +++ b/src/contracts/OpUSDCBridgeAdapter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; import {IOpUSDCBridgeAdapter} from 'interfaces/IOpUSDCBridgeAdapter.sol'; diff --git a/src/contracts/OpUSDCFactory.sol b/src/contracts/OpUSDCFactory.sol index 8e78df65..09ad96a3 100644 --- a/src/contracts/OpUSDCFactory.sol +++ b/src/contracts/OpUSDCFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; import {IOpUSDCLockbox} from 'interfaces/IOpUSDCLockbox.sol'; diff --git a/src/contracts/OpUSDCLockbox.sol b/src/contracts/OpUSDCLockbox.sol index 720d0322..14652c5a 100644 --- a/src/contracts/OpUSDCLockbox.sol +++ b/src/contracts/OpUSDCLockbox.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; import {IOpUSDCLockbox} from 'interfaces/IOpUSDCLockbox.sol'; diff --git a/src/interfaces/IOpUSDCBridgeAdapter.sol b/src/interfaces/IOpUSDCBridgeAdapter.sol index ca1d3bc6..3c0d69bf 100644 --- a/src/interfaces/IOpUSDCBridgeAdapter.sol +++ b/src/interfaces/IOpUSDCBridgeAdapter.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; interface IOpUSDCBridgeAdapter {} diff --git a/src/interfaces/IOpUSDCFactory.sol b/src/interfaces/IOpUSDCFactory.sol index 61e5a2ab..13c796eb 100644 --- a/src/interfaces/IOpUSDCFactory.sol +++ b/src/interfaces/IOpUSDCFactory.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; interface IOpUSDCFactory {} diff --git a/src/interfaces/IOpUSDCLockbox.sol b/src/interfaces/IOpUSDCLockbox.sol index e3dbe072..899bd5f3 100644 --- a/src/interfaces/IOpUSDCLockbox.sol +++ b/src/interfaces/IOpUSDCLockbox.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; interface IOpUSDCLockbox {} diff --git a/test/integration/IntegrationBase.sol b/test/integration/IntegrationBase.sol index 9d35dbed..62b292e3 100644 --- a/test/integration/IntegrationBase.sol +++ b/test/integration/IntegrationBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; import {Test} from 'forge-std/Test.sol'; diff --git a/test/unit/OpUSDCLockbox.t.sol b/test/unit/OpUSDCLockbox.t.sol index 21cc0a43..1ef46efa 100644 --- a/test/unit/OpUSDCLockbox.t.sol +++ b/test/unit/OpUSDCLockbox.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.25; import {Test} from 'forge-std/Test.sol';