Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: require noun age to fork #806

Draft
wants to merge 9 commits into
base: verbs-spend-or-burn-excess-eth-every-n-auctions
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,8 @@ contract NounsDAOStorageV3 {
INounsDAOForkEscrow forkEscrow;
/// @notice address of the DAO's fork deployer contract
IForkDAODeployer forkDAODeployer;
/// @notice the age of a noun, in noun ids, for a noun to be allowed to fork
uint16 nounAgeRequiredToFork;
/// @notice ERC20 tokens to include when sending funds to a deployed fork
address[] erc20TokensToIncludeInFork;
/// @notice The treasury contract of the last deployed fork
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,10 @@ contract NounsDAOLogicV3 is NounsDAOStorageV3, NounsDAOEventsV3 {
ds._setForkThresholdBPS(newForkThresholdBPS);
}

function _setNounAgeRequiredToFork(uint16 newNounAgeRequiredToFork) external {
ds._setNounAgeRequiredToFork(newNounAgeRequiredToFork);
}

/**
* @notice Admin function for setting the proposal id at which vote snapshots start using the voting start block
* instead of the proposal creation block.
Expand Down
11 changes: 11 additions & 0 deletions packages/nouns-contracts/contracts/governance/NounsDAOV3Admin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ library NounsDAOV3Admin {
/// @notice Emitted when the main timelock, timelockV1 and admin are set
event TimelocksAndAdminSet(address timelock, address timelockV1, address admin);

event NounAgeRequiredToForkSet(uint16 oldNounAgeRequiredToFork, uint16 newNounAgeRequiredToFork);

/// @notice The minimum setable proposal threshold
uint256 public constant MIN_PROPOSAL_THRESHOLD_BPS = 1; // 1 basis point or 0.01%

Expand Down Expand Up @@ -557,6 +559,15 @@ library NounsDAOV3Admin {
ds.forkThresholdBPS = newForkThresholdBPS;
}

function _setNounAgeRequiredToFork(NounsDAOStorageV3.StorageV3 storage ds, uint16 newNounAgeRequiredToFork)
external
onlyAdmin(ds)
{
emit NounAgeRequiredToForkSet(ds.nounAgeRequiredToFork, newNounAgeRequiredToFork);

ds.nounAgeRequiredToFork = newNounAgeRequiredToFork;
}

/**
* @notice Admin function for setting the timelocks and admin
* @param timelock the new timelock contract
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ pragma solidity ^0.8.19;
import { NounsDAOStorageV3, INounsDAOForkEscrow, INounsDAOExecutorV2 } from '../NounsDAOInterfaces.sol';
import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import { NounsTokenFork } from './newdao/token/NounsTokenFork.sol';
import { INounsAuctionHouseV2 } from '../../interfaces/INounsAuctionHouseV2.sol';

library NounsDAOV3Fork {
error ForkThresholdNotMet();
error ForkPeriodNotActive();
error ForkPeriodActive();
error AdminOnly();
error UseAlternativeWithdrawFunction();
error NounIdNotOldEnough();

/// @notice Emitted when someones adds nouns to the fork escrow
event EscrowedToFork(
Expand Down Expand Up @@ -81,6 +83,7 @@ library NounsDAOV3Fork {
INounsDAOForkEscrow forkEscrow = ds.forkEscrow;

for (uint256 i = 0; i < tokenIds.length; i++) {
checkNounIdIsAllowedToFork(ds, tokenIds[i]);
ds.nouns.safeTransferFrom(msg.sender, address(forkEscrow), tokenIds[i]);
}

Expand Down Expand Up @@ -151,6 +154,7 @@ library NounsDAOV3Fork {
sendProRataTreasury(ds, ds.forkDAOTreasury, tokenIds.length, adjustedTotalSupply(ds));

for (uint256 i = 0; i < tokenIds.length; i++) {
checkNounIdIsAllowedToFork(ds, tokenIds[i]);
ds.nouns.transferFrom(msg.sender, timelock, tokenIds[i]);
}

Expand Down Expand Up @@ -216,6 +220,11 @@ library NounsDAOV3Fork {
return ds.forkEscrow.numTokensInEscrow();
}

function checkNounIdIsAllowedToFork(NounsDAOStorageV3.StorageV3 storage ds, uint256 tokenId) internal view {
uint256 auctionedNounId = INounsAuctionHouseV2(ds.nouns.minter()).auction().nounId;
if (tokenId < auctionedNounId - ds.nounAgeRequiredToFork) revert NounIdNotOldEnough();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

gas: worth reading ds.nounAgeRequiredToFork and auctionedNounId once for all the tokens

}

/**
* @notice Returns the number of nouns in supply minus nouns owned by the DAO, i.e. held in the treasury or in an
* escrow after it has closed.
Expand Down
Loading