Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinkBalMonV2(minPerform) and CCIPWatchlist AutoUpdate Contract #13605

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions contracts/src/v0.8/automation/upkeeps/CCIPAutoWatchlist.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

import "../../shared/access/ConfirmedOwner.sol";
import {AutomationCompatibleInterface} from "../interfaces/AutomationCompatibleInterface.sol";
import {AccessControl} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/access/AccessControl.sol";
import {LinkAvailableBalanceMonitor} from "../upkeeps/LinkAvailableBalanceMonitor.sol";
import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol";

contract CCIPOnRampAutoWatchlist is ILogAutomation, ConfirmedOwner {
event setWatchlistOnMonitor(uint64 indexed _dstChainSelector, address indexed _onRamp);

LinkAvailableBalanceMonitor public linkAvailableBalanceMonitorAddress;
address public routerAddress;

// keccak256 signature for OnRampSet event set as constant
bytes32 private constant EVENT_SIGNATURE = 0x1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23;

constructor(address contractaddress, address _routerAddress) ConfirmedOwner(msg.sender) {
linkAvailableBalanceMonitorAddress = LinkAvailableBalanceMonitor(contractaddress);
routerAddress = _routerAddress;
}

// Option to change the Balance Monitor Address
function setBalanceMonitorAddress(address _newBalMonAddress) external onlyOwner {
linkAvailableBalanceMonitorAddress = LinkAvailableBalanceMonitor(_newBalMonAddress);
}

// Option to change the Router Address
// Changing Router Address would also require setting up new Upkeep as Upkeep is linked with the Router and cannot be changed
function setRouterAddress(address _newRouterAddress) external onlyOwner {
routerAddress = _newRouterAddress;
}

// updateWatchList function takes emitted OnRamp Address and dstChainSelector as input and calls addToWatchListOrDecommission function of LinkAvailableBalanceMonitor passing these paraments to add the OnRamp address to the watchlist
// addToWatchListOrDecommission function of LinkAvailableBalanceMonitor is used for sanity check before adding the address on the watchlist
// updateWatchList Function is set to internal for security purposes
function updateWatchList(address _targetAddress, uint64 _dstChainSelector) internal {
linkAvailableBalanceMonitorAddress.addToWatchListOrDecommission(_targetAddress, _dstChainSelector);
}

function checkLog(
poke1994 marked this conversation as resolved.
Show resolved Hide resolved
Log calldata log,
bytes memory checkData
) external view override returns (bool upkeepNeeded, bytes memory performData) {
// Ensure Router address is set
require(routerAddress != address(0), "Router address not set");

// Check if the log source matches router contract and topics contain the event signature
if (log.source == routerAddress && log.topics.length > 0 && log.topics[0] == EVENT_SIGNATURE) {
// Extract the indexed parameter from the log
uint64 destChainSelector = uint64(uint256(log.topics[1])); // cast to uint64
address onRamp = address(uint160(uint256(bytes32(log.data)))); // extract from log.data

// No sanity checks necessary as the would on to relay information to LinkAvailableBalanceMonitor as it is
// Checking is enabled in LinkAvailableBalanceMonitor contract
return (true, abi.encode(destChainSelector, onRamp));
}

// If the event signature doesn't match or log source is not Router contract, no upkeep is needed
return (false, "");
}

function performUpkeep(bytes memory performData) external override {
// Decode the data received from checkLog
(uint64 destChainSelector, address onRamp) = abi.decode(performData, (uint64, address));
// Perform the necessary upkeep actions based on the decoded data
updateWatchList(onRamp, destChainSelector);
// Emitting setWatchlist event to track the last added OnRamp addresses in form of Logs
emit setWatchlistOnMonitor(destChainSelector, onRamp);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
event UpkeepIntervalSet(uint256 oldUpkeepInterval, uint256 newUpkeepInterval);
event MaxCheckSet(uint256 oldMaxCheck, uint256 newMaxCheck);
event MaxPerformSet(uint256 oldMaxPerform, uint256 newMaxPerform);
event MinPerformSet(uint256 oldMinPerform, uint256 newMinPerform);
event MinWaitPeriodSet(uint256 s_minWaitPeriodSeconds, uint256 minWaitPeriodSeconds);
event TopUpBlocked(address indexed topUpAddress);
event TopUpFailed(address indexed recipient);
Expand Down Expand Up @@ -77,6 +78,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter

uint256 private s_minWaitPeriodSeconds;
uint16 private s_maxPerform;
uint16 private s_minPerform;
uint16 private s_maxCheck;
uint8 private s_upkeepInterval;

Expand Down Expand Up @@ -105,6 +107,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
IERC20 linkToken,
uint256 minWaitPeriodSeconds,
uint16 maxPerform,
uint16 minPerform,
uint16 maxCheck,
uint8 upkeepInterval
) {
Expand All @@ -114,6 +117,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
i_linkToken = linkToken;
setMinWaitPeriodSeconds(minWaitPeriodSeconds);
setMaxPerform(maxPerform);
setMinPerform(minPerform);
setMaxCheck(maxCheck);
setUpkeepInterval(upkeepInterval);
}
Expand Down Expand Up @@ -333,7 +337,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
bytes calldata
) external view override whenNotPaused returns (bool upkeepNeeded, bytes memory performData) {
address[] memory needsFunding = sampleUnderfundedAddresses();
if (needsFunding.length == 0) {
if (needsFunding.length <= s_minPerform) {
poke1994 marked this conversation as resolved.
Show resolved Hide resolved
return (false, "");
}
uint96 total_batch_balance;
Expand Down Expand Up @@ -389,6 +393,12 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
s_maxPerform = maxPerform;
}

/// @notice Update s_minPerform
function setMinPerform(uint16 minPerform) external onlyRole(ADMIN_ROLE) {
s_minPerform = minPerform;
emit MinPerformSet(s_minPerform, minPerform);
poke1994 marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice Update s_maxCheck
function setMaxCheck(uint16 maxCheck) public onlyRole(ADMIN_ROLE) {
emit MaxCheckSet(s_maxCheck, maxCheck);
Expand All @@ -412,6 +422,10 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
function getMaxPerform() external view returns (uint16) {
return s_maxPerform;
}
/// @notice Gets minPerform
function getMinPerform() external view returns (uint16) {
return s_minPerform;
}

/// @notice Gets maxCheck
function getMaxCheck() external view returns (uint16) {
Expand Down
Loading