Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c307e78
Add upgradeable RegistrarController, make it EIP-7201 compliant'
stevieraykatz Oct 1, 2024
a578e14
Add interface to new ENS contract, add support for setting primary to…
stevieraykatz Oct 1, 2024
5dfed4a
Add initializer for reverse resolver contract
stevieraykatz Oct 1, 2024
43a53a7
Add shim for migration period
stevieraykatz Oct 1, 2024
fc735bf
Add tests for Shim
stevieraykatz Oct 2, 2024
7a0d049
lint
stevieraykatz Oct 2, 2024
8151302
Testing start
stevieraykatz Oct 10, 2024
1fc8be7
chore: forge fmt
abdulla-cb Oct 31, 2024
15ebd14
chore: typos
abdulla-cb Oct 31, 2024
d256095
forge install: openzeppelin-contracts-upgradeable
abdulla-cb Oct 31, 2024
5214bc2
feat: use v5.0.0 of openzeppelin-contracts-upgradeable
abdulla-cb Oct 31, 2024
34a313a
feat: update tests to use OpenZeppelin Upgradeable
abdulla-cb Nov 1, 2024
78e3f28
chore: fix typo
abdulla-cb Nov 1, 2024
afb5014
Remove Upgradeable Registrar Controller from this PR's scope
stevieraykatz Apr 23, 2025
0370a6b
Refactor to use updated ENS L2ReverseRegistrar
stevieraykatz Apr 23, 2025
41eadb1
Refactor tests to match new L2ReverseRegistrar contract interface
stevieraykatz Apr 23, 2025
c997555
Remove foundry and module changes from this branch
stevieraykatz Apr 23, 2025
0125efe
Remove upgradeable OZ from the scope of this PR
stevieraykatz Apr 23, 2025
f1e1696
Remove oos test file changes from this PR
stevieraykatz Apr 23, 2025
a468d30
Pull in CI fix
stevieraykatz Apr 23, 2025
ceae9ab
natspec and lint
stevieraykatz Apr 23, 2025
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
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- name: Run Forge build
run: |
forge --version
forge build --sizes
id: build

- name: Run Forge tests
Expand Down
51 changes: 51 additions & 0 deletions src/L2/ReverseRegistrarShim.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {IReverseRegistrar} from "./interface/IReverseRegistrar.sol";
import {IL2ReverseRegistrar} from "./interface/IL2ReverseRegistrar.sol";

/// @title ReverseRegistrarShim
///
/// @notice A temporary shim contract used to ensure user data is not lost while migrating into ENSIP-19 compliance.
/// The contract writes reverse records to both the legacy ReverseRegistrar and the new ENS-deployed
/// L2ReverseRegistrar.
///
/// @author Coinbase (https://github.com/base/basenames)
contract ReverseRegistrarShim {
/// @notice The address of the legacy Basenames ReverseRegistrar contract.
address public immutable reverseRegistrar;
/// @notice The address of the ENS-deployed L2ReverseRegistrar contract.
address public immutable l2ReverseRegistrar;
/// @notice The address of the Basenames public resolver.
address public immutable l2Resolver;

/// @notice constructor.
constructor(address reverseRegistrar_, address l2ReverseRegistrar_, address l2Resolver_) {
reverseRegistrar = reverseRegistrar_;
l2ReverseRegistrar = l2ReverseRegistrar_;
l2Resolver = l2Resolver_;
}

/// @notice Sets the reverse record `name` for `addr`.
///
/// @dev First calls the ENS L2ReverseRegistrar and sets the name-record for the provided address. Then calls the legacy
/// Basenames reverse registrar and registers the name there as well.
///
/// @param addr The name records will be set for this address.
/// @param name The name that will be stored for `addr`.
/// @param signatureExpiry The timestamp expiration of the signature.
/// @param cointypes The array of networks-as-cointypes used in replayable reverse sets.
/// @param signature The signature bytes.
function setNameForAddrWithSignature(
address addr,
string calldata name,
uint256 signatureExpiry,
uint256[] memory cointypes,
bytes memory signature
) external returns (bytes32) {
IL2ReverseRegistrar(l2ReverseRegistrar).setNameForAddrWithSignature(
addr, signatureExpiry, name, cointypes, signature
);
return IReverseRegistrar(reverseRegistrar).setNameForAddr(addr, msg.sender, l2Resolver, name);
}
}
48 changes: 48 additions & 0 deletions src/L2/interface/IL2ReverseRegistrar.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Interface for the L2 Reverse Registrar.
interface IL2ReverseRegistrar {
Comment on lines +4 to +5
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// @notice Sets the `nameForAddr()` record for the calling account.
///
/// @param name The name to set.
function setName(string memory name) external;

/// @notice Sets the `nameForAddr()` record for the addr provided account.
///
/// @param addr The address to set the name for.
/// @param name The name to set.
function setNameForAddr(address addr, string memory name) external;

/// @notice Sets the `nameForAddr()` record for the addr provided account using a signature.
///
/// @param addr The address to set the name for.
/// @param name The name to set.
/// @param coinTypes The coin types to set. Must be inclusive of the coin type for the contract.
/// @param signatureExpiry Date when the signature expires.
/// @param signature The signature from the addr.
function setNameForAddrWithSignature(
address addr,
uint256 signatureExpiry,
string memory name,
uint256[] memory coinTypes,
bytes memory signature
) external;

/// @notice Sets the `nameForAddr()` record for the contract provided that is owned with `Ownable`.
///
/// @param contractAddr The address of the contract to set the name for (implementing Ownable).
/// @param owner The owner of the contract (via Ownable).
/// @param signatureExpiry The expiry of the signature.
/// @param name The name to set.
/// @param coinTypes The coin types to set. Must be inclusive of the coin type for the contract.
/// @param signature The signature of an address that will return true on isValidSignature for the owner.
function setNameForOwnableWithSignature(
address contractAddr,
address owner,
uint256 signatureExpiry,
string memory name,
uint256[] memory coinTypes,
bytes memory signature
) external;
}
35 changes: 35 additions & 0 deletions test/ReverseRegistrarShim/ReverseRegistrarShimBase.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {Test} from "forge-std/Test.sol";
import {ReverseRegistrarShim} from "src/L2/ReverseRegistrarShim.sol";
import {MockReverseRegistrar} from "test/mocks/MockReverseRegistrar.sol";
import {MockL2ReverseRegistrar} from "test/mocks/MockL2ReverseRegistrar.sol";
import {MockPublicResolver} from "test/mocks/MockPublicResolver.sol";

