Skip to content

Commit

Permalink
Refactor to have separate AddressAliasRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized committed Jan 26, 2024
1 parent 0c22461 commit 29a0a9e
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 200 deletions.
149 changes: 149 additions & 0 deletions contracts/modules/AddressAliasRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import { IAddressAliasRegistry } from "@modules/interfaces/IAddressAliasRegistry.sol";
import { LibZip } from "solady/utils/LibZip.sol";

/**
* @title AddressAliasRegistry
* @dev A registry for registering addresses with aliases.
*/
contract AddressAliasRegistry is IAddressAliasRegistry {
// =============================================================
// STORAGE
// =============================================================

/**
* @dev The current number of aliases.
*/
uint32 public numAliases;

/**
* @dev Maps an alias to its original address.
*/
mapping(address => address) internal _aliasToAddress;

/**
* @dev Maps an address to its alias.
*/
mapping(address => address) internal _addressToAlias;

// =============================================================
// PUBLIC / EXTERNAL WRITE FUNCTIONS
// =============================================================

/**
* @inheritdoc IAddressAliasRegistry
*/
function resolveAndRegister(address[] memory a)
public
returns (address[] memory aliases, address[] memory addresses)
{
unchecked {
uint256 n = a.length;
aliases = new address[](n);
addresses = new address[](n);
for (uint256 i; i != n; ++i) {
(aliases[i], addresses[i]) = _resolveAndRegister(a[i]);
}
}
}

// Misc functions:
// ---------------

/**
* @dev For calldata compression.
*/
fallback() external payable {
LibZip.cdFallback();
}

/**
* @dev For calldata compression.
*/
receive() external payable {
LibZip.cdFallback();
}

// =============================================================
// PUBLIC / EXTERNAL VIEW FUNCTIONS
// =============================================================

/**
* @inheritdoc IAddressAliasRegistry
*/
function resolve(address[] memory a) public view returns (address[] memory aliases, address[] memory addresses) {
unchecked {
uint256 n = a.length;
aliases = new address[](n);
addresses = new address[](n);
for (uint256 i; i != n; ++i) {
(aliases[i], addresses[i]) = _resolve(a[i]);
}
}
}

// =============================================================
// INTERNAL / PRIVATE HELPERS
// =============================================================

/**
* @dev Returns the alias and address for `aliasOrAddress`.
* If the `aliasOrAddress` is less than `2**31 - 1`, it is treated as an alias.
* Otherwise, it is treated as an address, and it's alias will be registered on-the-fly.
* @param aliasOrAddress The alias or address.
* @return alias_ The alias.
* @return address_ The address.
*/
function _resolveAndRegister(address aliasOrAddress) internal returns (address alias_, address address_) {
// If the `aliasOrAddress` is less than or equal to `2**32 - 1`, we will consider it an alias.
if (uint160(aliasOrAddress) <= type(uint32).max) {
alias_ = aliasOrAddress;
address_ = _aliasToAddress[alias_];
if (address_ == address(0)) revert AliasNotFound();
} else {
address_ = aliasOrAddress;
alias_ = _registerAlias(address_);
}
}

/**
* @dev Returns the alias and address for `aliasOrAddress`.
* If the `aliasOrAddress` is less than `2**31 - 1`, it is treated as an alias.
* Otherwise, it is treated as an address.
* @param aliasOrAddress The alias or address.
* @return alias_ The alias.
* @return address_ The address.
*/
function _resolve(address aliasOrAddress) internal view returns (address alias_, address address_) {
// If the `aliasOrAddress` is less than or equal to `2**32 - 1`, we will consider it an alias.
if (uint160(aliasOrAddress) <= type(uint32).max) {
alias_ = aliasOrAddress;
address_ = _aliasToAddress[alias_];
} else {
address_ = aliasOrAddress;
alias_ = _addressToAlias[address_];
}
}

/**
* @dev Registers the alias for the address on-the-fly.
* @param address_ The address.
* @return alias_ The alias registered for the address.
*/
function _registerAlias(address address_) internal returns (address alias_) {
if (uint160(address_) <= type(uint32).max) revert AddressTooSmall();

alias_ = _addressToAlias[address_];
// If the address has no alias, register it's alias.
if (alias_ == address(0)) {
// Increment the `numAliases` and cast it into an alias.
alias_ = address(uint160(++numAliases));
// Add to the mappings.
_aliasToAddress[alias_] = address_;
_addressToAlias[address_] = alias_;
emit RegisteredAlias(address_, alias_);
}
}
}
114 changes: 11 additions & 103 deletions contracts/modules/PlatformAirdropper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.16;

import { ISuperMinterV2 } from "@modules/interfaces/ISuperMinterV2.sol";
import { IPlatformAirdropper } from "@modules/interfaces/IPlatformAirdropper.sol";
import { IAddressAliasRegistry } from "@modules/interfaces/IAddressAliasRegistry.sol";
import { LibZip } from "solady/utils/LibZip.sol";

