ETH Price: $1,743.87 (+10.52%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim Refund172157562023-05-08 12:24:23715 days ago1683548663IN
0x60232134...5EFEf8E1A
0 ETH0.0082003791.27143256
Create Bid171950922023-05-05 14:41:23718 days ago1683297683IN
0x60232134...5EFEf8E1A
0.1 ETH0.04493743257.87280463
Cast External Vo...171891862023-05-04 18:49:35719 days ago1683226175IN
0x60232134...5EFEf8E1A
0 ETH0.0101640979.84234451
Create Bid171890432023-05-04 18:20:47719 days ago1683224447IN
0x60232134...5EFEf8E1A
0.15 ETH0.01886412108.62928707
Cast External Vo...165139922023-01-29 17:33:23814 days ago1675013603IN
0x60232134...5EFEf8E1A
0 ETH0.0024190619
Create Bid165139152023-01-29 17:17:59814 days ago1675012679IN
0x60232134...5EFEf8E1A
0.158 ETH0.0022788820.37134798
Cast External Vo...165093342023-01-29 1:55:59814 days ago1674957359IN
0x60232134...5EFEf8E1A
0 ETH0.0008043714.96991032
Cast External Vo...164983672023-01-27 13:11:59816 days ago1674825119IN
0x60232134...5EFEf8E1A
0 ETH0.0017729913.925574
Create Bid164792562023-01-24 21:08:35819 days ago1674594515IN
0x60232134...5EFEf8E1A
0.15 ETH0.0035522420.3745741
Create Bid164792512023-01-24 21:07:35819 days ago1674594455IN
0x60232134...5EFEf8E1A
0.15 ETH0.0037669121.60734069
Create Bid164792482023-01-24 21:06:59819 days ago1674594419IN
0x60232134...5EFEf8E1A
0.15 ETH0.0034140319.58185137
Set Beneficiary164163642023-01-16 2:27:23827 days ago1673836043IN
0x60232134...5EFEf8E1A
0 ETH0.0009909232.68445136
Transfer Ownersh...164163232023-01-16 2:18:59827 days ago1673835539IN
0x60232134...5EFEf8E1A
0 ETH0.0005181317.90762387

Latest 10 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer172157562023-05-08 12:24:23715 days ago1683548663
0x60232134...5EFEf8E1A
0.1 ETH
Transfer171891862023-05-04 18:49:35719 days ago1683226175
0x60232134...5EFEf8E1A
0.09061588 ETH
Transfer171891862023-05-04 18:49:35719 days ago1683226175
0x60232134...5EFEf8E1A
0.05938411 ETH
Transfer165139922023-01-29 17:33:23814 days ago1675013603
0x60232134...5EFEf8E1A
0.10576632 ETH
Transfer165139922023-01-29 17:33:23814 days ago1675013603
0x60232134...5EFEf8E1A
0.05223367 ETH
Transfer165139152023-01-29 17:17:59814 days ago1675012679
0x60232134...5EFEf8E1A
0.15 ETH
Transfer165093342023-01-29 1:55:59814 days ago1674957359
0x60232134...5EFEf8E1A
0.09824054 ETH
Transfer165093342023-01-29 1:55:59814 days ago1674957359
0x60232134...5EFEf8E1A
0.05175945 ETH
Transfer164983672023-01-27 13:11:59816 days ago1674825119
0x60232134...5EFEf8E1A
0.09836288 ETH
Transfer164983672023-01-27 13:11:59816 days ago1674825119
0x60232134...5EFEf8E1A
0.05163711 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DelegateBid

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 12 : delegate-bid.sol
// SPDX-License-Identifier: BSD-3-Clause

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import {NounsDAOStorageV1, INounsDAOLogic} from "../external/nouns/governance/NounsDAOInterfaces.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {SafeTransferLib} from "solady/src/utils/SafeTransferLib.sol";
import {Refundable} from "./refundable.sol";

pragma solidity ^0.8.17;

/// @title DelegateBid is a delegated voter which accepts ETH bids in exchange
/// for casting votes on external DAO proposals
contract DelegateBid is IERC1271, ReentrancyGuard, Refundable, Ownable {
    /// Bid is the structure of an offer for the delegate to cast a vote on a
    /// proposal
    struct Bid {
        /// @notice The amount of ETH bid
        uint256 amount;
        /// @notice The block number the external proposal voting period ends
        uint256 endBlock;
        /// @notice the block number the bid was made
        uint256 txBlock;
        /// @notice The address of the bidder
        address bidder;
        /// @notice The support value to cast for vote
        uint8 support;
        /// @notice Whether the vote was cast for this bid
        bool executed;
        /// @notice Whether the bid was refunded
        bool refunded;
    }

    /// @notice An event emitted when a vote has been cast on an external proposal
    /// @param dao The external dao address
    /// @param propId The proposal id which was voted on
    /// @param support Support value for the vote. 0=against, 1=for, 2=abstain
    /// @param amount Amount of ETH bid
    /// @param bidder The address of the bidder
    event VoteCast(address indexed dao, uint256 indexed propId, uint8 support, uint256 amount, address bidder);

    /// @notice Emitted when vote cast gas fee is refunded and bid distributed
    event VoteCastRefundAndDistribute(
        address indexed caller, uint256 refundAmount, uint256 tip, bool refundSent, uint256 fee, bool feeSent
    );

    /// @notice An event emitted when a bid has been placed to cast a vote on an external proposal
    /// @param dao The external dao address
    /// @param propId The proposal id which was voted on
    /// @param support Support value for the vote. 0=against, 1=for, 2=abstain
    /// @param amount Amount of ETH bid
    /// @param bidder The address of the bidder
    /// @param reason The reason given for the vote by the voter
    event BidPlaced(
        address indexed dao, uint256 indexed propId, uint8 support, uint256 amount, address bidder, string reason
    );

    /// @notice Emitted when beneficiary is changed
    event NewBeneficiary(address oldBeneficiary, address newBeneficiary);

    /// @notice Emitted when min bid increment percentage is changed
    event NewMinBidIncrementPercentage(uint8 oldBidIncPercentage, uint8 newBidIncPercentage);

    /// @notice Emitted when min bid is changed
    event NewMinBid(uint256 oldMinBid, uint256 newMinBid);

    /// @notice Emitted when vote cast window is changed
    event NewCastWindow(uint256 oldExecWindow, uint256 newExecWindow);

    /// @notice Emitted when base tip awarted to execute vote cast is changed
    event NewBaseTip(uint256 oldTip, uint256 newTip);

    /// @notice Emitted when ERC1271 the signer is changed
    event SignerChanged(address oldSigner, address newSigner);

    /// @notice Emitted when the prop submitter is changed
    event SubmitterChanged(address oldSubmitter, address newSubmitter);

    // PROPERTIES
    // ----------

    /// @notice The name of this contract
    string public constant name = "Federation Delegate Bid";

    /// @notice The address of the contract beneficiary
    address public beneficiary;

    /// @notice The address of an account approved to sign messages on behalf of
    /// this contract
    address public approvedSigner;

    /// @notice The address of an account approved to submit proposals using the
    /// representation of this contract
    address public approvedSubmitter;

    /// @notice The minimum percent difference between the last bid placed for a
    /// proposal vote and the current one
    uint8 public minBidIncrementPercentage;

    /// @notice The minimum bid accepted to cast a vote
    uint256 public minBid;

    /// @notice The window in blocks where casting a vote is allowed
    uint256 public castWindow;

    /// @notice The default tip configured for casting a vote
    uint256 public baseTip;

    /// @notice The active bid for each proposal in a given DAO
    mapping(address => mapping(uint256 => Bid)) public bids;

    /**
     * @param _castWindow The window in blocks that a vote is elegible to be cast
     * @param _baseTip the default tip awarded for casting an external vote
     * @param _minBid the minimum bid accepted to cast a vote
     * @param _minBidIncrementPercentage % a new bid for a prop must be greater than the last bid
     */
    constructor(uint256 _castWindow, uint256 _baseTip, uint256 _minBid, uint8 _minBidIncrementPercentage) {
        castWindow = _castWindow;
        baseTip = _baseTip;
        minBid = _minBid;
        minBidIncrementPercentage = _minBidIncrementPercentage;

        /// @notice default beneficiary is the owner address
        beneficiary = msg.sender;
    }

    /**
     * @notice Create a bid for a proposal vote
     * @param dao The address of the DAO
     * @param propId The id of the proposal to vote on
     * @param support The support value for the vote. 0=against, 1=for, 2=abstain
     * @param reason A string reason for the vote cast.
     * @dev ensure that this delegate has representation for the given DAO address
     * before calling this fn
     */
    function createBid(address dao, uint256 propId, uint8 support, string calldata reason)
        external
        payable
        nonReentrant
    {
        require(dao != address(0), "DAO address is not valid");
        require(_isPendingOrActive(dao, propId), "Proposal is not pending or active");
        require(support <= 2, "Invalid support type");
        require(msg.value >= minBid, "Must send at least minBid amount");

        Bid storage bid = bids[dao][propId];
        uint256 lastAmount = bid.amount;
        address lastBidder = bid.bidder;

        require(
            msg.value >= lastAmount + ((lastAmount * minBidIncrementPercentage) / 100),
            "Must send more than last bid by minBidIncrementPercentage amount"
        );

        require(!bid.executed, "Vote already cast");

        // get proposal end block
        uint256 propEndBlock;
        try this._proposalEndBlock(dao, propId) returns (uint256 endBlock) {
            propEndBlock = endBlock;
        } catch (bytes memory) {
            revert("Failed getting proposal end block");
        }

        bid.amount = msg.value;
        bid.bidder = msg.sender;
        bid.support = support;
        bid.endBlock = propEndBlock;
        bid.txBlock = block.number;

        emit BidPlaced(dao, propId, support, bid.amount, msg.sender, reason);

        // refund previous bid if there was one
        if (lastBidder != address(0)) {
            SafeTransferLib.forceSafeTransferETH(lastBidder, lastAmount);
        }
    }

    /**
     * @notice Casts a vote on an external proposal. Tip is awarded to the caller
     * @param dao The address of the DAO
     * @param propId The id of the proposal to execute
     * @dev This function ensures that the proposal is within the execution window
     * and that some bid has been offered to cast the vote
     */
    function castExternalVote(address dao, uint256 propId) external nonReentrant {
        uint256 startGas = gasleft();

        require(dao != address(0), "DAO address is not valid");
        require(_isActive(dao, propId), "Voting is closed for this proposal");

        Bid storage bid = bids[address(dao)][propId];

        require(bid.amount > 0 && bid.bidder != address(0), "Bid not offered for this proposal");
        require(block.number >= bid.endBlock - castWindow, "Vote can only be cast during the proposal execution window");
        require(!bid.executed, "Vote already cast");
        require(bid.txBlock < block.number, "Vote cannot be cast in the same block the bid was made");

        bid.executed = true;

        INounsDAOLogic eDAO = INounsDAOLogic(dao);
        eDAO.castVote(propId, bid.support);

        emit VoteCast(dao, propId, bid.support, bid.amount, bid.bidder);

        // refund gas and calculate an incentive for the executer, distribute the
        // rest to the contract beneficiary
        unchecked {
            uint256 balance = address(this).balance;
            if (balance == 0) {
                return;
            }

            uint256 tip = min(baseTip, bid.amount);
            uint256 basefee = min(block.basefee, MAX_REFUND_BASE_FEE);
            uint256 gasPrice = min(tx.gasprice, basefee + MAX_REFUND_PRIORITY_FEE);
            uint256 gasUsed = min(startGas - gasleft() + REFUND_BASE_GAS, MAX_REFUND_GAS_USED);
            uint256 refundAmount = min(gasPrice * gasUsed, balance);
            uint256 refundIncludingTip = min(refundAmount + tip, bid.amount);
            (bool refundSent,) = tx.origin.call{value: refundIncludingTip}("");

            uint256 fee = bid.amount - refundIncludingTip;
            (bool feeSent,) = beneficiary.call{value: fee}("");
            emit VoteCastRefundAndDistribute(tx.origin, refundAmount, tip, refundSent, fee, feeSent);
        }
    }

    /**
     * @notice Refunds ETH offered on a cancelled proposal to the last bidder
     * @param dao The address of the DAO
     * @param propId The id of the proposal
     */
    function claimRefund(address dao, uint256 propId) external nonReentrant {
        Bid storage bid = bids[dao][propId];

        require(msg.sender == bid.bidder, "Only the bidder can claim their refund");
        require(!bid.refunded, "Bid already refunded");
        require(!bid.executed, "Vote already cast");
        require(address(this).balance >= bid.amount, "Insufficient balance to refund");

        // if the external proposal voting period has ended and we could not
        // cast the vote allow the bidder to claim a refund
        if (!_isPendingOrActive(dao, propId)) {
            bid.refunded = true;
            SafeTransferLib.forceSafeTransferETH(bid.bidder, bid.amount);
            return;
        }

        revert("Refund cannot be claimed");
    }

    /**
     * @notice Allows an approved submitter to submit a proposal against an external DAO
     */
    function submitProp(
        address[] memory targets,
        uint256[] memory values,
        string[] memory signatures,
        bytes[] memory calldatas,
        string memory description,
        INounsDAOLogic eDAO
    ) external returns (uint256) {
        require(msg.sender == approvedSubmitter, "Submitter only");
        uint256 propID = eDAO.propose(targets, values, signatures, calldatas, description);
        return propID;
    }

    // MANAGEMENT FUNCTIONS
    // --------------------

    /**
     * @notice Changes the beneficiary address
     * @dev Function for updating beneficiary
     */
    function setBeneficiary(address _beneficiary) external onlyOwner {
        beneficiary = _beneficiary;
        emit NewBeneficiary(beneficiary, _beneficiary);
    }

    /**
     * @notice Changes min bid increment percent
     * @dev function for updating minBidIncrementPercentage
     */
    function setMinBidIncrementPercentage(uint8 _minBidIncrementPercentage) external onlyOwner {
        minBidIncrementPercentage = _minBidIncrementPercentage;
        emit NewMinBidIncrementPercentage(minBidIncrementPercentage, _minBidIncrementPercentage);
    }

    /**
     * @notice Changes min bid
     * @dev function for updating minBid
     */
    function setMinBid(uint256 _minBid) external onlyOwner {
        minBid = _minBid;
        emit NewMinBid(minBid, _minBid);
    }

    /**
     * @notice Changes window for casting an external vote
     * @dev function for updating execWindow
     */
    function setCastWindow(uint256 _castWindow) external onlyOwner {
        castWindow = _castWindow;
        emit NewCastWindow(castWindow, _castWindow);
    }

    /**
     * @notice Sets approved submitter for proposals
     * @dev Function for updating approvedSubmitter
     */
    function setApprovedSubmitter(address _submitter) external onlyOwner {
        approvedSubmitter = _submitter;
        emit SubmitterChanged(approvedSubmitter, _submitter);
    }

    /**
     * @notice Sets approved signer for ERC1271 signatures
     * @dev Function for updating approvedSigner
     */
    function setApprovedSigner(address _signer) external onlyOwner {
        approvedSigner = _signer;
        emit SignerChanged(approvedSigner, _signer);
    }

    // IERC1271 IMPLEMENTATION
    // -----------------------

    bytes4 constant IERC1271_MAGIC_VALUE = 0x1626ba7e;

    /**
     * @notice Handles EOA and smart contract signature verification
     */
    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue) {
        require(approvedSigner != address(0), "Approved signer not set");
        if (SignatureChecker.isValidSignatureNow(approvedSigner, hash, signature)) {
            magicValue = IERC1271_MAGIC_VALUE;
        }
    }

    // HELPERS
    // -------

    /**
     * @notice Helper function that determines if a proposal has been opened or the voting period is active
     * @param dao The address of the DAO that the given propId is in
     * @param propId The id of the proposal
     * @return bool True if the proposal is pending or active
     */
    function _isPendingOrActive(address dao, uint256 propId) internal view returns (bool) {
        bool isPending = INounsDAOLogic(dao).state(propId) == INounsDAOLogic.ProposalState.Pending;
        bool isActive = INounsDAOLogic(dao).state(propId) == INounsDAOLogic.ProposalState.Active;
        return isPending || isActive;
    }

    /**
     * @notice Helper function that determines if a proposal voting period is active
     * @param dao The address of the DAO that the given propId is in
     * @param propId The id of the proposal
     * @return bool True if the proposal is pending or active
     */
    function _isActive(address dao, uint256 propId) internal view returns (bool) {
        bool isActive = INounsDAOLogic(dao).state(propId) == INounsDAOLogic.ProposalState.Active;
        return isActive;
    }

    /**
     * @notice Helper function that parses end block from external proposals.
     * @param dao The address of the DAO that the given propId is in
     * @param propId The id of the proposal
     * @return uint256 The voting end block of the external proposal
     */
    function _proposalEndBlock(address dao, uint256 propId) public view returns (uint256) {
        (,,,,,, uint256 endBlock,,,,,,) = NounsDAOStorageV1(dao).proposals(propId);
        return endBlock;
    }

    /**
     * @notice Helper function that compares two integers and returns the larger
     * one
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @notice Helper function that compares two integers and returns the
     * smaller one
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a <= b ? a : b;
    }
}

File 2 of 12 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 12 : IERC1271.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC1271 standard signature validation method for
 * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
 *
 * _Available since v4.1._
 */
interface IERC1271 {
    /**
     * @dev Should return whether the signature provided is valid for the provided data
     * @param hash      Hash of the data to be signed
     * @param signature Signature byte array associated with _data
     */
    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}

File 4 of 12 : NounsDAOInterfaces.sol
// SPDX-License-Identifier: BSD-3-Clause

/// @title Nouns DAO Logic interfaces and events

/**
 *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░██░░░████░░██░░░████░░░ *
 * ░░██████░░░████████░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 *
 */

// LICENSE
// NounsDAOInterfaces.sol is a modified version of Compound Lab's GovernorBravoInterfaces.sol:
// https://github.com/compound-finance/compound-protocol/blob/b9b14038612d846b83f8a009a82c38974ff2dcfe/contracts/Governance/GovernorBravoInterfaces.sol
//
// GovernorBravoInterfaces.sol source code Copyright 2020 Compound Labs, Inc. licensed under the BSD-3-Clause license.
// With modifications by Nounders DAO.
//
// Additional conditions of BSD-3-Clause can be found here: https://opensource.org/licenses/BSD-3-Clause
//
// MODIFICATIONS
// NounsDAOEvents, NounsDAOProxyStorage, NounsDAOStorageV1 add support for changes made by Nouns DAO to GovernorBravo.sol
// See NounsDAOLogicV1.sol for more details.
// NounsDAOStorageV1Adjusted and NounsDAOStorageV2 add support for a dynamic vote quorum.
// See NounsDAOLogicV2.sol for more details.

pragma solidity ^0.8.6;

contract NounsDAOEvents {
    /// @notice An event emitted when a new proposal is created
    event ProposalCreated(
        uint256 id,
        address proposer,
        address[] targets,
        uint256[] values,
        string[] signatures,
        bytes[] calldatas,
        uint256 startBlock,
        uint256 endBlock,
        string description
    );

    /// @notice An event emitted when a new proposal is created, which includes additional information
    event ProposalCreatedWithRequirements(
        uint256 id,
        address proposer,
        address[] targets,
        uint256[] values,
        string[] signatures,
        bytes[] calldatas,
        uint256 startBlock,
        uint256 endBlock,
        uint256 proposalThreshold,
        uint256 quorumVotes,
        string description
    );

    /// @notice An event emitted when a vote has been cast on a proposal
    /// @param voter The address which casted a vote
    /// @param proposalId The proposal id which was voted on
    /// @param support Support value for the vote. 0=against, 1=for, 2=abstain
    /// @param votes Number of votes which were cast by the voter
    /// @param reason The reason given for the vote by the voter
    event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 votes, string reason);

    /// @notice An event emitted when a proposal has been canceled
    event ProposalCanceled(uint256 id);

    /// @notice An event emitted when a proposal has been queued in the NounsDAOExecutor
    event ProposalQueued(uint256 id, uint256 eta);

    /// @notice An event emitted when a proposal has been executed in the NounsDAOExecutor
    event ProposalExecuted(uint256 id);

    /// @notice An event emitted when a proposal has been vetoed by vetoAddress
    event ProposalVetoed(uint256 id);

    /// @notice An event emitted when the voting delay is set
    event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);

    /// @notice An event emitted when the voting period is set
    event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);

    /// @notice Emitted when implementation is changed
    event NewImplementation(address oldImplementation, address newImplementation);

    /// @notice Emitted when proposal threshold basis points is set
    event ProposalThresholdBPSSet(uint256 oldProposalThresholdBPS, uint256 newProposalThresholdBPS);

    /// @notice Emitted when quorum votes basis points is set
    event QuorumVotesBPSSet(uint256 oldQuorumVotesBPS, uint256 newQuorumVotesBPS);

    /// @notice Emitted when pendingAdmin is changed
    event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);

    /// @notice Emitted when pendingAdmin is accepted, which means admin is updated
    event NewAdmin(address oldAdmin, address newAdmin);

    /// @notice Emitted when vetoer is changed
    event NewVetoer(address oldVetoer, address newVetoer);
}

