From 846642a43e10585ea02c1f71a6254277f63e86a3 Mon Sep 17 00:00:00 2001 From: danilo neves cruz Date: Tue, 31 Dec 2024 11:55:06 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20contracts:=20inject=20test=20deploy?= =?UTF-8?q?ments=20through=20storage,=20simplify=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/.gas-snapshot | 38 ++++++------ contracts/script/Deploy.s.sol | 68 +++++++--------------- contracts/script/Refunder.s.sol | 19 ++---- contracts/test/ExaPlugin.t.sol | 43 +++++--------- contracts/test/Fork.t.sol | 17 +++++- contracts/test/InstallmentsPreviewer.t.sol | 9 +-- contracts/test/MockSwapper.t.sol | 10 ++-- contracts/test/Refunder.t.sol | 5 -- contracts/test/mocks/Mocks.s.sol | 11 +--- 9 files changed, 81 insertions(+), 139 deletions(-) diff --git a/contracts/.gas-snapshot b/contracts/.gas-snapshot index 825fb347..38adab61 100644 --- a/contracts/.gas-snapshot +++ b/contracts/.gas-snapshot @@ -1,33 +1,33 @@ ExaAccountFactoryTest:testFuzz_createAccount_EOAOwners(uint256,address[63]) (runs: 256, μ: 3621366, ~: 3460632) -ExaPluginTest:testFork_crossRepay_repays() (gas: 19666737) -ExaPluginTest:testFork_debitCollateral_collects() (gas: 19756315) -ExaPluginTest:testFork_swap_swaps() (gas: 16912274) +ExaPluginTest:testFork_crossRepay_repays() (gas: 19686996) +ExaPluginTest:testFork_debitCollateral_collects() (gas: 19776574) +ExaPluginTest:testFork_swap_swaps() (gas: 16929512) ExaPluginTest:test_borrowAtMaturity_reverts_withUnauthorized_whenReceiverNotCollector() (gas: 408975) ExaPluginTest:test_borrow_reverts_withUnauthorized_whenReceiverNotCollector() (gas: 408553) ExaPluginTest:test_collectCredit_collects() (gas: 921083) ExaPluginTest:test_collectCredit_collects_whenHealthFactorHigherThanMinHealthFactor() (gas: 801758) ExaPluginTest:test_collectCredit_collects_withEnoughSlippage() (gas: 800271) -ExaPluginTest:test_collectCredit_passes_whenProposalLeavesEnoughLiquidity() (gas: 1010088) +ExaPluginTest:test_collectCredit_passes_whenProposalLeavesEnoughLiquidity() (gas: 1010112) ExaPluginTest:test_collectCredit_reverts_asNotKeeper() (gas: 362757) ExaPluginTest:test_collectCredit_reverts_whenDisagreement() (gas: 556074) -ExaPluginTest:test_collectCredit_reverts_whenExpired() (gas: 358845) +ExaPluginTest:test_collectCredit_reverts_whenExpired() (gas: 358857) ExaPluginTest:test_collectCredit_reverts_whenHealthFactorLowerThanMinHealthFactor() (gas: 832014) -ExaPluginTest:test_collectCredit_reverts_whenPrposalCausesInsufficientLiquidity() (gas: 1010277) +ExaPluginTest:test_collectCredit_reverts_whenPrposalCausesInsufficientLiquidity() (gas: 1010289) ExaPluginTest:test_collectCredit_reverts_whenReplay() (gas: 843323) ExaPluginTest:test_collectCredit_reverts_whenTimelocked() (gas: 355114) ExaPluginTest:test_collectCredit_toleratesTimeDrift() (gas: 803748) ExaPluginTest:test_collectDebit_collects() (gas: 651749) -ExaPluginTest:test_collectDebit_collects_whenProposalLeavesEnoughLiquidity() (gas: 855108) +ExaPluginTest:test_collectDebit_collects_whenProposalLeavesEnoughLiquidity() (gas: 855120) ExaPluginTest:test_collectDebit_reverts_asNotKeeper() (gas: 362589) -ExaPluginTest:test_collectDebit_reverts_whenExpired() (gas: 358651) +ExaPluginTest:test_collectDebit_reverts_whenExpired() (gas: 358663) ExaPluginTest:test_collectDebit_reverts_whenProposalCausesInsufficientLiquidity() (gas: 852099) ExaPluginTest:test_collectDebit_reverts_whenReplay() (gas: 691191) ExaPluginTest:test_collectDebit_reverts_whenTimelocked() (gas: 354855) ExaPluginTest:test_collectDebit_toleratesTimeDrift() (gas: 651826) -ExaPluginTest:test_collectInstallments_collects() (gas: 1338830) -ExaPluginTest:test_collectInstallments_revertsWhenNoSlippage() (gas: 1203025) +ExaPluginTest:test_collectInstallments_collects() (gas: 1338854) +ExaPluginTest:test_collectInstallments_revertsWhenNoSlippage() (gas: 1203049) ExaPluginTest:test_collectInstallments_reverts_asNotKeeper() (gas: 363607) -ExaPluginTest:test_collectInstallments_reverts_whenExpired() (gas: 361030) +ExaPluginTest:test_collectInstallments_reverts_whenExpired() (gas: 361018) ExaPluginTest:test_collectInstallments_reverts_whenReplay() (gas: 1070925) ExaPluginTest:test_collectInstallments_reverts_whenTimelocked() (gas: 357218) ExaPluginTest:test_collectInstallments_toleratesTimeDrift() (gas: 1195516) @@ -57,7 +57,7 @@ ExaPluginTest:test_setMinHealthFactor_reverts_whenNotAdmin() (gas: 33768) ExaPluginTest:test_setMinHealthFactor_sets_whenAdmin() (gas: 39463) ExaPluginTest:test_swap_reverts_withDisagreement() (gas: 289042) ExaPluginTest:test_swap_swaps() (gas: 268686) -ExaPluginTest:test_withdrawWETH_transfersETH() (gas: 848687) +ExaPluginTest:test_withdrawWETH_transfersETH() (gas: 848699) ExaPluginTest:test_withdraw_reverts_whenNoProposal() (gas: 415178) ExaPluginTest:test_withdraw_reverts_whenNoProposalKeeper() (gas: 358000) ExaPluginTest:test_withdraw_reverts_whenNotKeeper() (gas: 355018) @@ -73,12 +73,12 @@ InstallmentsPreviewerTest:test_preview_returns() (gas: 135598) IssuerCheckerTest:test_setIssuer_emits_IssuerSet() (gas: 41782) IssuerCheckerTest:test_setIssuer_reverts_whenNotAdmin() (gas: 37070) IssuerCheckerTest:test_setIssuer_reverts_whenZeroAddress() (gas: 35449) -MockSwapperTest:test_swapExactAmountIn_swaps() (gas: 220530) -MockSwapperTest:test_swapExactAmountOut_swaps() (gas: 220657) -RefunderTest:test_refund_refunds() (gas: 242371) -RefunderTest:test_refund_reverts_whenExpired() (gas: 69551) -RefunderTest:test_refund_reverts_whenNotKeeper() (gas: 56897) -RefunderTest:test_refund_reverts_whenReplay() (gas: 279261) -RefunderTest:test_refund_reverts_whenTimelocked() (gas: 63310) +MockSwapperTest:test_swapExactAmountIn_swaps() (gas: 220542) +MockSwapperTest:test_swapExactAmountOut_swaps() (gas: 220669) +RefunderTest:test_refund_refunds() (gas: 242383) +RefunderTest:test_refund_reverts_whenExpired() (gas: 69563) +RefunderTest:test_refund_reverts_whenNotKeeper() (gas: 56909) +RefunderTest:test_refund_reverts_whenReplay() (gas: 279285) +RefunderTest:test_refund_reverts_whenTimelocked() (gas: 63298) RefunderTest:test_refund_reverts_whenWrongSignature() (gas: 68975) RefunderTest:test_refund_toleratesTimeDrift() (gas: 242469) \ No newline at end of file diff --git a/contracts/script/Deploy.s.sol b/contracts/script/Deploy.s.sol index 8199edf1..4f49404a 100644 --- a/contracts/script/Deploy.s.sol +++ b/contracts/script/Deploy.s.sol @@ -7,7 +7,6 @@ import { WebauthnOwnerPlugin } from "webauthn-owner-plugin/WebauthnOwnerPlugin.s import { ExaAccountFactory } from "../src/ExaAccountFactory.sol"; import { ExaPlugin, IAuditor, IBalancerVault, IDebtManager, IInstallmentsRouter, IMarket } from "../src/ExaPlugin.sol"; import { IssuerChecker } from "../src/IssuerChecker.sol"; -import { Refunder } from "../src/Refunder.sol"; import { BaseScript } from "./Base.s.sol"; @@ -15,58 +14,31 @@ import { BaseScript } from "./Base.s.sol"; contract DeployScript is BaseScript { ExaAccountFactory public factory; ExaPlugin public exaPlugin; - IssuerChecker public issuerChecker; - WebauthnOwnerPlugin public ownerPlugin; - IAuditor public auditor; - IMarket public exaUSDC; - IMarket public exaWETH; - IDebtManager public debtManager; - IInstallmentsRouter public installmentsRouter; - Refunder public refunder; - IBalancerVault public balancerVault; - - address public admin; - address public keeper; - address public deployer; - address public collector; - address public swapper; - - function setUp() external { - ownerPlugin = WebauthnOwnerPlugin(dependency("webauthn-owner-plugin", "WebauthnOwnerPlugin", "Plugin", 0)); - issuerChecker = IssuerChecker(broadcast("IssuerChecker")); - auditor = IAuditor(protocol("Auditor")); - exaUSDC = IMarket(protocol("MarketUSDC")); - exaWETH = IMarket(protocol("MarketWETH")); - debtManager = IDebtManager(protocol("DebtManager")); - installmentsRouter = IInstallmentsRouter(protocol("InstallmentsRouter")); - refunder = Refunder(broadcast("Refunder")); - - balancerVault = IBalancerVault(protocol("BalancerVault")); - - admin = acct("admin"); - keeper = acct("keeper"); - deployer = acct("deployer"); - collector = acct("collector"); - swapper = acct("swapper"); - } function run() external { - vm.startBroadcast(deployer); + vm.startBroadcast(acct("deployer")); exaPlugin = new ExaPlugin( - admin, - auditor, - exaUSDC, - exaWETH, - balancerVault, - debtManager, - installmentsRouter, - issuerChecker, - collector, - swapper, - keeper + acct("admin"), + IAuditor(protocol("Auditor")), + IMarket(protocol("MarketUSDC")), + IMarket(protocol("MarketWETH")), + IBalancerVault(protocol("BalancerVault")), + IDebtManager(protocol("DebtManager")), + IInstallmentsRouter(protocol("InstallmentsRouter")), + IssuerChecker(broadcast("IssuerChecker")), + acct("collector"), + acct("swapper"), + acct("keeper") + ); + + factory = new ExaAccountFactory( + acct("admin"), + WebauthnOwnerPlugin(dependency("webauthn-owner-plugin", "WebauthnOwnerPlugin", "Plugin", 0)), + exaPlugin, + ACCOUNT_IMPL, + ENTRYPOINT ); - factory = new ExaAccountFactory(admin, ownerPlugin, exaPlugin, ACCOUNT_IMPL, ENTRYPOINT); factory.donateStake{ value: 0.1 ether }(); diff --git a/contracts/script/Refunder.s.sol b/contracts/script/Refunder.s.sol index f064607a..74232723 100644 --- a/contracts/script/Refunder.s.sol +++ b/contracts/script/Refunder.s.sol @@ -6,23 +6,12 @@ import { IMarket, IssuerChecker, Refunder } from "../src/Refunder.sol"; import { BaseScript } from "./Base.s.sol"; contract DeployRefunder is BaseScript { - IMarket public exaUSDC; - IssuerChecker public issuerChecker; Refunder public refunder; - address public keeper; - address public deployer; - - function setUp() external { - exaUSDC = IMarket(protocol("MarketUSDC")); - issuerChecker = IssuerChecker(broadcast("IssuerChecker")); - - keeper = acct("keeper"); - deployer = acct("deployer"); - } - function run() external { - vm.broadcast(deployer); - refunder = new Refunder(acct("admin"), exaUSDC, issuerChecker, keeper); + vm.broadcast(acct("deployer")); + refunder = new Refunder( + acct("admin"), IMarket(protocol("MarketUSDC")), IssuerChecker(broadcast("IssuerChecker")), acct("keeper") + ); } } diff --git a/contracts/test/ExaPlugin.t.sol b/contracts/test/ExaPlugin.t.sol index d1095455..7df4526a 100644 --- a/contracts/test/ExaPlugin.t.sol +++ b/contracts/test/ExaPlugin.t.sol @@ -18,7 +18,6 @@ import { Address } from "openzeppelin-contracts/contracts/utils/Address.sol"; import { ECDSA } from "solady/utils/ECDSA.sol"; import { FixedPointMathLib } from "solady/utils/FixedPointMathLib.sol"; -import { LibString } from "solady/utils/LibString.sol"; import { MockERC20 } from "solmate/src/test/utils/mocks/MockERC20.sol"; @@ -60,7 +59,6 @@ import { DeployProtocol } from "./mocks/Protocol.s.sol"; contract ExaPluginTest is ForkTest { using FixedPointMathLib for uint256; using OwnersLib for address[]; - using LibString for address; using Address for address; using ECDSA for bytes32; @@ -87,16 +85,12 @@ contract ExaPluginTest is ForkTest { MockERC20 internal usdc; function setUp() external { - vm.setEnv("DEPLOYER_ADDRESS", address(this).toHexString()); - collector = payable(makeAddr("collector")); (owner, ownerKey) = makeAddrAndKey("owner"); owners = new address[](1); owners[0] = owner; (keeper, keeperKey) = makeAddrAndKey("keeper"); (issuer, issuerKey) = makeAddrAndKey("issuer"); - vm.setEnv("KEEPER_ADDRESS", keeper.toHexString()); - vm.setEnv("ISSUER_ADDRESS", issuer.toHexString()); new DeployAccount().run(); DeployProtocol p = new DeployProtocol(); @@ -107,25 +101,29 @@ contract ExaPluginTest is ForkTest { exaWETH = IMarket(address(p.exaWETH())); exa = p.exa(); usdc = p.usdc(); - vm.setEnv("PROTOCOL_AUDITOR_ADDRESS", address(auditor).toHexString()); - vm.setEnv("PROTOCOL_MARKETUSDC_ADDRESS", address(exaUSDC).toHexString()); - vm.setEnv("PROTOCOL_USDC_ADDRESS", address(usdc).toHexString()); - - DeployMocks m = new DeployMocks(); - m.setUp(); - m.run(); - vm.setEnv("SWAPPER_ADDRESS", address(m.swapper()).toHexString()); DeployIssuerChecker ic = new DeployIssuerChecker(); + set("issuer", issuer); ic.run(); + unset("issuer"); issuerChecker = ic.issuerChecker(); - vm.setEnv("BROADCAST_ISSUERCHECKER_ADDRESS", address(issuerChecker).toHexString()); + + DeployMocks m = new DeployMocks(); + set("Auditor", address(auditor)); + set("USDC", address(usdc)); + m.run(); + unset("Auditor"); + unset("USDC"); DeployRefunder r = new DeployRefunder(); - r.setUp(); + set("MarketUSDC", address(exaUSDC)); + set("IssuerChecker", address(issuerChecker)); + set("keeper", keeper); r.run(); + unset("MarketUSDC"); + unset("IssuerChecker"); + unset("keeper"); refunder = r.refunder(); - vm.setEnv("BROADCAST_REFUNDER_ADDRESS", address(refunder).toHexString()); exaPlugin = new ExaPlugin( address(this), @@ -1215,17 +1213,6 @@ contract ExaPluginTest is ForkTest { function _setUpLifiFork() internal { vm.createSelectFork("optimism", 127_050_624); account = ExaAccount(payable(0x6120Fb2A9d47f7955298b80363F00C620dB9f6E6)); - - vm.setEnv("DEPLOYER_ADDRESS", ""); - vm.setEnv("KEEPER_ADDRESS", ""); - vm.setEnv("ISSUER_ADDRESS", ""); - vm.setEnv("SWAPPER_ADDRESS", ""); - vm.setEnv("PROTOCOL_AUDITOR_ADDRESS", ""); - vm.setEnv("PROTOCOL_MARKETUSDC_ADDRESS", ""); - vm.setEnv("PROTOCOL_USDC_ADDRESS", ""); - vm.setEnv("BROADCAST_ISSUERCHECKER_ADDRESS", ""); - vm.setEnv("BROADCAST_REFUNDER_ADDRESS", ""); - issuerChecker = IssuerChecker(broadcast("IssuerChecker")); vm.prank(acct("deployer")); issuerChecker.setIssuer(issuer); diff --git a/contracts/test/Fork.t.sol b/contracts/test/Fork.t.sol index 900fcbae..aafa0918 100644 --- a/contracts/test/Fork.t.sol +++ b/contracts/test/Fork.t.sol @@ -11,8 +11,17 @@ abstract contract ForkTest is Test { using LibString for string; using stdJson for string; + function set(string memory name, address addr) internal { + vm.store(address(this), keccak256(abi.encode(name)), bytes32(uint256(uint160(addr)))); + } + + function unset(string memory name) internal { + vm.store(address(this), keccak256(abi.encode(name)), 0); + } + function acct(string memory name) internal returns (address addr) { - addr = vm.envOr(string.concat(name.upper(), "_ADDRESS"), address(0)); + addr = address(uint160(uint256(vm.load(msg.sender, keccak256(abi.encode(name)))))); + if (addr == address(0)) addr = vm.envOr(string.concat(name.upper(), "_ADDRESS"), address(0)); if (addr == address(0)) { string memory deploy = vm.readFile("deploy.json"); string memory key = string.concat(".accounts.", name, ".", block.chainid.toString()); @@ -24,7 +33,8 @@ abstract contract ForkTest is Test { } function protocol(string memory name) internal returns (address addr) { - addr = vm.envOr(string.concat("PROTOCOL_", name.upper(), "_ADDRESS"), address(0)); + addr = address(uint160(uint256(vm.load(msg.sender, keccak256(abi.encode(name)))))); + if (addr == address(0)) addr = vm.envOr(string.concat("PROTOCOL_", name.upper(), "_ADDRESS"), address(0)); if (addr == address(0)) { addr = vm.readFile( string.concat( @@ -55,7 +65,8 @@ abstract contract ForkTest is Test { } function _broadcast(string memory name, string memory script, uint256 index) private returns (address addr) { - addr = vm.envOr(string.concat("BROADCAST_", name.upper(), "_ADDRESS"), address(0)); + addr = address(uint160(uint256(vm.load(msg.sender, keccak256(abi.encode(name)))))); + if (addr == address(0)) addr = vm.envOr(string.concat("BROADCAST_", name.upper(), "_ADDRESS"), address(0)); if (addr == address(0)) { addr = vm.readFile(string.concat(script, ".s.sol/", block.chainid.toString(), "/run-latest.json")).readAddress( string.concat(".transactions[", index.toString(), "].contractAddress") diff --git a/contracts/test/InstallmentsPreviewer.t.sol b/contracts/test/InstallmentsPreviewer.t.sol index 367c3633..a43078f2 100644 --- a/contracts/test/InstallmentsPreviewer.t.sol +++ b/contracts/test/InstallmentsPreviewer.t.sol @@ -3,28 +3,23 @@ pragma solidity ^0.8.0; import { ForkTest } from "./Fork.t.sol"; -import { LibString } from "solady/utils/LibString.sol"; - import { DeployInstallmentsPreviewer } from "../script/InstallmentsPreviewer.s.sol"; import { ICollectableMarket, InstallmentsPreviewer } from "../src/InstallmentsPreviewer.sol"; import { DeployProtocol } from "./mocks/Protocol.s.sol"; contract InstallmentsPreviewerTest is ForkTest { - using LibString for address; - ICollectableMarket internal exaUSDC; InstallmentsPreviewer internal previewer; function setUp() external { - vm.setEnv("DEPLOYER_ADDRESS", address(this).toHexString()); - DeployProtocol p = new DeployProtocol(); p.run(); exaUSDC = ICollectableMarket(address(p.exaUSDC())); - vm.setEnv("PROTOCOL_MARKETUSDC_ADDRESS", address(exaUSDC).toHexString()); DeployInstallmentsPreviewer ip = new DeployInstallmentsPreviewer(); + set("MarketUSDC", address(exaUSDC)); ip.run(); + unset("MarketUSDC"); previewer = ip.installmentsPreviewer(); } diff --git a/contracts/test/MockSwapper.t.sol b/contracts/test/MockSwapper.t.sol index ed2a8bb6..eff430a4 100644 --- a/contracts/test/MockSwapper.t.sol +++ b/contracts/test/MockSwapper.t.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; -import { LibString } from "solady/utils/LibString.sol"; import { MockERC20 } from "solmate/src/test/utils/mocks/MockERC20.sol"; import { ForkTest } from "./Fork.t.sol"; @@ -10,8 +9,6 @@ import { DeployMocks } from "./mocks/Mocks.s.sol"; import { DeployProtocol } from "./mocks/Protocol.s.sol"; contract MockSwapperTest is ForkTest { - using LibString for address; - MockSwapper internal mockSwapper; MockERC20 internal exa; MockERC20 internal usdc; @@ -21,12 +18,13 @@ contract MockSwapperTest is ForkTest { p.run(); exa = p.exa(); usdc = p.usdc(); - vm.setEnv("PROTOCOL_AUDITOR_ADDRESS", address(p.auditor()).toHexString()); - vm.setEnv("PROTOCOL_USDC_ADDRESS", address(usdc).toHexString()); DeployMocks m = new DeployMocks(); - m.setUp(); + set("Auditor", address(p.auditor())); + set("USDC", address(usdc)); m.run(); + unset("Auditor"); + unset("USDC"); mockSwapper = m.swapper(); exa.mint(address(this), 10_000e18); diff --git a/contracts/test/Refunder.t.sol b/contracts/test/Refunder.t.sol index 21e1f4a4..5d75af45 100644 --- a/contracts/test/Refunder.t.sol +++ b/contracts/test/Refunder.t.sol @@ -3,8 +3,6 @@ pragma solidity ^0.8.0; import { ForkTest } from "./Fork.t.sol"; -import { LibString } from "solady/utils/LibString.sol"; - import { MockERC20 } from "solmate/src/test/utils/mocks/MockERC20.sol"; import { IMarket, Unauthorized } from "../src/IExaAccount.sol"; @@ -13,8 +11,6 @@ import { Refunder } from "../src/Refunder.sol"; import { DeployProtocol } from "./mocks/Protocol.s.sol"; contract RefunderTest is ForkTest { - using LibString for address; - address internal keeper; uint256 internal keeperKey; address internal issuer; @@ -28,7 +24,6 @@ contract RefunderTest is ForkTest { address internal bob = address(0xb0b); function setUp() external { - vm.setEnv("DEPLOYER_ADDRESS", address(this).toHexString()); DeployProtocol p = new DeployProtocol(); p.run(); diff --git a/contracts/test/mocks/Mocks.s.sol b/contracts/test/mocks/Mocks.s.sol index a0998d47..cfcb6f7a 100644 --- a/contracts/test/mocks/Mocks.s.sol +++ b/contracts/test/mocks/Mocks.s.sol @@ -17,18 +17,13 @@ contract DeployMocks is BaseScript { using FixedPointMathLib for uint256; using LibString for string; - Auditor public auditor; - MockERC20 public usdc; - MockVelodromeFactory public velodromeFactory; MockSwapper public swapper; - function setUp() external { - auditor = Auditor(protocol("Auditor")); - usdc = MockERC20(protocol("USDC")); - } - function run() external { + Auditor auditor = Auditor(protocol("Auditor")); + MockERC20 usdc = MockERC20(protocol("USDC")); + vm.startBroadcast(acct("deployer")); velodromeFactory = new MockVelodromeFactory();