Skip to content

Commit

Permalink
chore: audit snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
Rohan Kulkarni committed Sep 26, 2022
1 parent a99f613 commit 01642c6
Show file tree
Hide file tree
Showing 46 changed files with 950 additions and 919 deletions.
29 changes: 16 additions & 13 deletions src/auction/Auction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import { IWETH } from "../lib/interfaces/IWETH.sol";

/// @title Auction
/// @author Rohan Kulkarni
/// @notice DAO Auction House
/// @notice A DAO's auction house
/// Modified from:
/// - NounsAuctionHouse.sol commit 2cbe6c7 - licensed under the BSD-3-Clause license.
/// - Zora V3 ReserveAuctionCoreEth module commit 795aeca - licensed under the GPL-3.0 license.
contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionStorageV1 {
/// ///
/// IMMUTABLES ///
Expand All @@ -31,7 +34,7 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS
/// CONSTRUCTOR ///
/// ///

/// @param _manager The address of the contract upgrade manager
/// @param _manager The contract upgrade manager address
/// @param _weth The address of WETH
constructor(address _manager, address _weth) payable initializer {
manager = IManager(_manager);
Expand All @@ -42,7 +45,7 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS
/// INITIALIZER ///
/// ///

/// @notice Initializes a DAO's auction house
/// @notice Initializes a DAO's auction contract
/// @param _token The ERC-721 token address
/// @param _founder The founder responsible for starting the first auction
/// @param _treasury The treasury address where ETH will be sent
Expand All @@ -61,13 +64,13 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS
// Initialize the reentrancy guard
__ReentrancyGuard_init();

// Grant initial ownership to a founder to unpause the auction house when ready
// Grant initial ownership to a founder
__Ownable_init(_founder);

// Pause the contract until the first auction is ready to begin
// Pause the contract until the first auction
__Pausable_init(true);

// Store the address of the ERC-721 token that will be bid on
// Store DAO's ERC-721 token
token = Token(_token);

// Store the auction house settings
Expand All @@ -94,7 +97,7 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS
// Ensure the auction is still active
if (block.timestamp >= _auction.endTime) revert AUCTION_OVER();

// Cache the address of the current highest bidder
// Cache the address of the highest bidder
address highestBidder = _auction.highestBidder;

// If this is the first bid:
Expand All @@ -104,10 +107,10 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS

// Else this is a subsequent bid:
} else {
// Cache the current highest bid
// Cache the highest bid
uint256 highestBid = _auction.highestBid;

// Used to store the minimum amount required to beat the current bid
// Used to store the minimum bid required
uint256 minBid;

// Cannot realistically overflow
Expand All @@ -123,10 +126,10 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS
_handleOutgoingTransfer(highestBidder, highestBid);
}

// Store the incoming bid as the new highest bid
// Store the new highest bid
auction.highestBid = msg.value;

// Store the caller as the new highest bidder
// Store the new highest bidder
auction.highestBidder = msg.sender;

// Used to store if the auction will be extended
Expand All @@ -151,7 +154,7 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS
}

/// ///
/// SETTLE & CREATE AUCTION ///
/// SETTLE & CREATE AUCTION ///
/// ///

/// @notice Settles the current auction and creates the next one
Expand Down Expand Up @@ -290,7 +293,7 @@ contract Auction is IAuction, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionS
return settings.timeBuffer;
}

