Skip to content

Commit

Permalink
add dstChainSelector to setWatchList
Browse files Browse the repository at this point in the history
  • Loading branch information
Borja Aranda committed Dec 20, 2023
1 parent 9cfa798 commit fde3af6
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
error InvalidUpkeepInterval(uint8 upkeepInterval);
error InvalidLinkTokenAddress(address lt);
error InvalidWatchList();
error InvalidChainSelector();
error DuplicateAddress(address duplicate);

struct MonitoredAddress {
Expand All @@ -73,11 +74,19 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
uint16 private s_maxPerform;
uint16 private s_maxCheck;
uint8 private s_upkeepInterval;

/// @notice s_watchList contains all the addresses watched by this monitor
/// It mainly provides the length() function
address[] private s_watchList;

/// @notice s_targets contains all the addresses watched by this monitor
/// Each key points to a MonitoredAddress with all the needed metadata
mapping(address targetAddress => MonitoredAddress targetProperties) internal s_targets;

/// @notice s_onRampAddresses represents a list of CCIP onRamp addresses watched on this contract
/// There has to be only one onRamp per dstChainSelector.
/// dstChainSelector is needed as we have to track the live onRamp, and delete the onRamp
/// whenever a new one is deployed with the same dstChainSelector.
mapping(uint64 dstChainSelector => address onRamp) internal s_onRampAddresses;

/// @param admin is the administrator address of this contract
Expand Down Expand Up @@ -112,25 +121,33 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
function setWatchList(
address[] calldata addresses,
uint96[] calldata minBalances,
uint96[] calldata topUpAmounts
uint96[] calldata topUpAmounts,
uint64[] calldata dstChainSelectors
) external onlyAdminOrExecutor {
if (addresses.length != minBalances.length || addresses.length != topUpAmounts.length) {
if (
addresses.length != minBalances.length ||
addresses.length != topUpAmounts.length ||
addresses.length != dstChainSelectors.length
) {
revert InvalidWatchList();
}
for (uint256 idx = 0; idx < s_watchList.length; idx++) {
delete s_targets[s_watchList[idx]];
}
for (uint256 idx = 0; idx < addresses.length; idx++) {
address targetAddress = addresses[idx];
if (s_targets[targetAddress].isActive) revert DuplicateAddress(addresses[idx]);
if (addresses[idx] == address(0)) revert InvalidWatchList();
if (s_targets[targetAddress].isActive) revert DuplicateAddress(targetAddress);
if (targetAddress == address(0)) revert InvalidWatchList();
if (topUpAmounts[idx] == 0) revert InvalidWatchList();
s_targets[targetAddress] = MonitoredAddress({
isActive: true,
minBalance: minBalances[idx],
topUpAmount: topUpAmounts[idx],
lastTopUpTimestamp: 0
});
if (dstChainSelectors[idx] > 0) {
s_onRampAddresses[dstChainSelectors[idx]] = targetAddress;
}
}
s_watchList = addresses;
emit WatchlistUpdated();
Expand Down Expand Up @@ -169,7 +186,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
/// @notice Delete an address from the watchlist and sets the target to inactive
/// @param targetAddress the address to be deleted
function removeFromWatchList(address targetAddress) public onlyAdminOrExecutor returns (bool) {
s_targets[targetAddress].isActive = false;
delete s_targets[targetAddress];
for (uint256 i; i < s_watchList.length; i++) {
if (s_watchList[i] == targetAddress) {
s_watchList[i] = s_watchList[s_watchList.length - 1];
Expand Down Expand Up @@ -373,6 +390,12 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter
return s_watchList;
}

/// @notice Gets the onRamp address with the specified dstChainSelector
function getOnRampAddressAtChainSelector(uint64 dstChainSelector) external view returns (address) {
if (dstChainSelector > 0) revert InvalidChainSelector();
return s_onRampAddresses[dstChainSelector];
}

/// @notice Gets configuration information for an address on the watchlist
function getAccountInfo(
address targetAddress
Expand Down
40 changes: 35 additions & 5 deletions contracts/test/v0.8/automation/LinkAvailableBalanceMonitor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ let directTarget2: MockContract
let watchListAddresses: string[]
let watchListMinBalances: BigNumber[]
let watchListTopUpAmounts: BigNumber[]
let watchListDstChainSelectors: number[]

async function assertContractLinkBalances(
balance1: BigNumber,
Expand Down Expand Up @@ -120,6 +121,7 @@ const setup = async () => {
]
watchListMinBalances = [oneLINK, oneLINK, oneLINK, twoLINK, twoLINK]
watchListTopUpAmounts = [twoLINK, twoLINK, twoLINK, twoLINK, twoLINK]
watchListDstChainSelectors = [1, 2, 3, 4, 5]

await proxy1.mock.aggregator.returns(aggregator1.address)
await proxy2.mock.aggregator.returns(aggregator2.address)
Expand Down Expand Up @@ -169,6 +171,7 @@ const setup = async () => {
watchListAddresses,
watchListMinBalances,
watchListTopUpAmounts,
watchListDstChainSelectors,
)
await setTx.wait()
}
Expand Down Expand Up @@ -323,7 +326,7 @@ describe('LinkAvailableBalanceMonitor', () => {

beforeEach(async () => {
// reset watchlist to empty before running these tests
await labm.connect(owner).setWatchList([], [], [])
await labm.connect(owner).setWatchList([], [], [], [])
const watchList = await labm.getWatchList()
assert.deepEqual(watchList, [])
})
Expand All @@ -332,7 +335,7 @@ describe('LinkAvailableBalanceMonitor', () => {
// add first watchlist
let tx = await labm
.connect(owner)
.setWatchList([watchAddress1], [oneLINK], [oneLINK])
.setWatchList([watchAddress1], [oneLINK], [oneLINK], [0])
let watchList = await labm.getWatchList()
assert.deepEqual(watchList[0], watchAddress1)
// add more to watchlist
Expand All @@ -342,6 +345,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[watchAddress1, watchAddress2, watchAddress3],
[oneLINK, oneLINK, oneLINK],
[oneLINK, oneLINK, oneLINK],
[1, 2, 3],
)
await tx.wait()
watchList = await labm.getWatchList()
Expand All @@ -356,6 +360,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[watchAddress1, watchAddress2, watchAddress1],
[oneLINK, oneLINK],
[oneLINK, oneLINK],
[1, 2],
)
await expect(tx).to.be.revertedWith(errMsg)
})
Expand All @@ -368,14 +373,15 @@ describe('LinkAvailableBalanceMonitor', () => {
[watchAddress1, watchAddress2, watchAddress1],
[oneLINK, oneLINK, oneLINK],
[oneLINK, oneLINK, oneLINK],
[1, 2, 3],
)
await expect(tx).to.be.revertedWith(errMsg)
})

it('Should not allow strangers to set the watchlist', async () => {
const setTxStranger = labm
.connect(stranger)
.setWatchList([watchAddress1], [oneLINK], [oneLINK])
.setWatchList([watchAddress1], [oneLINK], [oneLINK], [0])
await expect(setTxStranger).to.be.reverted
})

Expand All @@ -386,6 +392,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[watchAddress1, ethers.constants.AddressZero],
[oneLINK, oneLINK],
[oneLINK, oneLINK],
[1, 2],
)
await expect(tx).to.be.revertedWith(INVALID_WATCHLIST_ERR)
})
Expand Down Expand Up @@ -535,6 +542,7 @@ describe('LinkAvailableBalanceMonitor', () => {
watchListAddresses,
watchListMinBalances,
watchListTopUpAmounts,
watchListDstChainSelectors,
)

const [should, payload] = await labm.checkUpkeep('0x')
Expand All @@ -560,6 +568,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[aggregator2.address, directTarget1.address, directTarget2.address],
[oneLINK, twoLINK, twoLINK],
[oneLINK, oneLINK, oneLINK],
[1, 2, 3],
)

// all of them are underfunded, return 3
Expand Down Expand Up @@ -608,6 +617,7 @@ describe('LinkAvailableBalanceMonitor', () => {
let minBalances: BigNumber[]
let topUpAmount: BigNumber[]
let aggregators: MockContract[]
let dstChainSelectors: number[]

beforeEach(async () => {
MAX_PERFORM = await labm.getMaxPerform()
Expand All @@ -616,6 +626,7 @@ describe('LinkAvailableBalanceMonitor', () => {
minBalances = []
topUpAmount = []
aggregators = []
dstChainSelectors = []
const numAggregators = MAX_CHECK + 50
for (let idx = 0; idx < numAggregators; idx++) {
const proxy = await deployMockContract(
Expand All @@ -632,8 +643,14 @@ describe('LinkAvailableBalanceMonitor', () => {
minBalances.push(oneLINK)
topUpAmount.push(oneLINK)
aggregators.push(aggregator)
dstChainSelectors.push(0)
}
await labm.setWatchList(proxyAddresses, minBalances, topUpAmount)
await labm.setWatchList(
proxyAddresses,
minBalances,
topUpAmount,
dstChainSelectors,
)
let watchlist = await labm.getWatchList()
expect(watchlist).to.deep.equalInAnyOrder(proxyAddresses)
assert.equal(watchlist.length, minBalances.length)
Expand Down Expand Up @@ -688,6 +705,7 @@ describe('LinkAvailableBalanceMonitor', () => {
watchListAddresses,
watchListMinBalances,
watchListTopUpAmounts,
watchListDstChainSelectors,
)
})

Expand Down Expand Up @@ -730,6 +748,7 @@ describe('LinkAvailableBalanceMonitor', () => {
const proxyAddresses = []
const minBalances = []
const topUpAmount = []
const dstChainSelectors = []
for (let idx = 0; idx < MAX_PERFORM; idx++) {
const proxy = await deployMockContract(
owner,
Expand All @@ -744,8 +763,14 @@ describe('LinkAvailableBalanceMonitor', () => {
proxyAddresses.push(proxy.address)
minBalances.push(oneLINK)
topUpAmount.push(oneLINK)
dstChainSelectors.push(0)
}
await labm.setWatchList(proxyAddresses, minBalances, topUpAmount)
await labm.setWatchList(
proxyAddresses,
minBalances,
topUpAmount,
dstChainSelectors,
)
let watchlist = await labm.getWatchList()
expect(watchlist).to.deep.equalInAnyOrder(proxyAddresses)
assert.equal(watchlist.length, minBalances.length)
Expand Down Expand Up @@ -858,6 +883,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[proxy1.address, directTarget1.address],
[oneLINK, oneLINK],
[oneLINK, oneLINK],
[1, 2],
)
const tx = await labm
.connect(keeperRegistry)
Expand Down Expand Up @@ -895,6 +921,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[proxy1.address, proxy4.address],
[oneLINK, oneLINK],
[oneLINK, oneLINK],
[1, 2],
)
const tx = await labm
.connect(keeperRegistry)
Expand All @@ -913,6 +940,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[proxy1.address, proxy4.address],
[oneLINK, oneLINK],
[oneLINK, oneLINK],
[1, 2],
)
const tx = await labm
.connect(keeperRegistry)
Expand All @@ -932,6 +960,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[proxy1.address, proxy4.address],
[oneLINK, oneLINK],
[oneLINK, oneLINK],
[1, 2],
)
const tx = await labm
.connect(keeperRegistry)
Expand All @@ -950,6 +979,7 @@ describe('LinkAvailableBalanceMonitor', () => {
[proxy1.address, directTarget1.address],
[oneLINK, oneLINK],
[oneLINK, oneLINK],
[1, 2],
)
const tx = await labm
.connect(keeperRegistry)
Expand Down

0 comments on commit fde3af6

Please sign in to comment.