Skip to content

Commit

Permalink
feat: add claim unbidded names (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
TuDo1403 authored Nov 23, 2023
2 parents eb0cf65 + cc9d738 commit 3ff1d46
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { console2 as console } from "forge-std/console2.sol";
import { ContractKey } from "foundry-deployment-kit/configs/ContractConfig.sol";
import { RNSDeploy } from "script/RNSDeploy.s.sol";
import { RNSUnified } from "@rns-contracts/RNSUnified.sol";
import { INSAuction, RNSAuction } from "@rns-contracts/RNSAuction.sol";

contract Migration__20231123_UpgradeAuctionClaimeUnbiddedNames is RNSDeploy {
function run() public trySetUp {
_upgradeProxy(ContractKey.RNSAuction, EMPTY_ARGS);
_validataBulkClaimUnbiddedNames({ size: 50 });
}

function _validataBulkClaimUnbiddedNames(uint256 size) internal logFn("_validataBulkClaimUnbiddedNames") {
RNSAuction auction = RNSAuction(_config.getAddressFromCurrentNetwork(ContractKey.RNSAuction));
RNSUnified rns = RNSUnified(_config.getAddressFromCurrentNetwork(ContractKey.RNSUnified));

uint256 auctionBalance = size;
console.log("auctionBalance", auctionBalance);
INSAuction.DomainAuction[] memory domainAuctions = new INSAuction.DomainAuction[](auctionBalance);
uint256[] memory reservedIds = new uint256[](auctionBalance);
for (uint256 i; i < auctionBalance; ++i) {
reservedIds[i] = rns.tokenOfOwnerByIndex(address(auction), i);
(domainAuctions[i],) = auction.getAuction(reservedIds[i]);
console.log(reservedIds[i], domainAuctions[i].bid.bidder);
}

address to = makeAddr("to");
address[] memory tos = new address[](reservedIds.length);
for (uint256 i; i < tos.length; ++i) {
tos[i] = to;
}

address operator = auction.getRoleMember(auction.OPERATOR_ROLE(), 0);
uint256 snapshotId = vm.snapshot();
// allowFailure
vm.prank(operator);
bool[] memory claimeds = auction.bulkClaimUnbiddedNames(tos, reservedIds, true);
for (uint256 i; i < claimeds.length; ++i) {
// flag claimed is true if bidder is null
assertTrue(claimeds[i] == (domainAuctions[i].bid.bidder == address(0x0)));
if (claimeds[i]) assertEq(rns.ownerOf(reservedIds[i]), to);
}

vm.revertTo(snapshotId);
uint256 firstFailId;
for (uint256 i; i < domainAuctions.length; ++i) {
if (domainAuctions[i].bid.bidder != address(0x0)) {
firstFailId = reservedIds[i];
break;
}
}
// !allowFailure
vm.prank(operator);
vm.expectRevert(abi.encodeWithSelector(INSAuction.AlreadyBidding.selector, firstFailId));
claimeds = auction.bulkClaimUnbiddedNames(tos, reservedIds, false);
}
}
38 changes: 37 additions & 1 deletion src/RNSAuction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ contract RNSAuction is Initializable, AccessControlEnumerable, INSAuction {
sAuction = _domainAuction[id];
mAuctionId = sAuction.auctionId;
if (!(mAuctionId == 0 || mAuctionId == auctionId || sAuction.bid.timestamp == 0)) {
revert AlreadyBidding();
revert AlreadyBidding(id);
}

sAuction.auctionId = auctionId;
Expand Down Expand Up @@ -205,6 +205,42 @@ contract RNSAuction is Initializable, AccessControlEnumerable, INSAuction {
if (prvPrice != 0) RONTransferHelper.safeTransfer(prvBidder, prvPrice);
}

/**
* @inheritdoc INSAuction
*/
function bulkClaimUnbiddedNames(address[] calldata tos, uint256[] calldata ids, bool allowFailure)
external
onlyRole(OPERATOR_ROLE)
returns (bool[] memory claimeds)
{
if (tos.length != ids.length) revert InvalidArrayLength();

uint64 expiry = uint64(block.timestamp.addWithUpperbound(DOMAIN_EXPIRY_DURATION, MAX_EXPIRY));
claimeds = new bool[](ids.length);
INSUnified rnsUnified = _rnsUnified;
DomainAuction memory auction;
uint256 id;

for (uint256 i; i < ids.length;) {
id = ids[i];
auction = _domainAuction[id];

if (auction.bid.bidder == address(0x0)) {
// remove id from auction
delete _domainAuction[id];
rnsUnified.setExpiry(id, expiry);
rnsUnified.transferFrom(address(this), tos[i], id);
claimeds[i] = true;
} else if (!allowFailure) {
revert AlreadyBidding(id);
}

unchecked {
++i;
}
}
}

/**
* @inheritdoc INSAuction
*/
Expand Down
17 changes: 16 additions & 1 deletion src/interfaces/INSAuction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface INSAuction {
error NotYetEnded();
error NoOneBidded();
error NullAssignment();
error AlreadyBidding();
error AlreadyBidding(uint256 id);
error RatioIsTooLarge();
error NameNotReserved();
error InvalidEventRange();
Expand Down Expand Up @@ -91,6 +91,21 @@ interface INSAuction {
*/
function reserved(uint256 id) external view returns (bool);

/**
* @dev Claim unbidded names and transfer them to the specified addresses.
*
* Requirements:
* - The method caller must be contract operator.
*
* @param tos The array of addresses to transfer domain names to.
* @param ids The id corresponding for namehash of domain names.
* @param allowFailure Flag to indicate whether to allow failure if a domain is already being bid on.
* @return claimeds An array indicating whether each domain name was successfully claimed.
*/
function bulkClaimUnbiddedNames(address[] calldata tos, uint256[] calldata ids, bool allowFailure)
external
returns (bool[] memory claimeds);

/**
* @dev Creates a new auction to sale with a specific time period.
*
Expand Down

0 comments on commit 3ff1d46

Please sign in to comment.