contract NounsDAOEventsV2 is NounsDAOEvents {
    /// @notice Emitted when minQuorumVotesBPS is set
    event MinQuorumVotesBPSSet(uint16 oldMinQuorumVotesBPS, uint16 newMinQuorumVotesBPS);

    /// @notice Emitted when maxQuorumVotesBPS is set
    event MaxQuorumVotesBPSSet(uint16 oldMaxQuorumVotesBPS, uint16 newMaxQuorumVotesBPS);

    /// @notice Emitted when quorumCoefficient is set
    event QuorumCoefficientSet(uint32 oldQuorumCoefficient, uint32 newQuorumCoefficient);

    /// @notice Emitted when a voter cast a vote requesting a gas refund.
    event RefundableVote(address indexed voter, uint256 refundAmount, bool refundSent);

    /// @notice Emitted when admin withdraws the DAO's balance.
    event Withdraw(uint256 amount, bool sent);

    /// @notice Emitted when pendingVetoer is changed
    event NewPendingVetoer(address oldPendingVetoer, address newPendingVetoer);
}

contract NounsDAOProxyStorage {
    /// @notice Administrator for this contract
    address public admin;

    /// @notice Pending administrator for this contract
    address public pendingAdmin;

    /// @notice Active brains of Governor
    address public implementation;
}

