Skip to content

Commit

Permalink
Refactor registry 2.3 foundry tests (#12499)
Browse files Browse the repository at this point in the history
* refactorfoundry tests

* regenerate wrappers
  • Loading branch information
RyanRHall authored Mar 19, 2024
1 parent 3ca3494 commit 1a36386
Show file tree
Hide file tree
Showing 10 changed files with 474 additions and 278 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-seas-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

refactor foundry tests for auto 2.3
5 changes: 5 additions & 0 deletions contracts/.changeset/pretty-cups-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@chainlink/contracts": patch
---

auto 2.3 foundry test refactor

Large diffs are not rendered by default.

165 changes: 52 additions & 113 deletions contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,180 +7,119 @@ import {ChainModuleBase} from "../../chains/ChainModuleBase.sol";

// forge test --match-path src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol

contract AutomationRegistry2_3_SetUp is BaseTest {
contract SetUp is BaseTest {
address[] internal s_registrars;

IAutomationRegistryMaster2_3 internal registryMaster;
IAutomationRegistryMaster2_3 internal registry;

function setUp() public override {
function setUp() public virtual override {
super.setUp();

s_registrars = new address[](1);
s_registrars[0] = 0x3a0eDE26aa188BFE00b9A0C9A431A1a0CA5f7966;

registryMaster = deployRegistry();
(registry, ) = deployAndConfigureAll();
}
}

contract AutomationRegistry2_3_LatestConfigDetails is AutomationRegistry2_3_SetUp {
contract LatestConfigDetails is SetUp {
function testGet() public {
(uint32 configCount, uint32 blockNumber, bytes32 configDigest) = registryMaster.latestConfigDetails();
assertEq(configCount, 0);
assertEq(blockNumber, 0);
assertEq(configDigest, "");
(uint32 configCount, uint32 blockNumber, bytes32 configDigest) = registry.latestConfigDetails();
assertEq(configCount, 1);
assertTrue(blockNumber > 0);
assertNotEq(configDigest, "");
}
}

contract AutomationRegistry2_3_CheckUpkeep is AutomationRegistry2_3_SetUp {
contract CheckUpkeep is SetUp {
function testPreventExecutionOnCheckUpkeep() public {
uint256 id = 1;
bytes memory triggerData = abi.encodePacked("trigger_data");

// The tx.origin is the DEFAULT_SENDER (0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38) of foundry
// Expecting a revert since the tx.origin is not address(0)
vm.expectRevert(abi.encodeWithSelector(IAutomationRegistryMaster2_3.OnlySimulatedBackend.selector));
registryMaster.checkUpkeep(id, triggerData);
registry.checkUpkeep(id, triggerData);
}
}

contract AutomationRegistry2_3_Withdraw is AutomationRegistry2_3_SetUp {
contract Withdraw is SetUp {
address internal aMockAddress = address(0x1111111111111111111111111111111111111113);

function mintLink(address recipient, uint256 amount) public {
vm.prank(OWNER);
//mint the link to the recipient
linkToken.mint(recipient, amount);
}

function mintERC20(address recipient, uint256 amount) public {
vm.prank(OWNER);
//mint the ERC20 to the recipient
mockERC20.mint(recipient, amount);
}

function setConfigForWithdraw() public {
address module = address(new ChainModuleBase());
AutomationRegistryBase2_3.OnchainConfig memory cfg = AutomationRegistryBase2_3.OnchainConfig({
checkGasLimit: 5_000_000,
stalenessSeconds: 90_000,
gasCeilingMultiplier: 0,
maxPerformGas: 10_000_000,
maxCheckDataSize: 5_000,
maxPerformDataSize: 5_000,
maxRevertDataSize: 5_000,
fallbackGasPrice: 20_000_000_000,
fallbackLinkPrice: 2_000_000_000, // $20
fallbackNativePrice: 400_000_000_000, // $4,000
transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c,
registrars: s_registrars,
upkeepPrivilegeManager: 0xD9c855F08A7e460691F41bBDDe6eC310bc0593D8,
chainModule: module,
reorgProtectionEnabled: true,
financeAdmin: FINANCE_ADMIN
});
bytes memory offchainConfigBytes = abi.encode(1234, ZERO_ADDRESS);

registryMaster.setConfigTypeSafe(
SIGNERS,
TRANSMITTERS,
F,
cfg,
OFFCHAIN_CONFIG_VERSION,
offchainConfigBytes,
new address[](0),
new AutomationRegistryBase2_3.BillingConfig[](0)
);
}

function testLinkAvailableForPaymentReturnsLinkBalance() public {
//simulate a deposit of link to the liquidity pool
mintLink(address(registryMaster), 1e10);
mintLink(address(registry), 1e10);

//check there's a balance
assertGt(linkToken.balanceOf(address(registryMaster)), 0);
assertGt(linkToken.balanceOf(address(registry)), 0);

//check the link available for payment is the link balance
assertEq(registryMaster.linkAvailableForPayment(), linkToken.balanceOf(address(registryMaster)));
assertEq(registry.linkAvailableForPayment(), linkToken.balanceOf(address(registry)));
}

function testWithdrawLinkFeesRevertsBecauseOnlyFinanceAdminAllowed() public {
// set config with the finance admin
setConfigForWithdraw();

vm.expectRevert(abi.encodeWithSelector(IAutomationRegistryMaster2_3.OnlyFinanceAdmin.selector));
registryMaster.withdrawLinkFees(aMockAddress, 1);
registry.withdrawLinkFees(aMockAddress, 1);
}

function testWithdrawLinkFeesRevertsBecauseOfInsufficientBalance() public {
// set config with the finance admin
setConfigForWithdraw();

vm.startPrank(FINANCE_ADMIN);

// try to withdraw 1 link while there is 0 balance
vm.expectRevert(abi.encodeWithSelector(IAutomationRegistryMaster2_3.InsufficientBalance.selector, 0, 1));
registryMaster.withdrawLinkFees(aMockAddress, 1);
registry.withdrawLinkFees(aMockAddress, 1);

vm.stopPrank();
}

function testWithdrawLinkFeesRevertsBecauseOfInvalidRecipient() public {
// set config with the finance admin
setConfigForWithdraw();

vm.startPrank(FINANCE_ADMIN);

// try to withdraw 1 link while there is 0 balance
vm.expectRevert(abi.encodeWithSelector(IAutomationRegistryMaster2_3.InvalidRecipient.selector));
registryMaster.withdrawLinkFees(ZERO_ADDRESS, 1);
registry.withdrawLinkFees(ZERO_ADDRESS, 1);

vm.stopPrank();
}

function testWithdrawLinkFeeSuccess() public {
// set config with the finance admin
setConfigForWithdraw();

//simulate a deposit of link to the liquidity pool
mintLink(address(registryMaster), 1e10);
mintLink(address(registry), 1e10);

//check there's a balance
assertGt(linkToken.balanceOf(address(registryMaster)), 0);
assertGt(linkToken.balanceOf(address(registry)), 0);

vm.startPrank(FINANCE_ADMIN);

// try to withdraw 1 link while there is a ton of link available
registryMaster.withdrawLinkFees(aMockAddress, 1);
registry.withdrawLinkFees(aMockAddress, 1);

vm.stopPrank();

assertEq(linkToken.balanceOf(address(aMockAddress)), 1);
assertEq(linkToken.balanceOf(address(registryMaster)), 1e10 - 1);
assertEq(linkToken.balanceOf(address(registry)), 1e10 - 1);
}

function testWithdrawERC20FeeSuccess() public {
// set config with the finance admin
setConfigForWithdraw();

// simulate a deposit of ERC20 to the liquidity pool
mintERC20(address(registryMaster), 1e10);
mintERC20(address(registry), 1e10);

// check there's a balance
assertGt(mockERC20.balanceOf(address(registryMaster)), 0);
assertGt(mockERC20.balanceOf(address(registry)), 0);

vm.startPrank(FINANCE_ADMIN);

// try to withdraw 1 link while there is a ton of link available
registryMaster.withdrawERC20Fees(address(mockERC20), aMockAddress, 1);
registry.withdrawERC20Fees(address(mockERC20), aMockAddress, 1);

vm.stopPrank();

assertEq(mockERC20.balanceOf(address(aMockAddress)), 1);
assertEq(mockERC20.balanceOf(address(registryMaster)), 1e10 - 1);
assertEq(mockERC20.balanceOf(address(registry)), 1e10 - 1);
}
}

contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
contract SetConfig is SetUp {
event ConfigSet(
uint32 previousConfigBlockNumber,
bytes32 configDigest,
Expand Down Expand Up @@ -215,8 +154,8 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
});

function testSetConfigSuccess() public {
(uint32 configCount, , ) = registryMaster.latestConfigDetails();
assertEq(configCount, 0);
(uint32 configCount, uint32 blockNumber, ) = registry.latestConfigDetails();
assertEq(configCount, 1);

address billingTokenAddress = address(0x1111111111111111111111111111111111111111);
address[] memory billingTokens = new address[](1);
Expand All @@ -239,7 +178,7 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
bytes memory offchainConfigBytes = abi.encode(a, b);
bytes32 configDigest = _configDigestFromConfigData(
block.chainid,
address(registryMaster),
address(registry),
++configCount,
SIGNERS,
TRANSMITTERS,
Expand All @@ -251,7 +190,7 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {

vm.expectEmit();
emit ConfigSet(
0,
blockNumber,
configDigest,
configCount,
SIGNERS,
Expand All @@ -262,7 +201,7 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
offchainConfigBytes
);

registryMaster.setConfig(
registry.setConfig(
SIGNERS,
TRANSMITTERS,
F,
Expand All @@ -271,25 +210,25 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
offchainConfigBytes
);

(, , address[] memory signers, address[] memory transmitters, uint8 f) = registryMaster.getState();
(, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState();

assertEq(signers, SIGNERS);
assertEq(transmitters, TRANSMITTERS);
assertEq(f, F);

AutomationRegistryBase2_3.BillingConfig memory config = registryMaster.getBillingTokenConfig(billingTokenAddress);
AutomationRegistryBase2_3.BillingConfig memory config = registry.getBillingTokenConfig(billingTokenAddress);
assertEq(config.gasFeePPB, 5_000);
assertEq(config.flatFeeMicroLink, 20_000);
assertEq(config.priceFeed, 0x2222222222222222222222222222222222222222);
assertEq(config.minSpend, 100_000);

address[] memory tokens = registryMaster.getBillingTokens();
address[] memory tokens = registry.getBillingTokens();
assertEq(tokens.length, 1);
}

function testSetConfigMultipleBillingConfigsSuccess() public {
(uint32 configCount, , ) = registryMaster.latestConfigDetails();
assertEq(configCount, 0);
(uint32 configCount, , ) = registry.latestConfigDetails();
assertEq(configCount, 1);

address billingTokenAddress1 = address(0x1111111111111111111111111111111111111111);
address billingTokenAddress2 = address(0x1111111111111111111111111111111111111112);
Expand Down Expand Up @@ -319,7 +258,7 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
address b = ZERO_ADDRESS;
bytes memory offchainConfigBytes = abi.encode(a, b);

registryMaster.setConfig(
registry.setConfig(
SIGNERS,
TRANSMITTERS,
F,
Expand All @@ -328,33 +267,33 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
offchainConfigBytes
);

(, , address[] memory signers, address[] memory transmitters, uint8 f) = registryMaster.getState();
(, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState();

assertEq(signers, SIGNERS);
assertEq(transmitters, TRANSMITTERS);
assertEq(f, F);

AutomationRegistryBase2_3.BillingConfig memory config1 = registryMaster.getBillingTokenConfig(billingTokenAddress1);
AutomationRegistryBase2_3.BillingConfig memory config1 = registry.getBillingTokenConfig(billingTokenAddress1);
assertEq(config1.gasFeePPB, 5_001);
assertEq(config1.flatFeeMicroLink, 20_001);
assertEq(config1.priceFeed, 0x2222222222222222222222222222222222222221);
assertEq(config1.fallbackPrice, 100);
assertEq(config1.minSpend, 100);

AutomationRegistryBase2_3.BillingConfig memory config2 = registryMaster.getBillingTokenConfig(billingTokenAddress2);
AutomationRegistryBase2_3.BillingConfig memory config2 = registry.getBillingTokenConfig(billingTokenAddress2);
assertEq(config2.gasFeePPB, 5_002);
assertEq(config2.flatFeeMicroLink, 20_002);
assertEq(config2.priceFeed, 0x2222222222222222222222222222222222222222);
assertEq(config2.fallbackPrice, 200);
assertEq(config2.minSpend, 200);

address[] memory tokens = registryMaster.getBillingTokens();
address[] memory tokens = registry.getBillingTokens();
assertEq(tokens.length, 2);
}

function testSetConfigTwiceAndLastSetOverwrites() public {
(uint32 configCount, , ) = registryMaster.latestConfigDetails();
assertEq(configCount, 0);
(uint32 configCount, , ) = registry.latestConfigDetails();
assertEq(configCount, 1);

// BillingConfig1
address billingTokenAddress1 = address(0x1111111111111111111111111111111111111111);
Expand Down Expand Up @@ -393,7 +332,7 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
bytes memory offchainConfigBytes = abi.encode(a, b);

// set config once
registryMaster.setConfig(
registry.setConfig(
SIGNERS,
TRANSMITTERS,
F,
Expand All @@ -403,7 +342,7 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
);

// set config twice
registryMaster.setConfig(
registry.setConfig(
SIGNERS,
TRANSMITTERS,
F,
Expand All @@ -412,26 +351,26 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
offchainConfigBytes
);

(, , address[] memory signers, address[] memory transmitters, uint8 f) = registryMaster.getState();
(, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState();

assertEq(signers, SIGNERS);
assertEq(transmitters, TRANSMITTERS);
assertEq(f, F);

AutomationRegistryBase2_3.BillingConfig memory config2 = registryMaster.getBillingTokenConfig(billingTokenAddress2);
AutomationRegistryBase2_3.BillingConfig memory config2 = registry.getBillingTokenConfig(billingTokenAddress2);
assertEq(config2.gasFeePPB, 5_002);
assertEq(config2.flatFeeMicroLink, 20_002);
assertEq(config2.priceFeed, 0x2222222222222222222222222222222222222222);
assertEq(config2.fallbackPrice, 200);
assertEq(config2.minSpend, 200);

address[] memory tokens = registryMaster.getBillingTokens();
address[] memory tokens = registry.getBillingTokens();
assertEq(tokens.length, 1);
}

function testSetConfigDuplicateBillingConfigFailure() public {
(uint32 configCount, , ) = registryMaster.latestConfigDetails();
assertEq(configCount, 0);
(uint32 configCount, , ) = registry.latestConfigDetails();
assertEq(configCount, 1);

address billingTokenAddress1 = address(0x1111111111111111111111111111111111111111);
address billingTokenAddress2 = address(0x1111111111111111111111111111111111111111);
Expand Down Expand Up @@ -463,7 +402,7 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {

// expect revert because of duplicate tokens
vm.expectRevert(abi.encodeWithSelector(IAutomationRegistryMaster2_3.DuplicateEntry.selector));
registryMaster.setConfig(
registry.setConfig(
SIGNERS,
TRANSMITTERS,
F,
Expand Down
Loading

0 comments on commit 1a36386

Please sign in to comment.