Skip to content

Commit

Permalink
add test for transmission of report with a mixed batch of billing tok…
Browse files Browse the repository at this point in the history
…ens (#12656)
  • Loading branch information
RyanRHall authored Apr 2, 2024
1 parent 42e72d2 commit 081d02a
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 39 deletions.
77 changes: 44 additions & 33 deletions contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,6 @@ contract SetConfig is SetUp {
}
}

// allow NOPs to withdraw balances made before disableOffchainNOPsOffchain is called
contract NOPsSettlement is SetUp {
event NOPsSettledOffchain(address[] payees, uint256[] payments);
event FundsWithdrawn(uint256 indexed id, uint256 amount, address to);
Expand Down Expand Up @@ -1000,38 +999,6 @@ contract NOPsSettlement is SetUp {
registry.withdrawFunds(id, UPKEEP_ADMIN);
}

function _transmit(uint256 id, Registry registry) internal {
uint256[] memory upkeepIds = new uint256[](1);
uint256[] memory gasLimits = new uint256[](1);
bytes[] memory performDatas = new bytes[](1);
bytes[] memory triggers = new bytes[](1);
upkeepIds[0] = id;
gasLimits[0] = 1000000;
triggers[0] = _encodeConditionalTrigger(
AutoBase.ConditionalTrigger(uint32(block.number - 1), blockhash(block.number - 1))
);
AutoBase.Report memory report = AutoBase.Report(
uint256(1000000000),
uint256(2000000000),
upkeepIds,
gasLimits,
triggers,
performDatas
);

bytes memory reportBytes = _encodeReport(report);
(, , bytes32 configDigest) = registry.latestConfigDetails();
bytes32[3] memory reportContext = [configDigest, configDigest, configDigest];
uint256[] memory signerPKs = new uint256[](2);
signerPKs[0] = SIGNING_KEY0;
signerPKs[1] = SIGNING_KEY1;
(bytes32[] memory rs, bytes32[] memory ss, bytes32 vs) = _signReport(reportBytes, reportContext, signerPKs);

vm.startPrank(TRANSMITTERS[0]);
registry.transmit(reportContext, reportBytes, rs, ss, vs);
vm.stopPrank();
}

function _configureWithNewTransmitters(Registry registry, Registrar registrar) internal {
IERC20[] memory billingTokens = new IERC20[](1);
billingTokens[0] = IERC20(address(usdToken));
Expand Down Expand Up @@ -1345,3 +1312,47 @@ contract BillingOverrides is SetUp {
assertGt(maxPayment2, maxPayment1);
}
}

contract Transmit is SetUp {
function test_handlesMixedBatchOfBillingTokens() external {
uint256[] memory prevUpkeepBalances = new uint256[](3);
prevUpkeepBalances[0] = registry.getBalance(linkUpkeepID);
prevUpkeepBalances[1] = registry.getBalance(usdUpkeepID);
prevUpkeepBalances[2] = registry.getBalance(nativeUpkeepID);
uint256[] memory prevTokenBalances = new uint256[](3);
prevTokenBalances[0] = linkToken.balanceOf(address(registry));
prevTokenBalances[1] = usdToken.balanceOf(address(registry));
prevTokenBalances[2] = weth.balanceOf(address(registry));
uint256[] memory prevReserveBalances = new uint256[](3);
prevReserveBalances[0] = registry.getReserveAmount(address(linkToken));
prevReserveBalances[1] = registry.getReserveAmount(address(usdToken));
prevReserveBalances[2] = registry.getReserveAmount(address(weth));
uint256[] memory upkeepIDs = new uint256[](3);
upkeepIDs[0] = linkUpkeepID;
upkeepIDs[1] = usdUpkeepID;
upkeepIDs[2] = nativeUpkeepID;
// do the thing
_transmit(upkeepIDs, registry);
// assert upkeep balances have decreased
require(prevUpkeepBalances[0] > registry.getBalance(linkUpkeepID), "link upkeep balance should have decreased");
require(prevUpkeepBalances[1] > registry.getBalance(usdUpkeepID), "usd upkeep balance should have decreased");
require(prevUpkeepBalances[2] > registry.getBalance(nativeUpkeepID), "native upkeep balance should have decreased");
// assert token balances have not changed
assertEq(prevTokenBalances[0], linkToken.balanceOf(address(registry)));
assertEq(prevTokenBalances[1], usdToken.balanceOf(address(registry)));
assertEq(prevTokenBalances[2], weth.balanceOf(address(registry)));
// assert reserve amounts have adjusted accordingly
require(
prevReserveBalances[0] < registry.getReserveAmount(address(linkToken)),
"usd reserve amount should have increased"
); // link reserve amount increases in value equal to the decrease of the other reserve amounts
require(
prevReserveBalances[1] > registry.getReserveAmount(address(usdToken)),
"usd reserve amount should have decreased"
);
require(
prevReserveBalances[2] > registry.getReserveAmount(address(weth)),
"native reserve amount should have decreased"
);
}
}
58 changes: 52 additions & 6 deletions contracts/src/v0.8/automation/dev/test/BaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {AutomationRegistryBase2_3 as AutoBase} from "../v2_3/AutomationRegistryB
import {AutomationRegistryLogicA2_3} from "../v2_3/AutomationRegistryLogicA2_3.sol";
import {AutomationRegistryLogicB2_3} from "../v2_3/AutomationRegistryLogicB2_3.sol";
import {AutomationRegistryLogicC2_3} from "../v2_3/AutomationRegistryLogicC2_3.sol";
import {IAutomationRegistryMaster2_3, AutomationRegistryBase2_3} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol";
import {IAutomationRegistryMaster2_3 as Registry, AutomationRegistryBase2_3} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol";
import {AutomationRegistrar2_3} from "../v2_3/AutomationRegistrar2_3.sol";
import {ChainModuleBase} from "../../chains/ChainModuleBase.sol";
import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
Expand Down Expand Up @@ -127,7 +127,7 @@ contract BaseTest is Test {
}

/// @notice deploys the component parts of a registry, but nothing more
function deployRegistry(AutoBase.PayoutMode payoutMode) internal returns (IAutomationRegistryMaster2_3) {
function deployRegistry(AutoBase.PayoutMode payoutMode) internal returns (Registry) {
AutomationForwarderLogic forwarderLogic = new AutomationForwarderLogic();
AutomationRegistryLogicC2_3 logicC2_3 = new AutomationRegistryLogicC2_3(
address(linkToken),
Expand All @@ -141,14 +141,14 @@ contract BaseTest is Test {
);
AutomationRegistryLogicB2_3 logicB2_3 = new AutomationRegistryLogicB2_3(logicC2_3);
AutomationRegistryLogicA2_3 logicA2_3 = new AutomationRegistryLogicA2_3(logicB2_3);
return IAutomationRegistryMaster2_3(payable(address(new AutomationRegistry2_3(logicA2_3))));
return Registry(payable(address(new AutomationRegistry2_3(logicA2_3))));
}

/// @notice deploys and configures a registry, registrar, and everything needed for most tests
function deployAndConfigureRegistryAndRegistrar(
AutoBase.PayoutMode payoutMode
) internal returns (IAutomationRegistryMaster2_3, AutomationRegistrar2_3) {
IAutomationRegistryMaster2_3 registry = deployRegistry(payoutMode);
) internal returns (Registry, AutomationRegistrar2_3) {
Registry registry = deployRegistry(payoutMode);

IERC20[] memory billingTokens = new IERC20[](3);
billingTokens[0] = IERC20(address(usdToken));
Expand Down Expand Up @@ -258,7 +258,7 @@ contract BaseTest is Test {
/// @notice this function updates the billing config for the provided token on the provided registry,
/// and throws an error if the token is not found
function _updateBillingTokenConfig(
IAutomationRegistryMaster2_3 registry,
Registry registry,
address billingToken,
AutomationRegistryBase2_3.BillingConfig memory newConfig
) internal {
Expand Down Expand Up @@ -291,6 +291,52 @@ contract BaseTest is Test {
);
}

function _transmit(uint256 id, Registry registry) internal {
uint256[] memory ids = new uint256[](1);
ids[0] = id;
_transmit(ids, registry);
}

function _transmit(uint256[] memory ids, Registry registry) internal {
uint256[] memory upkeepIds = new uint256[](ids.length);
uint256[] memory gasLimits = new uint256[](ids.length);
bytes[] memory performDatas = new bytes[](ids.length);
bytes[] memory triggers = new bytes[](ids.length);
for (uint256 i = 0; i < ids.length; i++) {
upkeepIds[i] = ids[i];
gasLimits[i] = registry.getUpkeep(ids[i]).performGas;
performDatas[i] = new bytes(0);
uint8 triggerType = registry.getTriggerType(ids[i]);
if (triggerType == 0) {
triggers[i] = _encodeConditionalTrigger(
AutoBase.ConditionalTrigger(uint32(block.number - 1), blockhash(block.number - 1))
);
} else {
revert("not implemented");
}
}
AutoBase.Report memory report = AutoBase.Report(
uint256(1000000000),
uint256(2000000000),
upkeepIds,
gasLimits,
triggers,
performDatas
);

bytes memory reportBytes = _encodeReport(report);
(, , bytes32 configDigest) = registry.latestConfigDetails();
bytes32[3] memory reportContext = [configDigest, configDigest, configDigest];
uint256[] memory signerPKs = new uint256[](2);
signerPKs[0] = SIGNING_KEY0;
signerPKs[1] = SIGNING_KEY1;
(bytes32[] memory rs, bytes32[] memory ss, bytes32 vs) = _signReport(reportBytes, reportContext, signerPKs);

vm.startPrank(TRANSMITTERS[0]);
registry.transmit(reportContext, reportBytes, rs, ss, vs);
vm.stopPrank();
}

/// @notice Gather signatures on report data
/// @param report - Report bytes generated from `_buildReport`
/// @param reportContext - Report context bytes32 generated from `_buildReport`
Expand Down

0 comments on commit 081d02a

Please sign in to comment.