/**
 * @title Storage for Governor Bravo Delegate
 * @notice For future upgrades, do not change NounsDAOStorageV1. Create a new
 * contract which implements NounsDAOStorageV1 and following the naming convention
 * NounsDAOStorageVX.
 */
contract NounsDAOStorageV1 is NounsDAOProxyStorage {
    /// @notice Vetoer who has the ability to veto any proposal
    address public vetoer;

    /// @notice The delay before voting on a proposal may take place, once proposed, in blocks
    uint256 public votingDelay;

    /// @notice The duration of voting on a proposal, in blocks
    uint256 public votingPeriod;

    /// @notice The basis point number of votes required in order for a voter to become a proposer. *DIFFERS from GovernerBravo
    uint256 public proposalThresholdBPS;

    /// @notice The basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed. *DIFFERS from GovernerBravo
    uint256 public quorumVotesBPS;

    /// @notice The total number of proposals
    uint256 public proposalCount;

    /// @notice The address of the Nouns DAO Executor NounsDAOExecutor
    INounsDAOExecutor public timelock;

    /// @notice The address of the Nouns tokens
    NounsTokenLike public nouns;

    /// @notice The official record of all proposals ever proposed
    mapping(uint256 => Proposal) public proposals;

    /// @notice The latest proposal for each proposer
    mapping(address => uint256) public latestProposalIds;

    struct Proposal {
        /// @notice Unique id for looking up a proposal
        uint256 id;
        /// @notice Creator of the proposal
        address proposer;
        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 proposalThreshold;
        /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 quorumVotes;
        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
        uint256 eta;
        /// @notice the ordered list of target addresses for calls to be made
        address[] targets;
        /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
        uint256[] values;
        /// @notice The ordered list of function signatures to be called
        string[] signatures;
        /// @notice The ordered list of calldata to be passed to each call
        bytes[] calldatas;
        /// @notice The block at which voting begins: holders must delegate their votes prior to this block
        uint256 startBlock;
        /// @notice The block at which voting ends: votes must be cast prior to this block
        uint256 endBlock;
        /// @notice Current number of votes in favor of this proposal
        uint256 forVotes;
        /// @notice Current number of votes in opposition to this proposal
        uint256 againstVotes;
        /// @notice Current number of votes for abstaining for this proposal
        uint256 abstainVotes;
        /// @notice Flag marking whether the proposal has been canceled
        bool canceled;
        /// @notice Flag marking whether the proposal has been vetoed
        bool vetoed;
        /// @notice Flag marking whether the proposal has been executed
        bool executed;
        /// @notice Receipts of ballots for the entire set of voters
        mapping(address => Receipt) receipts;
    }

    /// @notice Ballot receipt record for a voter
    struct Receipt {
        /// @notice Whether or not a vote has been cast
        bool hasVoted;
        /// @notice Whether or not the voter supports the proposal or abstains
        uint8 support;
        /// @notice The number of votes the voter had, which were cast
        uint96 votes;
    }

    /// @notice Possible states that a proposal may be in
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed,
        Vetoed
    }
}

/**
 * @title Extra fields added to the `Proposal` struct from NounsDAOStorageV1
 * @notice The following fields were added to the `Proposal` struct:
 * - `Proposal.totalSupply`
 * - `Proposal.creationBlock`
 */
contract NounsDAOStorageV1Adjusted is NounsDAOProxyStorage {
    /// @notice Vetoer who has the ability to veto any proposal
    address public vetoer;

    /// @notice The delay before voting on a proposal may take place, once proposed, in blocks
    uint256 public votingDelay;

    /// @notice The duration of voting on a proposal, in blocks
    uint256 public votingPeriod;

    /// @notice The basis point number of votes required in order for a voter to become a proposer. *DIFFERS from GovernerBravo
    uint256 public proposalThresholdBPS;

    /// @notice The basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed. *DIFFERS from GovernerBravo
    uint256 public quorumVotesBPS;

    /// @notice The total number of proposals
    uint256 public proposalCount;

    /// @notice The address of the Nouns DAO Executor NounsDAOExecutor
    INounsDAOExecutor public timelock;

    /// @notice The address of the Nouns tokens
    NounsTokenLike public nouns;

    /// @notice The official record of all proposals ever proposed
    mapping(uint256 => Proposal) internal _proposals;

    /// @notice The latest proposal for each proposer
    mapping(address => uint256) public latestProposalIds;

    struct Proposal {
        /// @notice Unique id for looking up a proposal
        uint256 id;
        /// @notice Creator of the proposal
        address proposer;
        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 proposalThreshold;
        /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 quorumVotes;
        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
        uint256 eta;
        /// @notice the ordered list of target addresses for calls to be made
        address[] targets;
        /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
        uint256[] values;
        /// @notice The ordered list of function signatures to be called
        string[] signatures;
        /// @notice The ordered list of calldata to be passed to each call
        bytes[] calldatas;
        /// @notice The block at which voting begins: holders must delegate their votes prior to this block
        uint256 startBlock;
        /// @notice The block at which voting ends: votes must be cast prior to this block
        uint256 endBlock;
        /// @notice Current number of votes in favor of this proposal
        uint256 forVotes;
        /// @notice Current number of votes in opposition to this proposal
        uint256 againstVotes;
        /// @notice Current number of votes for abstaining for this proposal
        uint256 abstainVotes;
        /// @notice Flag marking whether the proposal has been canceled
        bool canceled;
        /// @notice Flag marking whether the proposal has been vetoed
        bool vetoed;
        /// @notice Flag marking whether the proposal has been executed
        bool executed;
        /// @notice Receipts of ballots for the entire set of voters
        mapping(address => Receipt) receipts;
        /// @notice The total supply at the time of proposal creation
        uint256 totalSupply;
        /// @notice The block at which this proposal was created
        uint256 creationBlock;
    }

    /// @notice Ballot receipt record for a voter
    struct Receipt {
        /// @notice Whether or not a vote has been cast
        bool hasVoted;
        /// @notice Whether or not the voter supports the proposal or abstains
        uint8 support;
        /// @notice The number of votes the voter had, which were cast
        uint96 votes;
    }

    /// @notice Possible states that a proposal may be in
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed,
        Vetoed
    }
}

