// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {IPoolAddressesProviderRegistry} from '../../interfaces/IPoolAddressesProviderRegistry.sol'; /** * @title PoolAddressesProviderRegistry * @author Aave * @notice Main registry of PoolAddressesProvider of Aave markets. * @dev Used for indexing purposes of Aave protocol's markets. The id assigned to a PoolAddressesProvider refers to the * market it is connected with, for example with `1` for the Aave main market and `2` for the next created. */ contract PoolAddressesProviderRegistry is Ownable, IPoolAddressesProviderRegistry { // Map of address provider ids (addressesProvider => id) mapping(address => uint256) private _addressesProviderToId; // Map of id to address provider (id => addressesProvider) mapping(uint256 => address) private _idToAddressesProvider; // List of addresses providers address[] private _addressesProvidersList; // Map of address provider list indexes (addressesProvider => indexInList) mapping(address => uint256) private _addressesProvidersIndexes; /** * @dev Constructor. * @param owner The owner address of this contract. */ constructor(address owner) { transferOwnership(owner); } /// @inheritdoc IPoolAddressesProviderRegistry function getAddressesProvidersList() external view override returns (address[] memory) { return _addressesProvidersList; } /// @inheritdoc IPoolAddressesProviderRegistry function registerAddressesProvider(address provider, uint256 id) external override onlyOwner { require(id != 0, Errors.INVALID_ADDRESSES_PROVIDER_ID); require(_idToAddressesProvider[id] == address(0), Errors.INVALID_ADDRESSES_PROVIDER_ID); require(_addressesProviderToId[provider] == 0, Errors.ADDRESSES_PROVIDER_ALREADY_ADDED); _addressesProviderToId[provider] = id; _idToAddressesProvider[id] = provider; _addToAddressesProvidersList(provider); emit AddressesProviderRegistered(provider, id); } /// @inheritdoc IPoolAddressesProviderRegistry function unregisterAddressesProvider(address provider) external override onlyOwner { require(_addressesProviderToId[provider] != 0, Errors.ADDRESSES_PROVIDER_NOT_REGISTERED); uint256 oldId = _addressesProviderToId[provider]; _idToAddressesProvider[oldId] = address(0); _addressesProviderToId[provider] = 0; _removeFromAddressesProvidersList(provider); emit AddressesProviderUnregistered(provider, oldId); } /// @inheritdoc IPoolAddressesProviderRegistry function getAddressesProviderIdByAddress( address addressesProvider ) external view override returns (uint256) { return _addressesProviderToId[addressesProvider]; } /// @inheritdoc IPoolAddressesProviderRegistry function getAddressesProviderAddressById(uint256 id) external view override returns (address) { return _idToAddressesProvider[id]; } /** * @notice Adds the addresses provider address to the list. * @param provider The address of the PoolAddressesProvider */ function _addToAddressesProvidersList(address provider) internal { _addressesProvidersIndexes[provider] = _addressesProvidersList.length; _addressesProvidersList.push(provider); } /** * @notice Removes the addresses provider address from the list. * @param provider The address of the PoolAddressesProvider */ function _removeFromAddressesProvidersList(address provider) internal { uint256 index = _addressesProvidersIndexes[provider]; _addressesProvidersIndexes[provider] = 0; // Swap the index of the last addresses provider in the list with the index of the provider to remove uint256 lastIndex = _addressesProvidersList.length - 1; if (index < lastIndex) { address lastProvider = _addressesProvidersList[lastIndex]; _addressesProvidersList[index] = lastProvider; _addressesProvidersIndexes[lastProvider] = index; } _addressesProvidersList.pop(); } }