/**
Expand All @@ -11,23 +12,21 @@ import { LibZip } from "solady/utils/LibZip.sol";
*/
contract PlatformAirdropper is IPlatformAirdropper {
// =============================================================
// STORAGE
// IMMUTABLES
// =============================================================

/**
* @dev The current number of aliases.
* @dev The address alias registry.
*/
uint32 public numAliases;
address public immutable addressAliasRegistry;

/**
* @dev Maps an alias to its original address.
*/
mapping(address => address) internal _aliasToAddress;
// =============================================================
// CONSTRUCTOR
// =============================================================

/**
* @dev Maps an address to its alias.
*/
mapping(address => address) internal _addressToAlias;
constructor(address addressAliasRegistry_) payable {
addressAliasRegistry = addressAliasRegistry_;
}

// =============================================================
// PUBLIC / EXTERNAL WRITE FUNCTIONS
Expand All @@ -41,11 +40,7 @@ contract PlatformAirdropper is IPlatformAirdropper {
returns (uint256 fromTokenId, address[] memory aliases)
{
unchecked {
uint256 n = p.to.length;
aliases = new address[](n);
for (uint256 i; i != n; ++i) {
(aliases[i], p.to[i]) = _getAliasAndAddress(p.to[i]);
}
(aliases, p.to) = IAddressAliasRegistry(addressAliasRegistry).resolveAndRegister(p.to);
fromTokenId = ISuperMinterV2(superMinter).platformAirdrop(p);
}
}
Expand All @@ -67,19 +62,6 @@ contract PlatformAirdropper is IPlatformAirdropper {
}
}

/**
* @inheritdoc IPlatformAirdropper
*/
function registerAliases(address[] memory a) public returns (address[] memory) {
unchecked {
uint256 n = a.length;
for (uint256 i; i != n; ++i) {
a[i] = _registerAlias(a[i]);
}
return a;
}
}

// Misc functions:
// ---------------

Expand All @@ -96,78 +78,4 @@ contract PlatformAirdropper is IPlatformAirdropper {
receive() external payable {
LibZip.cdFallback();
}

// =============================================================
// PUBLIC / EXTERNAL VIEW FUNCTIONS
// =============================================================

/**
* @inheritdoc IPlatformAirdropper
*/
function addressesToAliases(address[] memory a) public view returns (address[] memory) {
unchecked {
uint256 n = a.length;
for (uint256 i; i != n; ++i) {
a[i] = _addressToAlias[a[i]];
}
return a;
}
}

/**
* @inheritdoc IPlatformAirdropper
*/
function aliasesToAddresses(address[] memory a) public view returns (address[] memory) {
unchecked {
uint256 n = a.length;
for (uint256 i; i != n; ++i) {
a[i] = _aliasToAddress[a[i]];
}
return a;
}
}

// =============================================================
// INTERNAL / PRIVATE HELPERS
// =============================================================

/**
* @dev Returns the alias and address for `aliasOrAddress`.
* If the `aliasOrAddress` is less than `2**31 - 1`, it is treated as an alias.
* Otherwise, it is treated as an address, and it's alias will be registered on-the-fly.
* @param aliasOrAddress The alias or address.
* @return alias_ The alias.
* @return address_ The address.
*/
function _getAliasAndAddress(address aliasOrAddress) internal returns (address alias_, address address_) {
// If the `aliasOrAddress` is less than or equal to `2**32 - 1`, we will consider it an alias.
if (uint160(aliasOrAddress) <= type(uint32).max) {
alias_ = aliasOrAddress;
address_ = _aliasToAddress[alias_];
if (address_ == address(0)) revert AliasNotFound();
} else {
address_ = aliasOrAddress;
alias_ = _registerAlias(address_);
}
}

/**
* @dev Registers the alias for the address on-the-fly.
* @param address_ The address.
* @return alias_ The alias registered for the address.
*/
function _registerAlias(address address_) internal returns (address alias_) {
if (uint160(address_) <= type(uint32).max) revert AddressTooSmall();

alias_ = _addressToAlias[address_];
// If the address has no alias, register it's alias.
if (alias_ == address(0)) {
// Increment the `numAliases` and cast it into an alias.
alias_ = address(uint160(++numAliases));
// Add to the mappings.
_aliasToAddress[alias_] = address_;
_addressToAlias[address_] = alias_;
emit RegisteredAlias(address_, alias_);
}
}
}
66 changes: 66 additions & 0 deletions contracts/modules/interfaces/IAddressAliasRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

/**
* @title AddressAliasRegistry
* @dev A registry for registering addresses with aliases.
*/
interface IAddressAliasRegistry {
// =============================================================
// EVENTS
// =============================================================

/**
* @dev Emitted when an address is registered with an alias.
*/
event RegisteredAlias(address address_, address alias_);

// =============================================================
// ERRORS
// =============================================================

/**
* @dev The alias has not been registered.
*/
error AliasNotFound();

/**
* @dev The address to be registered must be larger than `2**32 - 1`.
*/
error AddressTooSmall();

// =============================================================
// PUBLIC / EXTERNAL WRITE FUNCTIONS
// =============================================================

/**
* @dev Resolve the addresses or aliases.
* If an address does not have an aliases, an alias will be registered for it.
* @param a An array of addresses, which can be aliases.
* @return aliases The aliases for the addresses.
* @return addresses The resolved addresses.
*/
function resolveAndRegister(address[] memory a)
external
returns (address[] memory aliases, address[] memory addresses);

// =============================================================
// PUBLIC / EXTERNAL VIEW FUNCTIONS
// =============================================================

/**
* @dev Returns the current number of aliases.
* @return The latest value.
*/
function numAliases() external view returns (uint32);

/**
* @dev Resolve the addresses or aliases.
* If an address does not have an aliases, it's corresponding returned alias will be zero.
* If an alias does not have an address, it's corresponding returned address will be zero.
* @param a An array of addresses, which can be aliases.
* @return aliases The aliases for the addresses.
* @return addresses The resolved addresses.
*/
function resolve(address[] memory a) external view returns (address[] memory aliases, address[] memory addresses);
}
Loading

0 comments on commit 29a0a9e

Please sign in to comment.