/// @notice The minimum percentage of the highest bid that a subsequent bid must beat
/// @notice The minimum percentage an incoming bid must raise the highest bid
function minBidIncrement() external view returns (uint256) {
return settings.minBidIncrement;
}
Expand Down
2 changes: 1 addition & 1 deletion src/auction/IAuction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ interface IAuction is IUUPS, IOwnable, IPausable {
/// @notice The minimum amount of time to place a bid during an active auction
function timeBuffer() external view returns (uint256);

/// @notice The minimum percentage of the highest bid that a subsequent bid must beat
/// @notice The minimum percentage an incoming bid must raise the highest bid
function minBidIncrement() external view returns (uint256);

/// @notice Updates the time duration of each auction
Expand Down
2 changes: 1 addition & 1 deletion src/auction/types/AuctionTypesV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ contract AuctionTypesV1 {
/// @param treasury The DAO treasury
/// @param duration The time duration of each auction
/// @param timeBuffer The minimum time to place a bid
/// @param minBidIncrement The minimum percentage an incoming bid must beat the highest bid by
/// @param minBidIncrement The minimum percentage an incoming bid must raise the highest bid
/// @param reservePrice The reserve price of each auction
struct Settings {
address treasury;
Expand Down
44 changes: 23 additions & 21 deletions src/governance/governor/Governor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import { IGovernor } from "./IGovernor.sol";

/// @title Governor
/// @author Rohan Kulkarni
/// @notice DAO proposal manager and transaction scheduler
/// @notice A DAO's proposal manager and transaction scheduler
/// Modified from:
/// - OpenZeppelin Contracts v4.7.3 (governance/extensions/GovernorTimelockControl.sol)
/// - NounsDAOLogicV1.sol commit 2cbe6c7 - licensed under the BSD-3-Clause license.
contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
/// ///
/// CONSTANTS ///
Expand All @@ -34,7 +37,7 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
/// CONSTRUCTOR ///
/// ///

/// @param _manager The address of the contract upgrade manager
/// @param _manager The contract upgrade manager address
constructor(address _manager) payable initializer {
manager = IManager(_manager);
}
Expand Down Expand Up @@ -76,10 +79,10 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
settings.proposalThresholdBps = SafeCast.toUint16(_proposalThresholdBps);
settings.quorumThresholdBps = SafeCast.toUint16(_quorumThresholdBps);

// Initialize support for off-chain voting
// Initialize EIP-712 support
__EIP712_init(string.concat(settings.token.symbol(), " GOV"), "1");

// Grant ownership of the contract to the treasury
// Grant ownership to the treasury
__Ownable_init(_treasury);
}

Expand Down Expand Up @@ -135,7 +138,7 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
if (numTargets != _values.length) revert PROPOSAL_LENGTH_MISMATCH();
if (numTargets != _calldatas.length) revert PROPOSAL_LENGTH_MISMATCH();

// Compute the hash of the description
// Compute the description hash
bytes32 descriptionHash = keccak256(bytes(_description));

// Compute the proposal id
Expand All @@ -144,7 +147,7 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
// Get the pointer to store the proposal
Proposal storage proposal = proposals[proposalId];

// Ensure a proposal with the same id doesn't already exist
// Ensure the proposal doesn't already exist
if (proposal.voteStart != 0) revert PROPOSAL_EXISTS(proposalId);

// Used to store the snapshot and deadline
Expand All @@ -161,7 +164,6 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
// Store the proposal data
proposal.voteStart = uint32(snapshot);
proposal.voteEnd = uint32(deadline);

proposal.proposalThreshold = uint32(currentProposalThreshold);
proposal.quorumVotes = uint32(quorum());
proposal.proposer = msg.sender;
Expand Down Expand Up @@ -218,9 +220,9 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
// Used to store the signed digest
bytes32 digest;

// Cannot realistically overflow voter nonces
// Cannot realistically overflow
unchecked {
// Compute the encoded message
// Compute the message
digest = keccak256(
abi.encodePacked(
"\x19\x01",
Expand All @@ -230,11 +232,11 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
);
}

// Recover the signer of the message
// Recover the message signer
address recoveredAddress = ecrecover(digest, _v, _r, _s);

// Ensure the recovered signer is the given voter
if (recoveredAddress == address(0) || recoveredAddress != _voter) revert INVALID_SIGNER();
if (recoveredAddress == address(0) || recoveredAddress != _voter) revert INVALID_SIGNATURE();

return _castVote(_proposalId, _voter, _support, "");
}
Expand All @@ -249,7 +251,7 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
uint256 _support,
string memory _reason
) internal returns (uint256) {
// Ensure voting for the proposal is active
// Ensure voting is active
if (state(_proposalId) != ProposalState.Active) revert VOTING_NOT_STARTED();

// Ensure the voter hasn't already voted
Expand Down Expand Up @@ -304,8 +306,8 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
// Ensure the proposal has succeeded
if (state(_proposalId) != ProposalState.Succeeded) revert PROPOSAL_UNSUCCESSFUL();

// Schedule the proposal for execution and get the timestamp that it'll be valid to execute
eta = settings.treasury.schedule(_proposalId);
// Schedule the proposal for execution
eta = settings.treasury.queue(_proposalId);

emit ProposalQueued(_proposalId, eta);
}
Expand All @@ -320,9 +322,9 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
/// @param _calldatas The calldata of each call
/// @param _descriptionHash The hash of the description
function execute(
address[] memory _targets,
uint256[] memory _values,
bytes[] memory _calldatas,
address[] calldata _targets,
uint256[] calldata _values,
bytes[] calldata _calldatas,
bytes32 _descriptionHash
) external payable returns (bytes32) {
// Get the proposal id
Expand All @@ -334,7 +336,7 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
// Mark the proposal as executed
proposals[proposalId].executed = true;

// Call the treasury to execute the proposal
// Execute the proposal
settings.treasury.execute{ value: msg.value }(_targets, _values, _calldatas, _descriptionHash);

emit ProposalExecuted(proposalId);
Expand Down Expand Up @@ -518,12 +520,12 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
/// GOVERNOR SETTINGS ///
/// ///

/// @notice The minimum basis points of the total token supply required to submit a proposal
/// @notice The basis points of the token supply required to create a proposal
function proposalThresholdBps() external view returns (uint256) {
return settings.proposalThresholdBps;
}

/// @notice The minimum basis points of the total token supply required to reach quorum
/// @notice The basis points of the token supply required to reach quorum
function quorumThresholdBps() external view returns (uint256) {
return settings.quorumThresholdBps;
}
Expand All @@ -548,7 +550,7 @@ contract Governor is IGovernor, UUPS, Ownable, EIP712, GovernorStorageV1 {
return address(settings.token);
}

/// @notice The address of the transaction executor and treasury
/// @notice The address of the treasury
function treasury() external view returns (address) {
return address(settings.treasury);
}
Expand Down
12 changes: 6 additions & 6 deletions src/governance/governor/types/GovernorTypesV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import { Treasury } from "../../treasury/Treasury.sol";
/// @notice The Governor custom data types
interface GovernorTypesV1 {
/// @notice The governor settings
/// @param token The governance token
/// @param proposalThresholdBps The minimum votes (in basis points of the total supply) required to submit a proposal
/// @param quorumThresholdBps The minimum votes (in basis points of total supply) required to reach quorum
/// @param treasury The treasury controller
/// @param votingDelay The amount of time after a proposal until voting begins
/// @param votingPeriod The amount of time voting takes place for an active proposal
/// @param token The DAO governance token
/// @param proposalThresholdBps The basis points of the token supply required to create a proposal
/// @param quorumThresholdBps The basis points of the token supply required to reach quorum
/// @param treasury The DAO treasury
/// @param votingDelay The time delay to vote on a created proposal
/// @param votingPeriod The time period to vote on a proposal
/// @param vetoer The address with the ability to veto proposals
struct Settings {
Token token;
Expand Down
35 changes: 33 additions & 2 deletions src/governance/treasury/ITreasury.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,39 +58,70 @@ interface ITreasury is IUUPS, IOwnable {
/// FUNCTIONS ///
/// ///

/// @notice Initializes a DAO's treasury
/// @param governor The governor address
/// @param delay The time delay to execute a queued transaction
function initialize(address governor, uint256 delay) external;

/// @notice The timestamp that a proposal is valid to execute
/// @param proposalId The proposal id
function timestamp(bytes32 proposalId) external view returns (uint256);

/// @notice If a proposal has been queued
/// @param proposalId The proposal ids
function isQueued(bytes32 proposalId) external view returns (bool);

/// @notice If a proposal is ready to execute (does not consider if a proposal has expired)
/// @param proposalId The proposal id
function isReady(bytes32 proposalId) external view returns (bool);

/// @notice If a proposal has expired to execute
/// @param proposalId The proposal id
function isExpired(bytes32 proposalId) external view returns (bool);

/// @notice Hashes a proposal's details into its proposal id
/// @param targets The target addresses to call
/// @param values The ETH values of each call
/// @param calldatas The calldata of each call
/// @param descriptionHash The hash of the description
function hashProposal(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata calldatas,
bytes32 descriptionHash
) external pure returns (bytes32);

function schedule(bytes32 proposalId) external returns (uint256 eta);
/// @notice Schedules a proposal for execution
/// @param proposalId The proposal id
function queue(bytes32 proposalId) external returns (uint256 eta);

/// @notice Removes a queued proposal
/// @param proposalId The proposal id
function cancel(bytes32 proposalId) external;

/// @notice Executes a queued proposal
/// @param targets The target addresses to call
/// @param values The ETH values of each call
/// @param calldatas The calldata of each call
/// @param descriptionHash The hash of the description
function execute(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata calldatas,
bytes32 _descriptionHash
bytes32 descriptionHash
) external payable;

/// @notice The time delay to execute a queued transaction
function delay() external view returns (uint256);

/// @notice The time period to execute a transaction
function gracePeriod() external view returns (uint256);

/// @notice Updates the time delay
/// @param newDelay The new time delay
function updateDelay(uint256 newDelay) external;

/// @notice Updates the grace period
/// @param newGracePeriod The grace period
function updateGracePeriod(uint256 newGracePeriod) external;
}
Loading

0 comments on commit 01642c6

Please sign in to comment.