/**
 * @title Storage for Governor Bravo Delegate
 * @notice For future upgrades, do not change NounsDAOStorageV2. Create a new
 * contract which implements NounsDAOStorageV2 and following the naming convention
 * NounsDAOStorageVX.
 */
contract NounsDAOStorageV2 is NounsDAOStorageV1Adjusted {
    DynamicQuorumParamsCheckpoint[] public quorumParamsCheckpoints;

    /// @notice Pending new vetoer
    address public pendingVetoer;

    struct DynamicQuorumParams {
        /// @notice The minimum basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed.
        uint16 minQuorumVotesBPS;
        /// @notice The maximum basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed.
        uint16 maxQuorumVotesBPS;
        /// @notice The dynamic quorum coefficient
        /// @dev Assumed to be fixed point integer with 6 decimals, i.e 0.2 is represented as 0.2 * 1e6 = 200000
        uint32 quorumCoefficient;
    }

    /// @notice A checkpoint for storing dynamic quorum params from a given block
    struct DynamicQuorumParamsCheckpoint {
        /// @notice The block at which the new values were set
        uint32 fromBlock;
        /// @notice The parameter values of this checkpoint
        DynamicQuorumParams params;
    }

    struct ProposalCondensed {
        /// @notice Unique id for looking up a proposal
        uint256 id;
        /// @notice Creator of the proposal
        address proposer;
        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 proposalThreshold;
        /// @notice The minimum number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 quorumVotes;
        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
        uint256 eta;
        /// @notice The block at which voting begins: holders must delegate their votes prior to this block
        uint256 startBlock;
        /// @notice The block at which voting ends: votes must be cast prior to this block
        uint256 endBlock;
        /// @notice Current number of votes in favor of this proposal
        uint256 forVotes;
        /// @notice Current number of votes in opposition to this proposal
        uint256 againstVotes;
        /// @notice Current number of votes for abstaining for this proposal
        uint256 abstainVotes;
        /// @notice Flag marking whether the proposal has been canceled
        bool canceled;
        /// @notice Flag marking whether the proposal has been vetoed
        bool vetoed;
        /// @notice Flag marking whether the proposal has been executed
        bool executed;
        /// @notice The total supply at the time of proposal creation
        uint256 totalSupply;
        /// @notice The block at which this proposal was created
        uint256 creationBlock;
    }
}

interface INounsDAOExecutor {
    function delay() external view returns (uint256);

    function GRACE_PERIOD() external view returns (uint256);

    function acceptAdmin() external;

    function queuedTransactions(bytes32 hash) external view returns (bool);

    function queueTransaction(
        address target,
        uint256 value,
        string calldata signature,
        bytes calldata data,
        uint256 eta
    ) external returns (bytes32);

    function cancelTransaction(
        address target,
        uint256 value,
        string calldata signature,
        bytes calldata data,
        uint256 eta
    ) external;

    function executeTransaction(
        address target,
        uint256 value,
        string calldata signature,
        bytes calldata data,
        uint256 eta
    ) external payable returns (bytes memory);
}

interface INounsDAOLogic {
    /// @notice Possible states that a proposal may be in
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed,
        Vetoed
    }

    function propose(
        address[] memory targets,
        uint256[] memory values,
        string[] memory signatures,
        bytes[] memory calldatas,
        string memory description
    ) external returns (uint256);

    function queue(uint256 proposalId) external;

    function execute(uint256 proposalId) external;

    function cancel(uint256 proposalId) external;

    function veto(uint256 proposalId) external;

    function castVote(uint256 proposalId, uint8 support) external;

    function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external;

    function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external;

    function state(uint256 proposalId) external view returns (ProposalState);
}

interface NounsTokenLike {
    function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96);

    function totalSupply() external view returns (uint256);
}

File 5 of 12 : SignatureChecker.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.1) (utils/cryptography/SignatureChecker.sol)

pragma solidity ^0.8.0;

import "./ECDSA.sol";
import "../Address.sol";
import "../../interfaces/IERC1271.sol";

/**
 * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA
 * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like
 * Argent and Gnosis Safe.
 *
 * _Available since v4.1._
 */
library SignatureChecker {
    /**
     * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the
     * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.
     *
     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
     * change through time. It could return true at block N and false at block N+1 (or the opposite).
     */
    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
        (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
        if (error == ECDSA.RecoverError.NoError && recovered == signer) {
            return true;
        }

        (bool success, bytes memory result) =
            signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature));
        return (
            success && result.length == 32
                && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)
        );
    }
}

