diff --git a/contracts/.env.example b/contracts/.env.example index ee1e6e241..25b3c3434 100644 --- a/contracts/.env.example +++ b/contracts/.env.example @@ -1,6 +1,10 @@ PRIVATE_KEY= CREATE2_SALT= +### Roles +GUARDIAN= +PROVER= + ### Guardian & Timelock GUARDIAN_OWNERS= MINIMUM_DELAY= diff --git a/contracts/README.md b/contracts/README.md index c287877d0..f56cc78a3 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -22,8 +22,10 @@ forge test ## Addresses -SUCCINCT_GATEWAY=[0x6e4f1e9ea315ebfd69d18c2db974eef6105fb803](https://etherscan.io/address/0x6e4f1e9ea315ebfd69d18c2db974eef6105fb803) -SUCCINCT_FEE_VAULT=[0x5999d401444f15d262fdce310bb68bd234de11aa](https://etherscan.io/address/0x5999d401444f15d262fdce310bb68bd234de11aa) +`SUCCINCT_GATEWAY`=[0x6c7a05e0AE641c6559fD76ac56641778B6eCd776](https://etherscan.io/address/0x6c7a05e0AE641c6559fD76ac56641778B6eCd776) +`SUCCINCT_FEE_VAULT`=[0x296666e937b270193B960a7cEC526B351F353166](https://etherscan.io/address/0x296666e937b270193B960a7cEC526B351F353166) + +If the contracts are not deployed on a chain you need, you can deploy them yourself using the deployment instructions below or by contracting Succinct. ## Deploying @@ -44,7 +46,7 @@ Contract verification will be automatically applied during deployment. However, For example, to verify both the proxy and implementation contract of SuccinctGateway (both of which have no `constructor_args`) on Chains 5, 420, 84531, and 421613, you would run: ```sh -./script/verify.sh "SuccinctGateway" "5 420 84531 421613" "true" +./script/verify.sh "SuccinctGateway" "5 420 84531 421613" "true" ``` ## Upgrading @@ -59,7 +61,7 @@ Timelocked upgrades take place in two parts (`schedule` and then `execute` after #### Step 1: Deploy a new implementation contract -Re-deploy the new contract via `script/deploy.sh`. This will generate a new `*_IMPL` implementation contract address with the current contract code. +Re-deploy the new contract via `script/deploy.sh`. This will generate a new `*_IMPL` implementation contract address with the current contract code. #### Step 2: Schedule the upgrade diff --git a/contracts/script/deploy/SuccinctFeeVault.s.sol b/contracts/script/deploy/SuccinctFeeVault.s.sol index 82596a7d8..01643839b 100644 --- a/contracts/script/deploy/SuccinctFeeVault.s.sol +++ b/contracts/script/deploy/SuccinctFeeVault.s.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.16; import "forge-std/console.sol"; import {BaseScript} from "../misc/Base.s.sol"; import {SuccinctFeeVault} from "../../src/payments/SuccinctFeeVault.sol"; -import {Proxy} from "../../src/upgrades/Proxy.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; contract DeploySuccinctFeeVault is BaseScript { @@ -14,24 +13,14 @@ contract DeploySuccinctFeeVault is BaseScript { ); // Check inputs - address TIMELOCK = envAddress("TIMELOCK", block.chainid); - address GUARDIAN = envAddress("GUARDIAN", block.chainid); bytes32 CREATE2_SALT = envBytes32("CREATE2_SALT"); - bool UPGRADE = envBool("UPGRADE_VIA_EOA", false); + address GUARDIAN = envAddress("GUARDIAN", block.chainid); // Deploy contract - SuccinctFeeVault vaultImpl = new SuccinctFeeVault{salt: CREATE2_SALT}(); - SuccinctFeeVault vault; - if (!UPGRADE) { - vault = SuccinctFeeVault(address(new Proxy{salt: CREATE2_SALT}(address(vaultImpl), ""))); - vault.initialize(TIMELOCK, GUARDIAN); - } else { - vault = SuccinctFeeVault(envAddress("SUCCINCT_FEE_VAULT", block.chainid)); - vault.upgradeTo(address(vaultImpl)); - } + SuccinctFeeVault vault = new SuccinctFeeVault{salt: CREATE2_SALT}(); + vault.initialize(GUARDIAN); // Write address writeEnvAddress(DEPLOYMENT_FILE, "SUCCINCT_FEE_VAULT", address(vault)); - writeEnvAddress(DEPLOYMENT_FILE, "SUCCINCT_FEE_VAULT_IMPL", address(vaultImpl)); } } diff --git a/contracts/script/deploy/SuccinctGateway.s.sol b/contracts/script/deploy/SuccinctGateway.s.sol index 0a16a4a61..9282e39ac 100644 --- a/contracts/script/deploy/SuccinctGateway.s.sol +++ b/contracts/script/deploy/SuccinctGateway.s.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.16; import "forge-std/console.sol"; import {BaseScript} from "../misc/Base.s.sol"; import {SuccinctGateway} from "../../src/SuccinctGateway.sol"; -import {Proxy} from "../../src/upgrades/Proxy.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; contract DeploySuccinctGateway is BaseScript { @@ -13,26 +12,16 @@ contract DeploySuccinctGateway is BaseScript { "Deploying SuccinctGateway contract on chain %s", Strings.toString(block.chainid) ); - address SUCCINCT_FEE_VAULT = envAddress("SUCCINCT_FEE_VAULT", block.chainid); - address TIMELOCK = envAddress("TIMELOCK", block.chainid); - address GUARDIAN = envAddress("GUARDIAN", block.chainid); bytes32 CREATE2_SALT = envBytes32("CREATE2_SALT"); - bool UPGRADE = envBool("UPGRADE_VIA_EOA", false); + address GUARDIAN = envAddress("GUARDIAN", block.chainid); + address SUCCINCT_FEE_VAULT = envAddress("SUCCINCT_FEE_VAULT", block.chainid); + address PROVER = envAddress("PROVER", block.chainid); // Deploy contract - SuccinctGateway gatewayImpl = new SuccinctGateway{salt: CREATE2_SALT}(); - SuccinctGateway gateway; - if (!UPGRADE) { - gateway = - SuccinctGateway(address(new Proxy{salt: CREATE2_SALT}(address(gatewayImpl), ""))); - gateway.initialize(SUCCINCT_FEE_VAULT, TIMELOCK, GUARDIAN); - } else { - gateway = SuccinctGateway(envAddress("SUCCINCT_GATEWAY", block.chainid)); - gateway.upgradeTo(address(gatewayImpl)); - } + SuccinctGateway gateway = new SuccinctGateway{salt: CREATE2_SALT}(); + gateway.initialize(GUARDIAN, SUCCINCT_FEE_VAULT, PROVER); // Write address writeEnvAddress(DEPLOYMENT_FILE, "SUCCINCT_GATEWAY", address(gateway)); - writeEnvAddress(DEPLOYMENT_FILE, "SUCCINCT_GATEWAY_IMPL", address(gatewayImpl)); } } diff --git a/contracts/src/SuccinctGateway.sol b/contracts/src/SuccinctGateway.sol index 54ca44958..79f916835 100644 --- a/contracts/src/SuccinctGateway.sol +++ b/contracts/src/SuccinctGateway.sol @@ -4,10 +4,16 @@ pragma solidity ^0.8.16; import {ISuccinctGateway, WhitelistStatus} from "./interfaces/ISuccinctGateway.sol"; import {IFunctionVerifier} from "./interfaces/IFunctionVerifier.sol"; import {FunctionRegistry} from "./FunctionRegistry.sol"; -import {TimelockedUpgradeable} from "./upgrades/TimelockedUpgradeable.sol"; import {IFeeVault} from "./payments/interfaces/IFeeVault.sol"; - -contract SuccinctGateway is ISuccinctGateway, FunctionRegistry, TimelockedUpgradeable { +import {Initializable} from "@openzeppelin-upgradeable/contracts/proxy/utils/Initializable.sol"; +import {OwnableUpgradeable} from "@openzeppelin-upgradeable/contracts/access/OwnableUpgradeable.sol"; + +contract SuccinctGateway is + ISuccinctGateway, + FunctionRegistry, + Initializable, + OwnableUpgradeable +{ /// @notice The address of the fee vault. address public feeVault; @@ -61,22 +67,17 @@ contract SuccinctGateway is ISuccinctGateway, FunctionRegistry, TimelockedUpgrad _; } - /// @dev Version of the contract, used for tracking upgrades. - function VERSION() external pure override returns (string memory) { - return "1.0.1"; - } - - /// @notice Initializes the contract. + /// @notice Initializes the contract. Only callable once, and only callable by deployer. + /// @param _owner The address of the owner of the contract. /// @param _feeVault The address of the fee vault. - /// @param _timelock The address of the timelock contract. - /// @param _guardian The address of the guardian. - function initialize(address _feeVault, address _timelock, address _guardian) + /// @param _defaultProver The address of the default prover. + function initialize(address _owner, address _feeVault, address _defaultProver) external initializer { + _transferOwnership(_owner); feeVault = _feeVault; - isCallback = false; - __TimelockedUpgradeable_init(_timelock, _guardian); + allowedProvers[bytes32(0)][_defaultProver] = true; } /// @notice Creates a onchain request for a proof. The output and proof is fulfilled asynchronously @@ -320,21 +321,21 @@ contract SuccinctGateway is ISuccinctGateway, FunctionRegistry, TimelockedUpgrad /// @notice Add a default prover. /// @param _prover The address of the prover to add. - function addDefaultProver(address _prover) external onlyGuardian { + function addDefaultProver(address _prover) external onlyOwner { allowedProvers[bytes32(0)][_prover] = true; emit ProverUpdated(bytes32(0), _prover, true); } /// @notice Remove a default prover. /// @param _prover The address of the prover to remove. - function removeDefaultProver(address _prover) external onlyGuardian { + function removeDefaultProver(address _prover) external onlyOwner { delete allowedProvers[bytes32(0)][_prover]; emit ProverUpdated(bytes32(0), _prover, false); } /// @notice Sets the fee vault to a new address. Can be set to address(0) to disable fees. /// @param _feeVault The address of the fee vault. - function setFeeVault(address _feeVault) external onlyGuardian { + function setFeeVault(address _feeVault) external onlyOwner { emit SetFeeVault(feeVault, _feeVault); feeVault = _feeVault; } @@ -342,7 +343,7 @@ contract SuccinctGateway is ISuccinctGateway, FunctionRegistry, TimelockedUpgrad /// @notice Recovers stuck ETH from the contract. /// @param _to The address to send the ETH to. /// @param _amount The wei amount of ETH to send. - function recover(address _to, uint256 _amount) external onlyGuardian { + function recover(address _to, uint256 _amount) external onlyOwner { (bool success,) = _to.call{value: _amount}(""); if (!success) { revert RecoverFailed(); @@ -394,8 +395,4 @@ contract SuccinctGateway is ISuccinctGateway, FunctionRegistry, TimelockedUpgrad revert InvalidProof(address(verifier), _inputHash, _outputHash, _proof); } } - - /// @dev This empty reserved space to add new variables without shifting down storage. - /// See: https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - uint256[49] private __gap; } diff --git a/contracts/src/payments/SuccinctFeeVault.sol b/contracts/src/payments/SuccinctFeeVault.sol index 2169da447..2aa7aa31e 100644 --- a/contracts/src/payments/SuccinctFeeVault.sol +++ b/contracts/src/payments/SuccinctFeeVault.sol @@ -2,7 +2,8 @@ pragma solidity ^0.8.16; import {IFeeVault} from "./interfaces/IFeeVault.sol"; -import {TimelockedUpgradeable} from "../upgrades/TimelockedUpgradeable.sol"; +import {Initializable} from "@openzeppelin-upgradeable/contracts/proxy/utils/Initializable.sol"; +import {OwnableUpgradeable} from "@openzeppelin-upgradeable/contracts/access/OwnableUpgradeable.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -18,7 +19,7 @@ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol /// Any overspent fees will be used for future requests, so it may be more suitable to /// make a bulk deposit. /// @dev Address(0) is used to represent native currency in places where token address is specified. -contract SuccinctFeeVault is IFeeVault, TimelockedUpgradeable { +contract SuccinctFeeVault is IFeeVault, Initializable, OwnableUpgradeable { using SafeERC20 for IERC20; /// @notice Tracks the amount of active balance that an account has for Succinct services. @@ -35,27 +36,21 @@ contract SuccinctFeeVault is IFeeVault, TimelockedUpgradeable { _; } - /// @dev Version of the contract, used for tracking upgrades. - function VERSION() external pure override returns (string memory) { - return "1.0.1"; - } - - /// @dev Initializes the contract. - /// @param _timelock The address of the timelock contract. - /// @param _guardian The address of the guardian. - function initialize(address _timelock, address _guardian) external initializer { - __TimelockedUpgradeable_init(_timelock, _guardian); + /// @notice Initializes the contract. + /// @param _owner The address of the owner of the contract. + function initialize(address _owner) external initializer { + _transferOwnership(_owner); } /// @notice Add the specified deductor. /// @param _deductor The address of the deductor to add. - function addDeductor(address _deductor) external onlyGuardian { + function addDeductor(address _deductor) external onlyOwner { allowedDeductors[_deductor] = true; } /// @notice Remove the specified deductor. /// @param _deductor The address of the deductor to remove. - function removeDeductor(address _deductor) external onlyGuardian { + function removeDeductor(address _deductor) external onlyOwner { allowedDeductors[_deductor] = false; } @@ -136,7 +131,7 @@ contract SuccinctFeeVault is IFeeVault, TimelockedUpgradeable { /// @notice Collect the specified amount of native currency. /// @param _to The address to send the collected native currency to. /// @param _amount The amount of native currency to collect. - function collectNative(address _to, uint256 _amount) external onlyGuardian { + function collectNative(address _to, uint256 _amount) external onlyOwner { if (address(this).balance < _amount) { revert InsufficientBalance(address(0), _amount); } @@ -153,7 +148,7 @@ contract SuccinctFeeVault is IFeeVault, TimelockedUpgradeable { /// @param _to The address to send the collected tokens to. /// @param _token The address of the token to collect. /// @param _amount The amount of the token to collect. - function collect(address _to, address _token, uint256 _amount) external onlyGuardian { + function collect(address _to, address _token, uint256 _amount) external onlyOwner { if (_token == address(0)) { revert InvalidToken(_token); } @@ -165,8 +160,4 @@ contract SuccinctFeeVault is IFeeVault, TimelockedUpgradeable { emit Collected(_to, _token, _amount); } - - /// @dev This empty reserved space to add new variables without shifting down storage. - /// See: https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - uint256[50] private __gap; } diff --git a/contracts/test/SuccinctGateway.t.sol b/contracts/test/SuccinctGateway.t.sol index 9fa1e2cea..c5d05eacc 100644 --- a/contracts/test/SuccinctGateway.t.sol +++ b/contracts/test/SuccinctGateway.t.sol @@ -24,13 +24,11 @@ import { IFunctionRegistryErrors } from "src/interfaces/IFunctionRegistry.sol"; import {TestConsumer, TestFunctionVerifier1} from "test/TestUtils.sol"; -import {Proxy} from "src/upgrades/Proxy.sol"; import {SuccinctFeeVault} from "src/payments/SuccinctFeeVault.sol"; -import {AccessControlUpgradeable} from - "@openzeppelin-upgradeable/contracts/access/AccessControlUpgradeable.sol"; contract SuccinctGatewayTest is Test, ISuccinctGatewayEvents, ISuccinctGatewayErrors { // Example Function Request and expected values. + bytes32 internal constant VERIFIER_SALT = bytes32(uint256(1)); bytes internal constant INPUT = bytes("function-input"); bytes32 internal constant INPUT_HASH = sha256(INPUT); bytes internal constant OUTPUT = abi.encode(true); @@ -41,42 +39,35 @@ contract SuccinctGatewayTest is Test, ISuccinctGatewayEvents, ISuccinctGatewayEr uint32 internal constant DEFAULT_GAS_LIMIT = 1_000_000; address internal timelock; - address internal guardian; + address internal owner; address internal feeVault; address internal gateway; address internal verifier; address payable internal consumer; address payable internal sender; - address internal owner; - address internal prover; + address internal functionOwner; + address internal defaultProver; function setUp() public virtual { // Init variables - timelock = makeAddr("timelock"); - guardian = makeAddr("guardian"); - sender = payable(makeAddr("sender")); owner = makeAddr("owner"); - prover = makeAddr("prover"); + sender = payable(makeAddr("sender")); + functionOwner = makeAddr("function-owner"); + defaultProver = makeAddr("default-prover"); // Deploy FeeVault - address feeVaultImpl = address(new SuccinctFeeVault()); - feeVault = address(new Proxy(feeVaultImpl, "")); - SuccinctFeeVault(feeVault).initialize(timelock, guardian); + feeVault = address(new SuccinctFeeVault()); + SuccinctFeeVault(feeVault).initialize(owner); // Deploy SuccinctGateway - address gatewayImpl = address(new SuccinctGateway()); - gateway = address(new Proxy(gatewayImpl, "")); - SuccinctGateway(gateway).initialize(feeVault, timelock, guardian); - - // Add prover - vm.prank(guardian); - SuccinctGateway(gateway).addDefaultProver(prover); + gateway = address(new SuccinctGateway()); + SuccinctGateway(gateway).initialize(owner, feeVault, defaultProver); // Deploy Verifier bytes32 functionId; vm.prank(sender); (functionId, verifier) = IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier" + functionOwner, type(TestFunctionVerifier1).creationCode, VERIFIER_SALT ); // Deploy TestConsumer @@ -89,12 +80,20 @@ contract SuccinctGatewayTest is Test, ISuccinctGatewayEvents, ISuccinctGatewayEr contract SetupTest is SuccinctGatewayTest { function test_SetUp() public { + assertEq(SuccinctGateway(gateway).owner(), owner); + assertEq(SuccinctGateway(gateway).feeVault(), feeVault); + assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), defaultProver), true); + bytes32 functionId = TestConsumer(consumer).FUNCTION_ID(); + assertTrue(SuccinctGateway(gateway).whitelistStatus(functionId) == WhitelistStatus.Default); assertEq(IFunctionRegistry(gateway).verifiers(functionId), verifier); - assertEq(IFunctionRegistry(gateway).verifierOwners(functionId), owner); - assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), prover), true); - assertTrue(AccessControlUpgradeable(gateway).hasRole(keccak256("TIMELOCK_ROLE"), timelock)); - assertTrue(AccessControlUpgradeable(gateway).hasRole(keccak256("GUARDIAN_ROLE"), guardian)); + assertEq(IFunctionRegistry(gateway).verifierOwners(functionId), functionOwner); + assertEq(IFunctionRegistry(gateway).getFunctionId(functionOwner, VERIFIER_SALT), functionId); + } + + function test_RevertInitialize() public { + vm.expectRevert("Initializable: contract is already initialized"); + SuccinctGateway(gateway).initialize(owner, feeVault, defaultProver); } } @@ -135,7 +134,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectEmit(true, true, true, true, gateway); emit RequestFulfilled(nonce, functionId, inputHash, OUTPUT_HASH); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCallback( nonce, functionId, @@ -186,9 +185,9 @@ contract RequestTest is SuccinctGatewayTest { assertEq(prevNonce + 1, SuccinctGateway(gateway).nonce()); assertEq(TestConsumer(consumer).handledRequests(0), false); - vm.prank(owner); + vm.prank(functionOwner); SuccinctGateway(gateway).setWhitelistStatus(functionId, WhitelistStatus.Custom); - vm.prank(owner); + vm.prank(functionOwner); SuccinctGateway(gateway).addCustomProver(functionId, customProver); // Fulfill @@ -243,7 +242,7 @@ contract RequestTest is SuccinctGatewayTest { assertEq(prevNonce + 1, SuccinctGateway(gateway).nonce()); assertEq(TestConsumer(consumer).handledRequests(0), false); - vm.prank(owner); + vm.prank(functionOwner); SuccinctGateway(gateway).setWhitelistStatus(functionId, WhitelistStatus.Disabled); // Fulfill @@ -297,7 +296,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectEmit(true, true, true, true, gateway); emit RequestFulfilled(nonce, functionId, inputHash, OUTPUT_HASH); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCallback( nonce, functionId, @@ -314,8 +313,8 @@ contract RequestTest is SuccinctGatewayTest { } function test_Callback_WhenNoFeeVault() public { - // Set feeVault (first 20 bytes of slot 253) to 0x0 - vm.store(gateway, bytes32(uint256(253)), bytes20(address(0))); + // Set feeVault (first 20 bytes of slot 103) to 0x0 + vm.store(gateway, bytes32(uint256(103)), bytes20(address(0))); uint32 prevNonce = SuccinctGateway(gateway).nonce(); assertEq(prevNonce, 0); @@ -352,7 +351,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectEmit(true, true, true, true, gateway); emit RequestFulfilled(nonce, functionId, inputHash, OUTPUT_HASH); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCallback( nonce, functionId, @@ -368,10 +367,10 @@ contract RequestTest is SuccinctGatewayTest { assertEq(TestConsumer(consumer).handledRequests(0), true); // Recover ETH - vm.prank(guardian); - SuccinctGateway(gateway).recover(guardian, fee); + vm.prank(owner); + SuccinctGateway(gateway).recover(owner, fee); - assertEq(guardian.balance, fee); + assertEq(owner.balance, fee); } function test_Callback_WhenCallbackGasLimitTooLow() public { @@ -409,7 +408,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectRevert(); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCallback( nonce, functionId, @@ -436,7 +435,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectRevert(); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCallback( nonce, functionId, @@ -501,7 +500,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectEmit(true, true, true, true, gateway); emit Call(functionId, INPUT_HASH, OUTPUT_HASH); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCall( functionId, input, output, proof, callAddress, callData ); @@ -518,7 +517,7 @@ contract RequestTest is SuccinctGatewayTest { bytes memory callData = abi.encodeWithSelector(TestConsumer.handleCall.selector); // Fulfill - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCall( functionId, input, output, proof, callAddress, callData ); @@ -544,7 +543,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectEmit(true, true, true, true, gateway); emit Call(functionId, INPUT_HASH, OUTPUT_HASH); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCall( functionId, input, output, proof, callAddress, callData ); @@ -575,7 +574,7 @@ contract RequestTest is SuccinctGatewayTest { // Fulfill vm.expectEmit(true, true, true, true, gateway); emit Call(functionId, INPUT_HASH, OUTPUT_HASH); - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCall( functionId, input, output, proof, callAddress, callData ); @@ -609,11 +608,11 @@ contract RequestTest is SuccinctGatewayTest { bytes32 inputHash = INPUT_HASH; // Set the SuccinctGateway's storage slots to avoid revert: - // | verifiedFunctionId | bytes32 | 255 - // | verifiedInputHash | bytes32 | 256 - // | verifiedOutput | bytes | 257 - vm.store(gateway, bytes32(uint256(255)), functionId); - vm.store(gateway, bytes32(uint256(256)), inputHash); + // verifiedFunctionId | bytes32 | 105 + // verifiedInputHash | bytes32 | 106 + // verifiedOutput | bytes | 107 + vm.store(gateway, bytes32(uint256(105)), functionId); + vm.store(gateway, bytes32(uint256(106)), inputHash); // Verifiy call TestConsumer(consumer).verifiedCall(); @@ -639,7 +638,7 @@ contract AttackSuccinctGatewayTest is SuccinctGatewayTest { bytes32 functionId; vm.prank(sender); (functionId, verifier) = IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "attack-verifier" + functionOwner, type(TestFunctionVerifier1).creationCode, "attack-verifier" ); // Deploy AttackConsumer @@ -663,7 +662,7 @@ contract AttackSuccinctGatewayTest is SuccinctGatewayTest { AttackConsumer(attackConsumer).requestCallbackReenterCallback{value: fee}(); // Fulfill (test fails this doesn't revert with ReentrantFulfill() error) - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCallback( 0, functionId, @@ -692,7 +691,7 @@ contract AttackSuccinctGatewayTest is SuccinctGatewayTest { AttackConsumer(attackConsumer).requestCallbackReenterCall{value: fee}(); // Fulfill (test fails this doesn't revert with ReentrantFulfill() error) - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCallback( 0, functionId, @@ -721,7 +720,7 @@ contract AttackSuccinctGatewayTest is SuccinctGatewayTest { AttackConsumer(attackConsumer).requestCallReenterCallback{value: fee}(); // Fulfill (test fails this doesn't revert with ReentrantFulfill() error) - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCall( functionId, input, output, proof, callAddress, callData ); @@ -742,7 +741,7 @@ contract AttackSuccinctGatewayTest is SuccinctGatewayTest { AttackConsumer(attackConsumer).requestCallReenterCall{value: fee}(); // Fulfill (test fails this doesn't revert with ReentrantFulfill() error) - vm.prank(prover); + vm.prank(defaultProver); SuccinctGateway(gateway).fulfillCall( functionId, input, output, proof, callAddress, callData ); @@ -756,7 +755,7 @@ contract FunctionRegistryTest is { function test_RegisterFunction() public { bytes32 expectedFunctionId1 = - IFunctionRegistry(gateway).getFunctionId(owner, "test-verifier1"); + IFunctionRegistry(gateway).getFunctionId(functionOwner, "test-verifier1"); // Deploy verifier address verifier1; @@ -768,18 +767,18 @@ contract FunctionRegistryTest is // Register function vm.expectEmit(true, true, true, true, gateway); - emit FunctionRegistered(expectedFunctionId1, verifier1, "test-verifier1", owner); + emit FunctionRegistered(expectedFunctionId1, verifier1, "test-verifier1", functionOwner); bytes32 functionId1 = - IFunctionRegistry(gateway).registerFunction(owner, verifier1, "test-verifier1"); + IFunctionRegistry(gateway).registerFunction(functionOwner, verifier1, "test-verifier1"); assertEq(functionId1, expectedFunctionId1); assertEq(IFunctionRegistry(gateway).verifiers(expectedFunctionId1), verifier1); - assertEq(IFunctionRegistry(gateway).verifierOwners(expectedFunctionId1), owner); + assertEq(IFunctionRegistry(gateway).verifierOwners(expectedFunctionId1), functionOwner); } function test_RegisterFunction_WhenOwnerIsSender() public { bytes32 expectedFunctionId1 = - IFunctionRegistry(gateway).getFunctionId(owner, "test-verifier1"); + IFunctionRegistry(gateway).getFunctionId(functionOwner, "test-verifier1"); // Deploy verifier address verifier1; @@ -791,38 +790,38 @@ contract FunctionRegistryTest is // Register function vm.expectEmit(true, true, true, true, gateway); - emit FunctionRegistered(expectedFunctionId1, verifier1, "test-verifier1", owner); - vm.prank(owner); + emit FunctionRegistered(expectedFunctionId1, verifier1, "test-verifier1", functionOwner); + vm.prank(functionOwner); bytes32 functionId1 = - IFunctionRegistry(gateway).registerFunction(owner, verifier1, "test-verifier1"); + IFunctionRegistry(gateway).registerFunction(functionOwner, verifier1, "test-verifier1"); assertEq(functionId1, expectedFunctionId1); assertEq(IFunctionRegistry(gateway).verifiers(expectedFunctionId1), verifier1); - assertEq(IFunctionRegistry(gateway).verifierOwners(expectedFunctionId1), owner); + assertEq(IFunctionRegistry(gateway).verifierOwners(expectedFunctionId1), functionOwner); } function test_RevertRegisterFunction_WhenAlreadyRegistered() public { // Deploy verifier address verifier1; bytes memory bytecode = type(TestFunctionVerifier1).creationCode; - bytes32 salt = IFunctionRegistry(gateway).getFunctionId(owner, "test-verifier1"); + bytes32 salt = IFunctionRegistry(gateway).getFunctionId(functionOwner, "test-verifier1"); assembly { verifier1 := create2(0, add(bytecode, 32), mload(bytecode), salt) } // Register function vm.expectEmit(true, true, true, true, gateway); - emit FunctionRegistered(salt, verifier1, "test-verifier1", owner); - IFunctionRegistry(gateway).registerFunction(owner, verifier1, "test-verifier1"); + emit FunctionRegistered(salt, verifier1, "test-verifier1", functionOwner); + IFunctionRegistry(gateway).registerFunction(functionOwner, verifier1, "test-verifier1"); // Register function again vm.expectRevert(abi.encodeWithSelector(FunctionAlreadyRegistered.selector, salt)); - IFunctionRegistry(gateway).registerFunction(owner, verifier1, "test-verifier1"); + IFunctionRegistry(gateway).registerFunction(functionOwner, verifier1, "test-verifier1"); } function test_DeployAndRegisterFunction() public { bytes32 expectedFunctionId1 = - IFunctionRegistry(gateway).getFunctionId(owner, "test-verifier1"); + IFunctionRegistry(gateway).getFunctionId(functionOwner, "test-verifier1"); // Deploy verifier and register function vm.expectEmit(true, false, false, true, gateway); @@ -830,20 +829,20 @@ contract FunctionRegistryTest is keccak256(type(TestFunctionVerifier1).creationCode), expectedFunctionId1, address(0) ); vm.expectEmit(true, true, true, false, gateway); - emit FunctionRegistered(expectedFunctionId1, address(0), "test-verifier1", owner); + emit FunctionRegistered(expectedFunctionId1, address(0), "test-verifier1", functionOwner); (bytes32 functionId1, address verifier1) = IFunctionRegistry(gateway) .deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); assertEq(functionId1, expectedFunctionId1); assertEq(IFunctionRegistry(gateway).verifiers(functionId1), verifier1); - assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), owner); + assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), functionOwner); } function test_DeployAndRegisterFunction_WhenOwnerIsSender() public { bytes32 expectedFunctionId1 = - IFunctionRegistry(gateway).getFunctionId(owner, "test-verifier1"); + IFunctionRegistry(gateway).getFunctionId(functionOwner, "test-verifier1"); // Deploy verifier and register function vm.expectEmit(true, false, false, true, gateway); @@ -851,22 +850,22 @@ contract FunctionRegistryTest is keccak256(type(TestFunctionVerifier1).creationCode), expectedFunctionId1, address(0) ); vm.expectEmit(true, true, true, false, gateway); - emit FunctionRegistered(expectedFunctionId1, address(0), "test-verifier1", owner); - vm.prank(owner); + emit FunctionRegistered(expectedFunctionId1, address(0), "test-verifier1", functionOwner); + vm.prank(functionOwner); (bytes32 functionId1, address verifier1) = IFunctionRegistry(gateway) .deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); assertEq(functionId1, expectedFunctionId1); assertEq(IFunctionRegistry(gateway).verifiers(functionId1), verifier1); - assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), owner); + assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), functionOwner); } function test_RevertDeployAndRegisterFunction_WhenAlreadyRegistered() public { // Deploy verifier and register function IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); // Deploy verifier and register function again @@ -874,17 +873,17 @@ contract FunctionRegistryTest is // a contract is already deployed to that address. vm.expectRevert(FailedDeploy.selector); IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); } function test_UpdateFunction() public { bytes32 expectedFunctionId1 = - IFunctionRegistry(gateway).getFunctionId(owner, "test-verifier1"); + IFunctionRegistry(gateway).getFunctionId(functionOwner, "test-verifier1"); // Deploy verifier and register function IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); // Deploy verifier @@ -898,18 +897,18 @@ contract FunctionRegistryTest is // Update function vm.expectEmit(true, true, true, true, gateway); emit FunctionVerifierUpdated(expectedFunctionId1, verifier2); - vm.prank(owner); + vm.prank(functionOwner); bytes32 functionId1 = IFunctionRegistry(gateway).updateFunction(verifier2, "test-verifier1"); assertEq(functionId1, expectedFunctionId1); assertEq(IFunctionRegistry(gateway).verifiers(functionId1), verifier2); - assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), owner); + assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), functionOwner); } function test_RevertUpdateFunction_WhenNotOwner() public { // Deploy verifier and register function (bytes32 functionId,) = IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); // Deploy verifier @@ -936,8 +935,10 @@ contract FunctionRegistryTest is } // Update function - vm.expectRevert(abi.encodeWithSelector(NotFunctionOwner.selector, owner, address(0))); - vm.prank(owner); + vm.expectRevert( + abi.encodeWithSelector(NotFunctionOwner.selector, functionOwner, address(0)) + ); + vm.prank(functionOwner); IFunctionRegistry(gateway).updateFunction(verifier2, "test-verifier1"); } @@ -945,22 +946,22 @@ contract FunctionRegistryTest is // Deploy verifier and register function (bytes32 functionId1, address verifier1) = IFunctionRegistry(gateway) .deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); // Update function vm.expectRevert(abi.encodeWithSelector(VerifierAlreadyUpdated.selector, functionId1)); - vm.prank(owner); + vm.prank(functionOwner); IFunctionRegistry(gateway).updateFunction(verifier1, "test-verifier1"); } function test_deployAndUpdateFunction() public { bytes32 expectedFunctionId1 = - IFunctionRegistry(gateway).getFunctionId(owner, "test-verifier1"); + IFunctionRegistry(gateway).getFunctionId(functionOwner, "test-verifier1"); // Deploy verifier and register function IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); // Deploy verifier and update function @@ -970,19 +971,19 @@ contract FunctionRegistryTest is ); vm.expectEmit(true, true, true, false, gateway); emit FunctionVerifierUpdated(expectedFunctionId1, address(0)); - vm.prank(owner); + vm.prank(functionOwner); (bytes32 functionId1, address verifier2) = IFunctionRegistry(gateway) .deployAndUpdateFunction(type(TestFunctionVerifier2).creationCode, "test-verifier1"); assertEq(functionId1, expectedFunctionId1); assertEq(IFunctionRegistry(gateway).verifiers(functionId1), verifier2); - assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), owner); + assertEq(IFunctionRegistry(gateway).verifierOwners(functionId1), functionOwner); } function test_RevertDeployAndUpdateFunction_WhenNotOwner() public { // Deploy verifier and register function IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); // Deploy verifier and update function @@ -995,8 +996,10 @@ contract FunctionRegistryTest is function test_RevertDeployAndUpdateFunction_WhenNeverRegistered() public { // Deploy verifier and update function - vm.expectRevert(abi.encodeWithSelector(NotFunctionOwner.selector, owner, address(0))); - vm.prank(owner); + vm.expectRevert( + abi.encodeWithSelector(NotFunctionOwner.selector, functionOwner, address(0)) + ); + vm.prank(functionOwner); IFunctionRegistry(gateway).deployAndUpdateFunction( type(TestFunctionVerifier1).creationCode, "test-verifier1" ); @@ -1005,12 +1008,12 @@ contract FunctionRegistryTest is function test_RevertDeployAndUpdateFunction_WhenBytecodeSame() public { // Deploy verifier and register function IFunctionRegistry(gateway).deployAndRegisterFunction( - owner, type(TestFunctionVerifier1).creationCode, "test-verifier1" + functionOwner, type(TestFunctionVerifier1).creationCode, "test-verifier1" ); // Deploy verifier and update function vm.expectRevert(abi.encodeWithSelector(FailedDeploy.selector)); - vm.prank(owner); + vm.prank(functionOwner); IFunctionRegistry(gateway).deployAndUpdateFunction( type(TestFunctionVerifier1).creationCode, "test-verifier1" ); @@ -1019,36 +1022,38 @@ contract FunctionRegistryTest is contract UpdateProverTest is SuccinctGatewayTest { function test_AddDefaultProver() public { - address defaultProver = makeAddr("default-prover"); + address newDefaultProver = makeAddr("default-prover"); vm.expectEmit(true, true, true, true, gateway); - emit ProverUpdated(bytes32(0), defaultProver, true); - vm.prank(guardian); - SuccinctGateway(gateway).addDefaultProver(defaultProver); + emit ProverUpdated(bytes32(0), newDefaultProver, true); + vm.prank(owner); + SuccinctGateway(gateway).addDefaultProver(newDefaultProver); assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), defaultProver), true); + assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), newDefaultProver), true); } - function test_RevertAddDefaultProver_WhenNotGuardian() public { - address defaultProver = makeAddr("default-prover"); + function test_RevertAddDefaultProver_WhenNotOwner() public { + address newDefaultProver = makeAddr("new-default-prover"); - vm.expectRevert(abi.encodeWithSignature("OnlyGuardian(address)", sender)); + vm.expectRevert("Ownable: caller is not the owner"); vm.prank(sender); - SuccinctGateway(gateway).addDefaultProver(defaultProver); - assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), defaultProver), false); + SuccinctGateway(gateway).addDefaultProver(newDefaultProver); + assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), defaultProver), true); + assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), newDefaultProver), false); } function test_RemoveDefaultProver() public { - emit ProverUpdated(bytes32(0), prover, true); - vm.prank(guardian); - SuccinctGateway(gateway).removeDefaultProver(prover); - assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), prover), false); + emit ProverUpdated(bytes32(0), defaultProver, true); + vm.prank(owner); + SuccinctGateway(gateway).removeDefaultProver(defaultProver); + assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), defaultProver), false); } - function test_RevertRemoveDefaultProver_WhenNotGuardian() public { - vm.expectRevert(abi.encodeWithSignature("OnlyGuardian(address)", sender)); + function test_RevertRemoveDefaultProver_WhenNotOwner() public { + vm.expectRevert("Ownable: caller is not the owner"); vm.prank(sender); - SuccinctGateway(gateway).removeDefaultProver(prover); - assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), prover), true); + SuccinctGateway(gateway).removeDefaultProver(defaultProver); + assertEq(SuccinctGateway(gateway).allowedProvers(bytes32(0), defaultProver), true); } function test_AddCustomProver() public { @@ -1057,7 +1062,7 @@ contract UpdateProverTest is SuccinctGatewayTest { vm.expectEmit(true, true, true, true, gateway); emit ProverUpdated(functionId, customProver, true); - vm.prank(owner); + vm.prank(functionOwner); SuccinctGateway(gateway).addCustomProver(functionId, customProver); assertEq(SuccinctGateway(gateway).allowedProvers(functionId, customProver), true); } @@ -1066,7 +1071,9 @@ contract UpdateProverTest is SuccinctGatewayTest { bytes32 functionId = TestConsumer(consumer).FUNCTION_ID(); address customProver = makeAddr("custom-prover"); - vm.expectRevert(abi.encodeWithSignature("NotFunctionOwner(address,address)", sender, owner)); + vm.expectRevert( + abi.encodeWithSignature("NotFunctionOwner(address,address)", sender, functionOwner) + ); vm.prank(sender); SuccinctGateway(gateway).addCustomProver(functionId, customProver); assertEq(SuccinctGateway(gateway).allowedProvers(functionId, customProver), false); @@ -1075,18 +1082,20 @@ contract UpdateProverTest is SuccinctGatewayTest { function test_RemoveCustomProver() public { bytes32 functionId = TestConsumer(consumer).FUNCTION_ID(); - emit ProverUpdated(functionId, prover, true); - vm.prank(owner); - SuccinctGateway(gateway).removeCustomProver(functionId, prover); - assertEq(SuccinctGateway(gateway).allowedProvers(functionId, prover), false); + emit ProverUpdated(functionId, defaultProver, true); + vm.prank(functionOwner); + SuccinctGateway(gateway).removeCustomProver(functionId, defaultProver); + assertEq(SuccinctGateway(gateway).allowedProvers(functionId, defaultProver), false); } function test_RevertRemoveCustomProver_WhenNotOwner() public { bytes32 functionId = TestConsumer(consumer).FUNCTION_ID(); - vm.expectRevert(abi.encodeWithSignature("NotFunctionOwner(address,address)", sender, owner)); + vm.expectRevert( + abi.encodeWithSignature("NotFunctionOwner(address,address)", sender, functionOwner) + ); vm.prank(sender); - SuccinctGateway(gateway).removeCustomProver(functionId, prover); + SuccinctGateway(gateway).removeCustomProver(functionId, defaultProver); } } @@ -1097,7 +1106,7 @@ contract SetWhitelistStatusTest is SuccinctGatewayTest { vm.expectEmit(true, true, true, true, gateway); emit WhitelistStatusUpdated(functionId, status); - vm.prank(owner); + vm.prank(functionOwner); SuccinctGateway(gateway).setWhitelistStatus(functionId, status); assertTrue(SuccinctGateway(gateway).whitelistStatus(functionId) == status); } @@ -1106,7 +1115,9 @@ contract SetWhitelistStatusTest is SuccinctGatewayTest { bytes32 functionId = TestConsumer(consumer).FUNCTION_ID(); WhitelistStatus status = WhitelistStatus.Custom; - vm.expectRevert(abi.encodeWithSignature("NotFunctionOwner(address,address)", sender, owner)); + vm.expectRevert( + abi.encodeWithSignature("NotFunctionOwner(address,address)", sender, functionOwner) + ); vm.prank(sender); SuccinctGateway(gateway).setWhitelistStatus(functionId, status); assertTrue(SuccinctGateway(gateway).whitelistStatus(functionId) == WhitelistStatus.Default); @@ -1122,11 +1133,12 @@ contract SetFeeVaultTest is SuccinctGatewayTest { uint32 callGasLimit = DEFAULT_GAS_LIMIT; uint256 fee = DEFAULT_FEE; address newFeeVault = address(new SuccinctFeeVault()); + SuccinctFeeVault(newFeeVault).initialize(functionOwner); // Set FeeVault vm.expectEmit(true, true, true, true, gateway); emit SetFeeVault(SuccinctGateway(gateway).feeVault(), newFeeVault); - vm.prank(guardian); + vm.prank(owner); SuccinctGateway(gateway).setFeeVault(newFeeVault); assertEq(SuccinctGateway(gateway).feeVault(), newFeeVault); @@ -1137,8 +1149,9 @@ contract SetFeeVaultTest is SuccinctGatewayTest { TestConsumer(consumer).requestCall{value: fee}(callGasLimit); } - function test_RevertSetFeeVault_WhenNotGuardian() public { + function test_RevertSetFeeVault_WhenNotOwner() public { address newFeeVault = address(new SuccinctFeeVault()); + SuccinctFeeVault(newFeeVault).initialize(functionOwner); // Set FeeVault vm.expectRevert(); @@ -1152,19 +1165,19 @@ contract RecoverTest is SuccinctGatewayTest { vm.deal(gateway, fee); // Recover ETH - vm.prank(guardian); - SuccinctGateway(gateway).recover(guardian, fee); + vm.prank(owner); + SuccinctGateway(gateway).recover(owner, fee); - assertEq(guardian.balance, fee); + assertEq(owner.balance, fee); } - function test_RevertRecover_WhenNotGuardian() public { + function test_RevertRecover_WhenNotOwner() public { uint256 fee = DEFAULT_FEE; vm.deal(gateway, fee); // Recover ETH - vm.expectRevert(abi.encodeWithSignature("OnlyGuardian(address)", sender)); + vm.expectRevert("Ownable: caller is not the owner"); vm.prank(sender); - SuccinctGateway(gateway).recover(guardian, fee); + SuccinctGateway(gateway).recover(owner, fee); } } diff --git a/contracts/test/payments/SuccinctFeeVault.t.sol b/contracts/test/payments/SuccinctFeeVault.t.sol index 68f2693aa..6866912da 100644 --- a/contracts/test/payments/SuccinctFeeVault.t.sol +++ b/contracts/test/payments/SuccinctFeeVault.t.sol @@ -5,18 +5,14 @@ import "forge-std/Vm.sol"; import "forge-std/console.sol"; import "forge-std/Test.sol"; -import {IFeeVault, IFeeVaultEvents, IFeeVaultErrors} from "src/payments/interfaces/IFeeVault.sol"; +import {IFeeVaultEvents, IFeeVaultErrors} from "src/payments/interfaces/IFeeVault.sol"; import {SuccinctFeeVault} from "src/payments/SuccinctFeeVault.sol"; -import {Proxy} from "src/upgrades/Proxy.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import {AccessControlUpgradeable} from - "@openzeppelin-upgradeable/contracts/access/AccessControlUpgradeable.sol"; contract SuccinctFeeVaultTest is Test, IFeeVaultEvents, IFeeVaultErrors { uint256 constant FEE = 1 ether; - address internal timelock; - address internal guardian; + address internal owner; address internal feeVault; address internal token1; address internal token2; @@ -29,8 +25,7 @@ contract SuccinctFeeVaultTest is Test, IFeeVaultEvents, IFeeVaultErrors { function setUp() public { // Init variables - timelock = makeAddr("timelock"); - guardian = makeAddr("guardian"); + owner = makeAddr("owner"); token1 = address(new ERC20("UnicornToken", "UNI")); token2 = address(new ERC20("DragonToken", "DRG")); @@ -42,12 +37,11 @@ contract SuccinctFeeVaultTest is Test, IFeeVaultEvents, IFeeVaultErrors { account2 = makeAddr("account2"); // Deploy FeeVault - address feeVaultImpl = address(new SuccinctFeeVault()); - feeVault = address(new Proxy(feeVaultImpl, "")); - SuccinctFeeVault(feeVault).initialize(timelock, guardian); + feeVault = address(new SuccinctFeeVault()); + SuccinctFeeVault(feeVault).initialize(owner); // Add deductor - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).addDeductor(deductor); // Give spenders some native @@ -64,8 +58,7 @@ contract SuccinctFeeVaultTest is Test, IFeeVaultEvents, IFeeVaultErrors { contract SetUpTest is SuccinctFeeVaultTest { function test_SetUp() public { - assertTrue(AccessControlUpgradeable(feeVault).hasRole(keccak256("TIMELOCK_ROLE"), timelock)); - assertTrue(AccessControlUpgradeable(feeVault).hasRole(keccak256("GUARDIAN_ROLE"), guardian)); + assertEq(SuccinctFeeVault(feeVault).owner(), owner); assertEq(SuccinctFeeVault(feeVault).allowedDeductors(deductor), true); assertEq(SuccinctFeeVault(feeVault).balances(address(0), spender1), 0); assertEq(SuccinctFeeVault(feeVault).balances(address(0), spender2), 0); @@ -86,30 +79,35 @@ contract SetUpTest is SuccinctFeeVaultTest { assertEq(ERC20(token1).balanceOf(spender2), FEE); assertEq(ERC20(token2).balanceOf(spender2), FEE); } + + function test_RevertInitialize() public { + vm.expectRevert("Initializable: contract is already initialized"); + SuccinctFeeVault(feeVault).initialize(owner); + } } contract DeductorTest is SuccinctFeeVaultTest { function test_AddDeductor() public { - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).addDeductor(spender1); assertEq(SuccinctFeeVault(feeVault).allowedDeductors(spender1), true); } function test_RevertAddDeductor_WhenNotGuardian() public { - vm.expectRevert(abi.encodeWithSignature("OnlyGuardian(address)", spender1)); + vm.expectRevert("Ownable: caller is not the owner"); vm.prank(spender1); SuccinctFeeVault(feeVault).addDeductor(spender1); assertEq(SuccinctFeeVault(feeVault).allowedDeductors(spender1), false); } function test_RemoveDeductor() public { - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).removeDeductor(deductor); assertEq(SuccinctFeeVault(feeVault).allowedDeductors(deductor), false); } function test_RevertRemoveDeductor_WhenNotGuardian() public { - vm.expectRevert(abi.encodeWithSignature("OnlyGuardian(address)", spender1)); + vm.expectRevert("Ownable: caller is not the owner"); vm.prank(spender1); SuccinctFeeVault(feeVault).removeDeductor(deductor); assertEq(SuccinctFeeVault(feeVault).allowedDeductors(deductor), true); @@ -537,7 +535,7 @@ contract CollectNativeTest is SuccinctFeeVaultTest { vm.expectEmit(true, true, true, true); emit Collected(collector, address(0), FEE); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collectNative(collector, FEE); assertEq(address(feeVault).balance, 0); assertEq(collector.balance, FEE); @@ -551,7 +549,7 @@ contract CollectNativeTest is SuccinctFeeVaultTest { vm.expectEmit(true, true, true, true); emit Collected(collector, address(0), FEE / 2); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collectNative(collector, FEE / 2); assertEq(address(feeVault).balance, FEE / 2); assertEq(collector.balance, FEE / 2); @@ -565,21 +563,21 @@ contract CollectNativeTest is SuccinctFeeVaultTest { vm.expectEmit(true, true, true, true); emit Collected(collector, address(0), 0); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collectNative(collector, 0); assertEq(address(feeVault).balance, FEE); assertEq(collector.balance, 0); } function test_RevertCollectNative_WhenNotOwner() public { - vm.expectRevert(abi.encodeWithSignature("OnlyGuardian(address)", spender1)); + vm.expectRevert("Ownable: caller is not the owner"); vm.prank(spender1); SuccinctFeeVault(feeVault).collectNative(collector, FEE); } function test_RevertCollectNative_WhenNotEnoughBalance() public { vm.expectRevert(abi.encodeWithSelector(InsufficientBalance.selector, address(0), FEE)); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collectNative(collector, FEE); } } @@ -595,7 +593,7 @@ contract CollectTest is SuccinctFeeVaultTest { vm.expectEmit(true, true, true, true); emit Collected(collector, token1, FEE); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collect(collector, token1, FEE); assertEq(ERC20(token1).balanceOf(address(feeVault)), 0); assertEq(ERC20(token1).balanceOf(collector), FEE); @@ -611,7 +609,7 @@ contract CollectTest is SuccinctFeeVaultTest { vm.expectEmit(true, true, true, true); emit Collected(collector, token1, FEE / 2); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collect(collector, token1, FEE / 2); assertEq(ERC20(token1).balanceOf(address(feeVault)), FEE / 2); assertEq(ERC20(token1).balanceOf(collector), FEE / 2); @@ -627,21 +625,21 @@ contract CollectTest is SuccinctFeeVaultTest { vm.expectEmit(true, true, true, true); emit Collected(collector, token1, 0); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collect(collector, token1, 0); assertEq(ERC20(token1).balanceOf(address(feeVault)), FEE); assertEq(ERC20(token1).balanceOf(collector), 0); } function test_RevertCollect_WhenNotGuardian() public { - vm.expectRevert(abi.encodeWithSignature("OnlyGuardian(address)", spender1)); + vm.expectRevert("Ownable: caller is not the owner"); vm.prank(spender1); SuccinctFeeVault(feeVault).collect(collector, token1, FEE); } function test_RevertCollect_WhenNotEnoughBalance() public { vm.expectRevert(abi.encodeWithSelector(InsufficientBalance.selector, token1, FEE)); - vm.prank(guardian); + vm.prank(owner); SuccinctFeeVault(feeVault).collect(collector, token1, FEE); } }