contract ReverseRegistrarShimBase is Test {
MockL2ReverseRegistrar l2RevReg;
MockReverseRegistrar revReg;
MockPublicResolver resolver;

ReverseRegistrarShim public shim;

address userA;
address userB;
string nameA = "userAName";
string nameB = "userBName";

uint256 signatureExpiry = 0;
bytes signature;
uint256[] cointypes;

function setUp() external {
l2RevReg = new MockL2ReverseRegistrar();
revReg = new MockReverseRegistrar();
resolver = new MockPublicResolver();
shim = new ReverseRegistrarShim(address(revReg), address(l2RevReg), address(resolver));

userA = makeAddr("userA");
userB = makeAddr("userB");
}
}
29 changes: 29 additions & 0 deletions test/ReverseRegistrarShim/SetNameForAddrWithSignature.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {ReverseRegistrarShimBase} from "./ReverseRegistrarShimBase.t.sol";
import {MockL2ReverseRegistrar} from "test/mocks/MockL2ReverseRegistrar.sol";
import {MockReverseRegistrar} from "test/mocks/MockReverseRegistrar.sol";

contract SetNameForAddrWithSignature is ReverseRegistrarShimBase {
function test_setsNameForAddr_onReverseRegistrar() public {
vm.expectCall(
address(revReg),
abi.encodeCall(MockReverseRegistrar.setNameForAddr, (userA, userA, address(resolver), nameA))
);
vm.prank(userA);
shim.setNameForAddrWithSignature(userA, nameA, signatureExpiry, cointypes, signature);
}

function test_setsNameForAddr_onL2ReverseRegistrar() public {
vm.expectCall(
address(l2RevReg),
abi.encodeCall(
MockL2ReverseRegistrar.setNameForAddrWithSignature,
(userA, signatureExpiry, nameA, cointypes, signature)
)
);
vm.prank(userA);
shim.setNameForAddrWithSignature(userA, nameA, signatureExpiry, cointypes, signature);
}
}
19 changes: 19 additions & 0 deletions test/mocks/MockL2ReverseRegistrar.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

contract MockL2ReverseRegistrar {
/// @notice Sets the `nameForAddr()` record for the addr provided account using a signature.
///
/// @param addr The address to set the name for.
/// @param name The name to set.
/// @param coinTypes The coin types to set. Must be inclusive of the coin type for the contract.
/// @param signatureExpiry Date when the signature expires.
/// @param signature The signature from the addr.
function setNameForAddrWithSignature(
address addr,
uint256 signatureExpiry,
string memory name,
uint256[] memory coinTypes,
bytes memory signature
) external {}
}
12 changes: 12 additions & 0 deletions test/mocks/MockReverseResolver.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

contract MockReverseResolver {
function setNameForAddrWithSignature(address, string calldata, uint256, bytes memory)
external
view
returns (bytes32)
{
return bytes32(block.timestamp);
}
}
Loading