File 6 of 12 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 7 of 12 : SafeTransferLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH
    /// that disallows any storage writes.
    uint256 internal constant _GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    /// Multiply by a small constant (e.g. 2), if needed.
    uint256 internal constant _GAS_STIPEND_NO_GRIEF = 100000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` (in wei) ETH to `to`.
    /// Reverts upon failure.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {
                // Store the function selector of `ETHTransferFailed()`.
                mstore(0x00, 0xb12d13eb)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    /// The `gasStipend` can be set to a low enough value to prevent
    /// storage writes or gas griefing.
    ///
    /// If sending via the normal procedure fails, force sends the ETH by
    /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH.
    ///
    /// Reverts if the current contract has insufficient balance.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // If insufficient balance, revert.
            if lt(selfbalance(), amount) {
                // Store the function selector of `ETHTransferFailed()`.
                mstore(0x00, 0xb12d13eb)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Transfer the ETH and check if it succeeded or not.
            if iszero(call(gasStipend, to, amount, 0, 0, 0, 0)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                // We can directly use `SELFDESTRUCT` in the contract creation.
                // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758
                pop(create(amount, 0x0b, 0x16))
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a gas stipend
    /// equal to `_GAS_STIPEND_NO_GRIEF`. This gas stipend is a reasonable default
    /// for 99% of cases and can be overriden with the three-argument version of this
    /// function if necessary.
    ///
    /// If sending via the normal procedure fails, force sends the ETH by
    /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH.
    ///
    /// Reverts if the current contract has insufficient balance.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        // Manually inlined because the compiler doesn't inline functions with branches.
        /// @solidity memory-safe-assembly
        assembly {
            // If insufficient balance, revert.
            if lt(selfbalance(), amount) {
                // Store the function selector of `ETHTransferFailed()`.
                mstore(0x00, 0xb12d13eb)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Transfer the ETH and check if it succeeded or not.
            if iszero(call(_GAS_STIPEND_NO_GRIEF, to, amount, 0, 0, 0, 0)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                // We can directly use `SELFDESTRUCT` in the contract creation.
                // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758
                pop(create(amount, 0x0b, 0x16))
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    /// The `gasStipend` can be set to a low enough value to prevent
    /// storage writes or gas griefing.
    ///
    /// Simply use `gasleft()` for `gasStipend` if you don't need a gas stipend.
    ///
    /// Note: Does NOT revert upon failure.
    /// Returns whether the transfer of ETH is successful instead.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and check if it succeeded or not.
            success := call(gasStipend, to, amount, 0, 0, 0, 0)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.

            // Store the function selector of `transferFrom(address,address,uint256)`.
            mstore(0x00, 0x23b872dd)
            mstore(0x20, from) // Store the `from` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x60, amount) // Store the `amount` argument.

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFromFailed()`.
                mstore(0x00, 0x7939f424)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.

            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, from) // Store the `from` argument.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                // Store the function selector of `TransferFromFailed()`.
                mstore(0x00, 0x7939f424)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            // Store the function selector of `transferFrom(address,address,uint256)`.
            mstore(0x00, 0x23b872dd)
            mstore(0x40, to) // Store the `to` argument.
            // The `amount` argument is already written to the memory word at 0x6a.
            amount := mload(0x60)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFromFailed()`.
                mstore(0x00, 0x7939f424)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1a, to) // Store the `to` argument.
            mstore(0x3a, amount) // Store the `amount` argument.
            // Store the function selector of `transfer(address,uint256)`,
            // left by 6 bytes (enough for 8tb of memory represented by the free memory pointer).
            // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL).
            mstore(0x00, 0xa9059cbb000000000000)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x16, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFailed()`.
                mstore(0x00, 0x90b8ec18)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the part of the free memory pointer that was overwritten,
            // which is guaranteed to be zero, if less than 8tb of memory is used.
            mstore(0x3a, 0)
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x3a, 0x20)
                )
            ) {
                // Store the function selector of `TransferFailed()`.
                mstore(0x00, 0x90b8ec18)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x1a, to) // Store the `to` argument.
            // The `amount` argument is already written to the memory word at 0x3a.
            amount := mload(0x3a)
            // Store the function selector of `transfer(address,uint256)`,
            // left by 6 bytes (enough for 8tb of memory represented by the free memory pointer).
            // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL).
            mstore(0x00, 0xa9059cbb000000000000)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x16, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFailed()`.
                mstore(0x00, 0x90b8ec18)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the part of the free memory pointer that was overwritten,
            // which is guaranteed to be zero, if less than 8tb of memory is used.
            mstore(0x3a, 0)
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1a, to) // Store the `to` argument.
            mstore(0x3a, amount) // Store the `amount` argument.
            // Store the function selector of `approve(address,uint256)`,
            // left by 6 bytes (enough for 8tb of memory represented by the free memory pointer).
            // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL).
            mstore(0x00, 0x095ea7b3000000000000)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x16, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `ApproveFailed()`.
                mstore(0x00, 0x3e3f8f73)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the part of the free memory pointer that was overwritten,
            // which is guaranteed to be zero, if less than 8tb of memory is used.
            mstore(0x3a, 0)
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, account) // Store the `account` argument.
            amount :=
                mul(
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x1c, 0x24, 0x20, 0x20)
                    )
                )
        }
    }
}

File 8 of 12 : refundable.sol
// SPDX-License-Identifier: BSD-3-Clause

pragma solidity ^0.8.17;

contract Refundable {
    /// @notice The maximum priority fee used to cap gas refunds in `castRefundableVote`
    uint256 public constant MAX_REFUND_PRIORITY_FEE = 2 gwei;

    /// @notice The vote refund gas overhead, including 7K for ETH transfer and 29K for general transaction overhead
    uint256 public constant REFUND_BASE_GAS = 36000;

    /// @notice The maximum gas units the DAO will refund voters on; supports about 9,190 characters
    uint256 public constant MAX_REFUND_GAS_USED = 200_000;

    /// @notice The maximum basefee the DAO will refund voters on
    uint256 public constant MAX_REFUND_BASE_FEE = 200 gwei;
}

File 9 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 10 of 12 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 11 of 12 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 12 of 12 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

Settings
{
  "viaIR": true,
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"uint256","name":"_castWindow","type":"uint256"},{"internalType":"uint256","name":"_baseTip","type":"uint256"},{"internalType":"uint256","name":"_minBid","type":"uint256"},{"internalType":"uint8","name":"_minBidIncrementPercentage","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dao","type":"address"},{"indexed":true,"internalType":"uint256","name":"propId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"BidPlaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldTip","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTip","type":"uint256"}],"name":"NewBaseTip","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldBeneficiary","type":"address"},{"indexed":false,"internalType":"address","name":"newBeneficiary","type":"address"}],"name":"NewBeneficiary","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldExecWindow","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newExecWindow","type":"uint256"}],"name":"NewCastWindow","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMinBid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinBid","type":"uint256"}],"name":"NewMinBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"oldBidIncPercentage","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"newBidIncPercentage","type":"uint8"}],"name":"NewMinBidIncrementPercentage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"},{"indexed":false,"internalType":"address","name":"newSigner","type":"address"}],"name":"SignerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldSubmitter","type":"address"},{"indexed":false,"internalType":"address","name":"newSubmitter","type":"address"}],"name":"SubmitterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dao","type":"address"},{"indexed":true,"internalType":"uint256","name":"propId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"bidder","type":"address"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tip","type":"uint256"},{"indexed":false,"internalType":"bool","name":"refundSent","type":"bool"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"bool","name":"feeSent","type":"bool"}],"name":"VoteCastRefundAndDistribute","type":"event"},{"inputs":[],"name":"MAX_REFUND_BASE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REFUND_GAS_USED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REFUND_PRIORITY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REFUND_BASE_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dao","type":"address"},{"internalType":"uint256","name":"propId","type":"uint256"}],"name":"_proposalEndBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvedSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvedSubmitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTip","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"bids","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"txBlock","type":"uint256"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"bool","name":"refunded","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dao","type":"address"},{"internalType":"uint256","name":"propId","type":"uint256"}],"name":"castExternalVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"castWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dao","type":"address"},{"internalType":"uint256","name":"propId","type":"uint256"}],"name":"claimRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dao","type":"address"},{"internalType":"uint256","name":"propId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"createBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBidIncrementPercentage","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setApprovedSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_submitter","type":"address"}],"name":"setApprovedSubmitter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"setBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_castWindow","type":"uint256"}],"name":"setCastWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minBid","type":"uint256"}],"name":"setMinBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_minBidIncrementPercentage","type":"uint8"}],"name":"setMinBidIncrementPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"string[]","name":"signatures","type":"string[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"string","name":"description","type":"string"},{"internalType":"contract INounsDAOLogic","name":"eDAO","type":"address"}],"name":"submitProp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080346100e157601f611efc38819003918201601f19168301916001600160401b038311848410176100e6578084926080946040528339810103126100e1578051602082015191606060408201519101519060ff821682036100e15760016000556001549360018060a01b031993338587161760015560405195339060018060a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a36006556007556005556004549060ff60a01b9060a01b169060ff60a01b19161760045533906002541617600255611dff90816100fd8239f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe608080604052600436101561001357600080fd5b60003560e01c90816301495c1c146111f557508063042bc3de146111d757806306fdde031461114d57806312874688146110fc5780631626ba7e146110395780631c31f71014610fc05780633630593914610f4757806336ebdb3814610ecb57806338af3eed14610ea25780633be8ef3f14610e855780633e109a1914610e67578063715018a614610e0a57806386df10ff1461097b5780638da5cb5b146109525780638e6fad45146109345780638f859f421461090b57806393e54a6b14610891578063b296024d1461086d578063b97de68f14610834578063bc4cd08414610814578063d082fe17146107eb578063d317774e146103c9578063d50f1dec146103ab578063e45d5f3e1461035a578063e57066ca1461031a578063f2fde38b14610251578063fbfee876146102325763ff0bb0d91461015357600080fd5b3461021a57604036600319011261021a5761016c611284565b60405163013cf08b60e01b815260248035600483015290916101a0916001600160a01b039183918591829085165afa918215610226576000926101b5575b602083604051908152f35b90915082813d831161021f575b6101cc818361129a565b8101031261021a5760208201519081160361021a578061021261018060c06020940151926101fd6101408201611dbc565b5061020b6101608201611dbc565b5001611dbc565b5038806101aa565b600080fd5b503d6101c2565b6040513d6000823e3d90fd5b3461021a57600036600319011261021a57602060405163773594008152f35b3461021a57602036600319011261021a5761026a611284565b610272611374565b6001600160a01b039081169081156102c657600154826bffffffffffffffffffffffff60a01b821617600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b3461021a57604036600319011261021a57610353610336611284565b610345600260005414156113cc565b600260005560243590611514565b6001600055005b3461021a57602036600319011261021a577f77aed0985629485c13bfd593822543f4bab8881be176ee9e6025762ecaa253016040600435610399611374565b806006558151908082526020820152a1005b3461021a57600036600319011261021a576020600654604051908152f35b608036600319011261021a576103dd611284565b60ff604435166044350361021a576001600160401b03806064351161021a5736602360643501121561021a57606435600401351161021a573660246064356004013560643501011161021a57610438600260005414156113cc565b60026000556104516001600160a01b0382161515611418565b61045d60243582611cf8565b1561079c57600260ff604435161161076057600554341061071c5760018060a01b03811660005260086020526040600020602435600052602052604060002080549160038201549160ff60045460a01c16848181020481148515171561070657606490850204840180851161070657341061069c576104e260ff8460a81c1615611464565b604051600162f44f2760e01b031981526001600160a01b03831660048201526024803590820152602081604481305afa60009181610668575b50610578576105286114a4565b5060405162461bcd60e51b815260206004820152602160248201527f4661696c65642067657474696e672070726f706f73616c20656e6420626c6f636044820152606b60f81b6064820152608490fd5b34825560ff60a01b60443560a01b1660ff60a01b1933166affffffffffffffffffffff60a81b861617176003830155600182015560024391015560405160ff604435168152346020820152336040820152608060608201526064356004013560808201526064356004013560246064350160a0830137600060a060643560040135830101527f6c9461c1cfed7740d3f3f993b1adb6e4b413e353ad747031a6f0b17fb7726d306024359260018060a01b03169160a081601f19601f6064356004013501168101030190a36001600160a01b03169081610658576001600055005b610661916114d4565b8080610353565b9091506020813d602011610694575b816106846020938361129a565b8101031261021a5751908661051b565b3d9150610677565b608460405162461bcd60e51b815260206004820152604060248201527f4d7573742073656e64206d6f7265207468616e206c617374206269642062792060448201527f6d696e426964496e6372656d656e7450657263656e7461676520616d6f756e746064820152fd5b634e487b7160e01b600052601160045260246000fd5b606460405162461bcd60e51b815260206004820152602060248201527f4d7573742073656e64206174206c65617374206d696e42696420616d6f756e746044820152fd5b60405162461bcd60e51b8152602060048201526014602482015273496e76616c696420737570706f7274207479706560601b6044820152606490fd5b60405162461bcd60e51b815260206004820152602160248201527f50726f706f73616c206973206e6f742070656e64696e67206f722061637469766044820152606560f81b6064820152608490fd5b3461021a57600036600319011261021a576003546040516001600160a01b039091168152602090f35b3461021a57600036600319011261021a576020604051642e90edd0008152f35b3461021a57604036600319011261021a57610353610850611284565b61085f600260005414156113cc565b600260005560243590611977565b3461021a57600036600319011261021a57602060ff60045460a01c16604051908152f35b3461021a57602036600319011261021a577feeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad505796108cb611284565b6108d3611374565b600380546001600160a01b0319166001600160a01b03929092169182179055604080518281526020810192909252819081015b0390a1005b3461021a57600036600319011261021a576004546040516001600160a01b039091168152602090f35b3461021a57600036600319011261021a576020600754604051908152f35b3461021a57600036600319011261021a576001546040516001600160a01b039091168152602090f35b3461021a5760c036600319011261021a576004356001600160401b03811161021a573660238201121561021a5780600401356109b68161135d565b916109c4604051938461129a565b81835260208301906024829360051b8201019036821161021a57602401915b818310610dea57505050602435906001600160401b03821161021a573660238301121561021a57816004013590610a198261135d565b92610a27604051948561129a565b828452602084016024819460051b8301019136831161021a57602401905b828210610dda575050506044356001600160401b03811161021a573660238201121561021a57806004013590610a7a8261135d565b90610a88604051928361129a565b82825260208201906024829460051b8201019036821161021a5760248101925b828410610dac57505050506001600160401b036064351161021a5736602360643501121561021a576064356004013593610ae18561135d565b91610aef604051938461129a565b8583526020830180963660248260051b60643501011161021a57602460643501915b60248260051b60643501018310610d77575050506084356001600160401b03811161021a57610b44903690600401611316565b60a435979095906001600160a01b038916890361021a576004546001600160a01b03163303610d4157604051636d4ab48d60e11b815260a06004820152995160a48b018190528a9897969594939260c48a01929160005b818110610d1f575050506020906003198a84030160248b0152519182815201929060005b818110610d065750505060031987830301604488015251808252602082019160208260051b82010194926000915b838310610ccf57505050505060031985830301606486015251808252602082019160208260051b82010194926000915b838310610c9c57878703600319016084890152876020818b81600081610c438e8e6112d6565b03926001600160a01b03165af1801561022657600090610c69575b602090604051908152f35b506020813d602011610c94575b81610c836020938361129a565b8101031261021a5760209051610c5e565b3d9150610c76565b91939650919394602080610cbc600193601f198682030187528a516112d6565b9801930193019092889695949293610c1d565b919396979850919394602080610cf1600193601f198682030187528a516112d6565b98019301930190928a98979695949293610bed565b825185528b995060209485019490920191600101610bbf565b82516001600160a01b031685528d9b5060209485019490920191600101610b9b565b60405162461bcd60e51b815260206004820152600e60248201526d5375626d6974746572206f6e6c7960901b6044820152606490fd5b8235906001600160401b03821161021a5760208091610d9f6024948536916064350101611316565b8152019301929050610b11565b6001600160401b0384351161021a5760208091610dcf3660248835870101611316565b815201930192610aa8565b8135815260209182019101610a45565b82356001600160a01b038116810361021a578152602092830192016109e3565b3461021a57600036600319011261021a57610e23611374565b600180546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461021a57600036600319011261021a576020600554604051908152f35b3461021a57600036600319011261021a576020604051618ca08152f35b3461021a57600036600319011261021a576002546040516001600160a01b039091168152602090f35b3461021a57602036600319011261021a5760043560ff81169081810361021a577f0ade66b49969898cbfa1f0d478364f2552fda679597b9a19c76f1cf4207a287691604091610f18611374565b6004805460ff60a01b191660a092831b60ff60a01b1617908190558351911c60ff1681526020810191909152a1005b3461021a57602036600319011261021a577f0b58a643e259107d3f251effee8248c1dc89b4530c88dd514960273e8961e481610f81611284565b610f89611374565b600480546001600160a01b0319166001600160a01b0392909216918217905560408051828152602081019290925281908101610906565b3461021a57602036600319011261021a577f6b73ba97679a45fa03de9ae7002a53163e4c0c6cdcb3ae225dd5fffd555181f2610ffa611284565b611002611374565b600280546001600160a01b0319166001600160a01b0392909216918217905560408051828152602081019290925281908101610906565b3461021a57604036600319011261021a576024356001600160401b03811161021a57611069903690600401611316565b6003546000916001600160a01b039091169081156110b75761108e9160043590611b18565b6110a9575b6040516001600160e01b03199091168152602090f35b50630b135d3f60e11b611093565b60405162461bcd60e51b815260206004820152601760248201527f417070726f766564207369676e6572206e6f74207365740000000000000000006044820152606490fd5b3461021a57602036600319011261021a577fd4420e2ede06c8ec744d7935828ce668b6901be78f6512ed5d9f84dd9564f8df604060043561113b611374565b806005558151908082526020820152a1005b3461021a57600036600319011261021a5760405160408101908082106001600160401b038311176111c1576111bd91604052601781527f46656465726174696f6e2044656c65676174652042696400000000000000000060208201526040519182916020835260208301906112d6565b0390f35b634e487b7160e01b600052604160045260246000fd5b3461021a57600036600319011261021a57602060405162030d408152f35b3461021a57604036600319011261021a5760e09060ff6001600160a01b038061121c611284565b16600052600860205260406000206024356000526020526040600020908154916001810154600360028301549201549386526020860152604085015281166060840152818160a01c166080840152818160a81c16151560a084015260b01c16151560c0820152f35b600435906001600160a01b038216820361021a57565b90601f801991011681019081106001600160401b038211176111c157604052565b6001600160401b0381116111c157601f01601f191660200190565b919082519283825260005b848110611302575050826000602080949584010152601f8019910116010190565b6020818301810151848301820152016112e1565b81601f8201121561021a5780359061132d826112bb565b9261133b604051948561129a565b8284526020838301011161021a57816000926020809301838601378301015290565b6001600160401b0381116111c15760051b60200190565b6001546001600160a01b0316330361138857565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b156113d357565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b1561141f57565b60405162461bcd60e51b815260206004820152601860248201527f44414f2061646472657373206973206e6f742076616c696400000000000000006044820152606490fd5b1561146b57565b60405162461bcd60e51b8152602060048201526011602482015270159bdd1948185b1c9958591e4818d85cdd607a1b6044820152606490fd5b3d156114cf573d906114b5826112bb565b916114c3604051938461129a565b82523d6000602084013e565b606090565b8147106115065760008080808585620186a0f1156114f0575050565b601691600b916000526073825360ff602053f050565b63b12d13eb6000526004601cfd5b905a6001600160a01b0392831692906000611530851515611418565b604091825191631f27a4f360e11b83526004958087850152602096602494888187818d5afa90811561196d578491611940575b50600981101561192e576001036118e1578883526008885285832082845288528583209485541515806118d2575b15611886576001860154600654810390811161187457431061180c57600386019182546115c460ff8260a81c1615611464565b43600289015410156117ac5760ff60a81b1916600160a81b178084558b3b156117a857908560ff60448e9594838d519788948593630acf027160e31b85528c8986015260a01c16888401525af1801561179e5761176f575b50505054977f530751216f7b1ed8586c79759d3c12ea7c29565d484512af313c3787d7afdac2606086549a8989519160ff8160a01c1683528d8d8401521689820152a347801561176557818080926007548b81111560001461175d57955b642e90edd00048811061175257506377359400485b013a81106117485750618ca03a915b5a90030162030d408082116117405750905b02908082116117385750995b8a86019080821161173157505b8180808084325af1966116da6114a4565b5054038098600254165af1946116ee6114a4565b5083519687528601521515908401526060830152151560808201527fdcea780a1dde82a82fb04cade0bc656a9011b7c533ba9c0b42021464d0531f7a60a03292a2565b90506116c9565b9050996116bc565b9050906116b0565b618ca0909161169e565b63773594009061168f565b508a9561167a565b5050505050505050565b6001600160401b03839694961161178d57505086529138808061161c565b634e487b7160e01b84526041905282fd5b89513d88823e3d90fd5b8580fd5b5060366084928b8a519362461bcd60e51b85528401528201527f566f74652063616e6e6f74206265206361737420696e207468652073616d6520604482015275626c6f636b207468652062696420776173206d61646560501b6064820152fd5b865162461bcd60e51b8152918201899052603a908201527f566f74652063616e206f6e6c79206265206361737420647572696e672074686560448201527f2070726f706f73616c20657865637574696f6e2077696e646f770000000000006064820152608490fd5b50634e487b7160e01b84526011825283fd5b865162461bcd60e51b81529182018990526021908201527f426964206e6f74206f66666572656420666f7220746869732070726f706f73616044820152601b60fa1b6064820152608490fd5b50876003870154161515611591565b855162461bcd60e51b81529081018890526022818601527f566f74696e6720697320636c6f73656420666f7220746869732070726f706f73604482015261185b60f21b6064820152608490fd5b634e487b7160e01b8452602182528584fd5b6119609150893d8b11611966575b611958818361129a565b810190611ce0565b38611563565b503d61194e565b87513d86823e3d90fd5b9060018060a01b03808316600052602092600884526040928360002081600052855283600020926003840191825491821693843303611ac55760ff8360b01c16611a8a576119cb60ff8460a81c1615611464565b479554809610611a4657906119df91611cf8565b15611a2857845162461bcd60e51b815260048101879052601860248201527f526566756e642063616e6e6f7420626520636c61696d656400000000000000006044820152606490fd5b60ff60b01b1916600160b01b179055611a4493509091506114d4565b565b865162461bcd60e51b815260048101899052601e60248201527f496e73756666696369656e742062616c616e636520746f20726566756e6400006044820152606490fd5b865162461bcd60e51b8152600481018990526014602482015273109a5908185b1c9958591e481c99599d5b99195960621b6044820152606490fd5b865162461bcd60e51b815260048101899052602660248201527f4f6e6c7920746865206269646465722063616e20636c61696d207468656972206044820152651c99599d5b9960d21b6064820152608490fd5b9091611b248184611bf3565b6005811015611bdd57159081611bc7575b50611bbf576000918291604051611b7e81611b706020820194630b135d3f60e11b998a875260248401526040604484015260648301906112d6565b03601f19810183528261129a565b51915afa90611b8b6114a4565b82611bb3575b82611b9b57505090565b90915060208180518101031261021a57602001511490565b80516020149250611b91565b505050600190565b6001600160a01b03848116911614905038611b35565b634e487b7160e01b600052602160045260246000fd5b906041815114600014611c2157611c1d916020820151906060604084015193015160001a90611c2b565b9091565b5050600090600290565b9291907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311611cd45760ff16601b81141580611cc9575b611cbd579160809493916020936040519384528484015260408301526060820152600093849182805260015afa15611cb05781516001600160a01b03811615611caa579190565b50600190565b50604051903d90823e3d90fd5b50505050600090600490565b50601c811415611c63565b50505050600090600390565b9081602091031261021a5751600981101561021a5790565b604051631f27a4f360e11b80825260048201849052926020926001600160a01b031691908382602481865afa91821561022657600092611d9d575b506009821015611bdd576024849215956040519485938492835260048301525afa91821561022657600092611d80575b50506009811015611bdd578115611d78575090565b600191501490565b611d969250803d1061196657611958818361129a565b3880611d63565b611db5919250843d861161196657611958818361129a565b9038611d33565b5190811515820361021a5756fea26469706673582212203ba2cd0096b5bea52a790ac013bbc5836d50708912f42457eeb2881d3923bc6e64736f6c63430008110033000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000005

Deployed Bytecode

0x608080604052600436101561001357600080fd5b60003560e01c90816301495c1c146111f557508063042bc3de146111d757806306fdde031461114d57806312874688146110fc5780631626ba7e146110395780631c31f71014610fc05780633630593914610f4757806336ebdb3814610ecb57806338af3eed14610ea25780633be8ef3f14610e855780633e109a1914610e67578063715018a614610e0a57806386df10ff1461097b5780638da5cb5b146109525780638e6fad45146109345780638f859f421461090b57806393e54a6b14610891578063b296024d1461086d578063b97de68f14610834578063bc4cd08414610814578063d082fe17146107eb578063d317774e146103c9578063d50f1dec146103ab578063e45d5f3e1461035a578063e57066ca1461031a578063f2fde38b14610251578063fbfee876146102325763ff0bb0d91461015357600080fd5b3461021a57604036600319011261021a5761016c611284565b60405163013cf08b60e01b815260248035600483015290916101a0916001600160a01b039183918591829085165afa918215610226576000926101b5575b602083604051908152f35b90915082813d831161021f575b6101cc818361129a565b8101031261021a5760208201519081160361021a578061021261018060c06020940151926101fd6101408201611dbc565b5061020b6101608201611dbc565b5001611dbc565b5038806101aa565b600080fd5b503d6101c2565b6040513d6000823e3d90fd5b3461021a57600036600319011261021a57602060405163773594008152f35b3461021a57602036600319011261021a5761026a611284565b610272611374565b6001600160a01b039081169081156102c657600154826bffffffffffffffffffffffff60a01b821617600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b3461021a57604036600319011261021a57610353610336611284565b610345600260005414156113cc565b600260005560243590611514565b6001600055005b3461021a57602036600319011261021a577f77aed0985629485c13bfd593822543f4bab8881be176ee9e6025762ecaa253016040600435610399611374565b806006558151908082526020820152a1005b3461021a57600036600319011261021a576020600654604051908152f35b608036600319011261021a576103dd611284565b60ff604435166044350361021a576001600160401b03806064351161021a5736602360643501121561021a57606435600401351161021a573660246064356004013560643501011161021a57610438600260005414156113cc565b60026000556104516001600160a01b0382161515611418565b61045d60243582611cf8565b1561079c57600260ff604435161161076057600554341061071c5760018060a01b03811660005260086020526040600020602435600052602052604060002080549160038201549160ff60045460a01c16848181020481148515171561070657606490850204840180851161070657341061069c576104e260ff8460a81c1615611464565b604051600162f44f2760e01b031981526001600160a01b03831660048201526024803590820152602081604481305afa60009181610668575b50610578576105286114a4565b5060405162461bcd60e51b815260206004820152602160248201527f4661696c65642067657474696e672070726f706f73616c20656e6420626c6f636044820152606b60f81b6064820152608490fd5b34825560ff60a01b60443560a01b1660ff60a01b1933166affffffffffffffffffffff60a81b861617176003830155600182015560024391015560405160ff604435168152346020820152336040820152608060608201526064356004013560808201526064356004013560246064350160a0830137600060a060643560040135830101527f6c9461c1cfed7740d3f3f993b1adb6e4b413e353ad747031a6f0b17fb7726d306024359260018060a01b03169160a081601f19601f6064356004013501168101030190a36001600160a01b03169081610658576001600055005b610661916114d4565b8080610353565b9091506020813d602011610694575b816106846020938361129a565b8101031261021a5751908661051b565b3d9150610677565b608460405162461bcd60e51b815260206004820152604060248201527f4d7573742073656e64206d6f7265207468616e206c617374206269642062792060448201527f6d696e426964496e6372656d656e7450657263656e7461676520616d6f756e746064820152fd5b634e487b7160e01b600052601160045260246000fd5b606460405162461bcd60e51b815260206004820152602060248201527f4d7573742073656e64206174206c65617374206d696e42696420616d6f756e746044820152fd5b60405162461bcd60e51b8152602060048201526014602482015273496e76616c696420737570706f7274207479706560601b6044820152606490fd5b60405162461bcd60e51b815260206004820152602160248201527f50726f706f73616c206973206e6f742070656e64696e67206f722061637469766044820152606560f81b6064820152608490fd5b3461021a57600036600319011261021a576003546040516001600160a01b039091168152602090f35b3461021a57600036600319011261021a576020604051642e90edd0008152f35b3461021a57604036600319011261021a57610353610850611284565b61085f600260005414156113cc565b600260005560243590611977565b3461021a57600036600319011261021a57602060ff60045460a01c16604051908152f35b3461021a57602036600319011261021a577feeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad505796108cb611284565b6108d3611374565b600380546001600160a01b0319166001600160a01b03929092169182179055604080518281526020810192909252819081015b0390a1005b3461021a57600036600319011261021a576004546040516001600160a01b039091168152602090f35b3461021a57600036600319011261021a576020600754604051908152f35b3461021a57600036600319011261021a576001546040516001600160a01b039091168152602090f35b3461021a5760c036600319011261021a576004356001600160401b03811161021a573660238201121561021a5780600401356109b68161135d565b916109c4604051938461129a565b81835260208301906024829360051b8201019036821161021a57602401915b818310610dea57505050602435906001600160401b03821161021a573660238301121561021a57816004013590610a198261135d565b92610a27604051948561129a565b828452602084016024819460051b8301019136831161021a57602401905b828210610dda575050506044356001600160401b03811161021a573660238201121561021a57806004013590610a7a8261135d565b90610a88604051928361129a565b82825260208201906024829460051b8201019036821161021a5760248101925b828410610dac57505050506001600160401b036064351161021a5736602360643501121561021a576064356004013593610ae18561135d565b91610aef604051938461129a565b8583526020830180963660248260051b60643501011161021a57602460643501915b60248260051b60643501018310610d77575050506084356001600160401b03811161021a57610b44903690600401611316565b60a435979095906001600160a01b038916890361021a576004546001600160a01b03163303610d4157604051636d4ab48d60e11b815260a06004820152995160a48b018190528a9897969594939260c48a01929160005b818110610d1f575050506020906003198a84030160248b0152519182815201929060005b818110610d065750505060031987830301604488015251808252602082019160208260051b82010194926000915b838310610ccf57505050505060031985830301606486015251808252602082019160208260051b82010194926000915b838310610c9c57878703600319016084890152876020818b81600081610c438e8e6112d6565b03926001600160a01b03165af1801561022657600090610c69575b602090604051908152f35b506020813d602011610c94575b81610c836020938361129a565b8101031261021a5760209051610c5e565b3d9150610c76565b91939650919394602080610cbc600193601f198682030187528a516112d6565b9801930193019092889695949293610c1d565b919396979850919394602080610cf1600193601f198682030187528a516112d6565b98019301930190928a98979695949293610bed565b825185528b995060209485019490920191600101610bbf565b82516001600160a01b031685528d9b5060209485019490920191600101610b9b565b60405162461bcd60e51b815260206004820152600e60248201526d5375626d6974746572206f6e6c7960901b6044820152606490fd5b8235906001600160401b03821161021a5760208091610d9f6024948536916064350101611316565b8152019301929050610b11565b6001600160401b0384351161021a5760208091610dcf3660248835870101611316565b815201930192610aa8565b8135815260209182019101610a45565b82356001600160a01b038116810361021a578152602092830192016109e3565b3461021a57600036600319011261021a57610e23611374565b600180546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461021a57600036600319011261021a576020600554604051908152f35b3461021a57600036600319011261021a576020604051618ca08152f35b3461021a57600036600319011261021a576002546040516001600160a01b039091168152602090f35b3461021a57602036600319011261021a5760043560ff81169081810361021a577f0ade66b49969898cbfa1f0d478364f2552fda679597b9a19c76f1cf4207a287691604091610f18611374565b6004805460ff60a01b191660a092831b60ff60a01b1617908190558351911c60ff1681526020810191909152a1005b3461021a57602036600319011261021a577f0b58a643e259107d3f251effee8248c1dc89b4530c88dd514960273e8961e481610f81611284565b610f89611374565b600480546001600160a01b0319166001600160a01b0392909216918217905560408051828152602081019290925281908101610906565b3461021a57602036600319011261021a577f6b73ba97679a45fa03de9ae7002a53163e4c0c6cdcb3ae225dd5fffd555181f2610ffa611284565b611002611374565b600280546001600160a01b0319166001600160a01b0392909216918217905560408051828152602081019290925281908101610906565b3461021a57604036600319011261021a576024356001600160401b03811161021a57611069903690600401611316565b6003546000916001600160a01b039091169081156110b75761108e9160043590611b18565b6110a9575b6040516001600160e01b03199091168152602090f35b50630b135d3f60e11b611093565b60405162461bcd60e51b815260206004820152601760248201527f417070726f766564207369676e6572206e6f74207365740000000000000000006044820152606490fd5b3461021a57602036600319011261021a577fd4420e2ede06c8ec744d7935828ce668b6901be78f6512ed5d9f84dd9564f8df604060043561113b611374565b806005558151908082526020820152a1005b3461021a57600036600319011261021a5760405160408101908082106001600160401b038311176111c1576111bd91604052601781527f46656465726174696f6e2044656c65676174652042696400000000000000000060208201526040519182916020835260208301906112d6565b0390f35b634e487b7160e01b600052604160045260246000fd5b3461021a57600036600319011261021a57602060405162030d408152f35b3461021a57604036600319011261021a5760e09060ff6001600160a01b038061121c611284565b16600052600860205260406000206024356000526020526040600020908154916001810154600360028301549201549386526020860152604085015281166060840152818160a01c166080840152818160a81c16151560a084015260b01c16151560c0820152f35b600435906001600160a01b038216820361021a57565b90601f801991011681019081106001600160401b038211176111c157604052565b6001600160401b0381116111c157601f01601f191660200190565b919082519283825260005b848110611302575050826000602080949584010152601f8019910116010190565b6020818301810151848301820152016112e1565b81601f8201121561021a5780359061132d826112bb565b9261133b604051948561129a565b8284526020838301011161021a57816000926020809301838601378301015290565b6001600160401b0381116111c15760051b60200190565b6001546001600160a01b0316330361138857565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b156113d357565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b1561141f57565b60405162461bcd60e51b815260206004820152601860248201527f44414f2061646472657373206973206e6f742076616c696400000000000000006044820152606490fd5b1561146b57565b60405162461bcd60e51b8152602060048201526011602482015270159bdd1948185b1c9958591e4818d85cdd607a1b6044820152606490fd5b3d156114cf573d906114b5826112bb565b916114c3604051938461129a565b82523d6000602084013e565b606090565b8147106115065760008080808585620186a0f1156114f0575050565b601691600b916000526073825360ff602053f050565b63b12d13eb6000526004601cfd5b905a6001600160a01b0392831692906000611530851515611418565b604091825191631f27a4f360e11b83526004958087850152602096602494888187818d5afa90811561196d578491611940575b50600981101561192e576001036118e1578883526008885285832082845288528583209485541515806118d2575b15611886576001860154600654810390811161187457431061180c57600386019182546115c460ff8260a81c1615611464565b43600289015410156117ac5760ff60a81b1916600160a81b178084558b3b156117a857908560ff60448e9594838d519788948593630acf027160e31b85528c8986015260a01c16888401525af1801561179e5761176f575b50505054977f530751216f7b1ed8586c79759d3c12ea7c29565d484512af313c3787d7afdac2606086549a8989519160ff8160a01c1683528d8d8401521689820152a347801561176557818080926007548b81111560001461175d57955b642e90edd00048811061175257506377359400485b013a81106117485750618ca03a915b5a90030162030d408082116117405750905b02908082116117385750995b8a86019080821161173157505b8180808084325af1966116da6114a4565b5054038098600254165af1946116ee6114a4565b5083519687528601521515908401526060830152151560808201527fdcea780a1dde82a82fb04cade0bc656a9011b7c533ba9c0b42021464d0531f7a60a03292a2565b90506116c9565b9050996116bc565b9050906116b0565b618ca0909161169e565b63773594009061168f565b508a9561167a565b5050505050505050565b6001600160401b03839694961161178d57505086529138808061161c565b634e487b7160e01b84526041905282fd5b89513d88823e3d90fd5b8580fd5b5060366084928b8a519362461bcd60e51b85528401528201527f566f74652063616e6e6f74206265206361737420696e207468652073616d6520604482015275626c6f636b207468652062696420776173206d61646560501b6064820152fd5b865162461bcd60e51b8152918201899052603a908201527f566f74652063616e206f6e6c79206265206361737420647572696e672074686560448201527f2070726f706f73616c20657865637574696f6e2077696e646f770000000000006064820152608490fd5b50634e487b7160e01b84526011825283fd5b865162461bcd60e51b81529182018990526021908201527f426964206e6f74206f66666572656420666f7220746869732070726f706f73616044820152601b60fa1b6064820152608490fd5b50876003870154161515611591565b855162461bcd60e51b81529081018890526022818601527f566f74696e6720697320636c6f73656420666f7220746869732070726f706f73604482015261185b60f21b6064820152608490fd5b634e487b7160e01b8452602182528584fd5b6119609150893d8b11611966575b611958818361129a565b810190611ce0565b38611563565b503d61194e565b87513d86823e3d90fd5b9060018060a01b03808316600052602092600884526040928360002081600052855283600020926003840191825491821693843303611ac55760ff8360b01c16611a8a576119cb60ff8460a81c1615611464565b479554809610611a4657906119df91611cf8565b15611a2857845162461bcd60e51b815260048101879052601860248201527f526566756e642063616e6e6f7420626520636c61696d656400000000000000006044820152606490fd5b60ff60b01b1916600160b01b179055611a4493509091506114d4565b565b865162461bcd60e51b815260048101899052601e60248201527f496e73756666696369656e742062616c616e636520746f20726566756e6400006044820152606490fd5b865162461bcd60e51b8152600481018990526014602482015273109a5908185b1c9958591e481c99599d5b99195960621b6044820152606490fd5b865162461bcd60e51b815260048101899052602660248201527f4f6e6c7920746865206269646465722063616e20636c61696d207468656972206044820152651c99599d5b9960d21b6064820152608490fd5b9091611b248184611bf3565b6005811015611bdd57159081611bc7575b50611bbf576000918291604051611b7e81611b706020820194630b135d3f60e11b998a875260248401526040604484015260648301906112d6565b03601f19810183528261129a565b51915afa90611b8b6114a4565b82611bb3575b82611b9b57505090565b90915060208180518101031261021a57602001511490565b80516020149250611b91565b505050600190565b6001600160a01b03848116911614905038611b35565b634e487b7160e01b600052602160045260246000fd5b906041815114600014611c2157611c1d916020820151906060604084015193015160001a90611c2b565b9091565b5050600090600290565b9291907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311611cd45760ff16601b81141580611cc9575b611cbd579160809493916020936040519384528484015260408301526060820152600093849182805260015afa15611cb05781516001600160a01b03811615611caa579190565b50600190565b50604051903d90823e3d90fd5b50505050600090600490565b50601c811415611c63565b50505050600090600390565b9081602091031261021a5751600981101561021a5790565b604051631f27a4f360e11b80825260048201849052926020926001600160a01b031691908382602481865afa91821561022657600092611d9d575b506009821015611bdd576024849215956040519485938492835260048301525afa91821561022657600092611d80575b50506009811015611bdd578115611d78575090565b600191501490565b611d969250803d1061196657611958818361129a565b3880611d63565b611db5919250843d861161196657611958818361129a565b9038611d33565b5190811515820361021a5756fea26469706673582212203ba2cd0096b5bea52a790ac013bbc5836d50708912f42457eeb2881d3923bc6e64736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000005

-----Decoded View---------------
Arg [0] : _castWindow (uint256): 150
Arg [1] : _baseTip (uint256): 50000000000000000
Arg [2] : _minBid (uint256): 100000000000000000
Arg [3] : _minBidIncrementPercentage (uint8): 5

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000096
Arg [1] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [2] : 000000000000000000000000000000000000000000000000016345785d8a0000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000005


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.