Skip to content

Commit

Permalink
✅ contracts: inject test deployments through storage, simplify setup
Browse files Browse the repository at this point in the history
  • Loading branch information
cruzdanilo committed Dec 31, 2024
1 parent 7d7a9fb commit 846642a
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 139 deletions.
38 changes: 19 additions & 19 deletions contracts/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
68 changes: 20 additions & 48 deletions contracts/script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,66 +7,38 @@ 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";

// solhint-disable-next-line max-states-count
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 }();

Expand Down
19 changes: 4 additions & 15 deletions contracts/script/Refunder.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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")
);
}
}
43 changes: 15 additions & 28 deletions contracts/test/ExaPlugin.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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;

Expand All @@ -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();
Expand All @@ -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),
Expand Down Expand Up @@ -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);
Expand Down
17 changes: 14 additions & 3 deletions contracts/test/Fork.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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(
Expand Down Expand Up @@ -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")
Expand Down
9 changes: 2 additions & 7 deletions contracts/test/InstallmentsPreviewer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
10 changes: 4 additions & 6 deletions contracts/test/MockSwapper.t.sol
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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;
Expand All @@ -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);
Expand Down
Loading

0 comments on commit 846642a

Please sign in to comment.