Contract 0x007A66A2a13415DB3613C1a4dd1C942A285902d1 9

Contract Overview

Balance:
0 ETH

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x14a80a28f2181cca5185b9535700aeb532f2297ef91b55779d4bad1649992ac0Register Auction...278255792023-06-24 1:47:1489 days 8 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.0000087 0.10388
0x67b97b6ae0228d291161bb7763f8a6e248326812dd99462ba003b5c2b013561eRegister Auction...278255542023-06-24 1:47:0789 days 8 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.00000838 0.1
0x00973f3fb596ee5440e2ebf2751a853fad9362f401787260b13603f3b14aeed4Register Auction...195896082023-05-12 19:19:52131 days 14 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000008380.1
0x0deac568fdf4b733a6ad44ddc4e651bd4c9723e6725cc932f17f9298589175a6Register Auction...195895972023-05-12 19:19:45131 days 14 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000008380.1
0xec3842a5e01049f4ae80bd6ac524a1a8a576910a6f758c67bb84d3a3c2f6b9fdRegister Auction...189285542023-05-05 14:43:57138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000734450.1
0x87de6ea4b1473bac4107fcafd73b7e1ef93c84ca80f50b51b393371294dd3570Register Auction...189285362023-05-05 14:43:50138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000734450.1
0xf92929cc7b17da3a2584f4241531268d3f14701ccf499e4720b2765eb3f224acRegister Auction...189285242023-05-05 14:43:43138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000711620.1
0xd16ea14135fb77e0cb1a3bdae5b84d3ea6e1509f0d581e62d791b33aa0f6e851Register Auction...189285162023-05-05 14:43:36138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000711620.1
0xb241ae208ab894890df8706e9d888aaa8d5e04f5e5d2f95130332ecf2d6253d9Register Auction...189281782023-05-05 14:39:01138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000711620.1
0xfd9ea4309436c1139555b7e2592127bba04793f3c7909e1feb0e3ebed28221d8Register Auction...189281672023-05-05 14:38:54138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000711620.1
0xe786f271f3cb1e99790509ca7b1f550610c5cc523cc7aba182c0b10bec7099b0Register Auction...189274152023-05-05 14:29:05138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000907670.1
0x22dac1fcb37316afef78d285066f35f90fb1b574b6963ff991c49ae950390313Register Auction...189274062023-05-05 14:28:58138 days 19 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000907670.1
0x2a60bad40d6481dac989e0bfb65bd43f731c1f046ad4cbc3710518b260127c5dRegister Auction...19310712022-11-28 18:29:37296 days 15 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000016660.1
0x656f3166b893f52f958a3e46fdf16e60a3983f326acded7b0440fcbbf22c762aRegister Auction...19310672022-11-28 18:29:30296 days 15 hrs ago0x1a5309f208f161a393e8b5a253de8ab894a67188 IN  0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH0.000018370.1
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xc35aec4cba8cb13836d3814ea0432ba2b962efa818dd3dd176be2bb6adaa2c0f281559672023-06-25 12:26:4687 days 21 hrs ago 0x007f7735baf391e207e3aa380bb53c4bd9a5fed6 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xc35aec4cba8cb13836d3814ea0432ba2b962efa818dd3dd176be2bb6adaa2c0f281559672023-06-25 12:26:4687 days 21 hrs ago 0x007f7735baf391e207e3aa380bb53c4bd9a5fed6 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xaea131fd421450b8005a6b7e2e29134e7cf2c0a3992aea5e2adcb6b02252c839281533792023-06-25 12:10:0887 days 21 hrs ago 0xf75da09c8538b7afe8b9d3adc1d626da5d33467f 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x0f726d48c9a03dc05fa986e15a4e2a68ae2ba7ef9a14dab465fa41148cb64b16278258142023-06-24 1:49:1989 days 7 hrs ago 0xf75da09c8538b7afe8b9d3adc1d626da5d33467f 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x14a80a28f2181cca5185b9535700aeb532f2297ef91b55779d4bad1649992ac0278255792023-06-24 1:47:1489 days 8 hrs ago 0x007a66a2a13415db3613c1a4dd1c942a285902d1 0x007a0f48a4e3d74ab4234adf9ea9eb32f87b4b140 ETH
0x67b97b6ae0228d291161bb7763f8a6e248326812dd99462ba003b5c2b013561e278255542023-06-24 1:47:0789 days 8 hrs ago 0x007a66a2a13415db3613c1a4dd1c942a285902d1 0x007a0f48a4e3d74ab4234adf9ea9eb32f87b4b140 ETH
0x45e03ff23518ba984036c4cda7d96d93e069ada41d2923fce143359975ca7ed0231605122023-05-31 9:11:39113 days 36 mins ago 0x91d20a4d57944618500bdce4d94d14c15ef12720 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x45e03ff23518ba984036c4cda7d96d93e069ada41d2923fce143359975ca7ed0231605122023-05-31 9:11:39113 days 36 mins ago 0xf70fdaae514a8b48b83cada51c0847b46bb698bd 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x0c326580c2168ad06dd9af8d7e67fff756d8d094dd836aef975f7dea8ac366bf231603942023-05-31 9:10:45113 days 37 mins ago 0x91d20a4d57944618500bdce4d94d14c15ef12720 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x0c326580c2168ad06dd9af8d7e67fff756d8d094dd836aef975f7dea8ac366bf231603942023-05-31 9:10:45113 days 37 mins ago 0xf705da9476a172408e1b94b2a7b2ef595a91c29b 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xe53ee47c4390dd6920f6a3625882a76d55da3f3292c9c422ee1e73f7f92cd642203303312023-05-18 10:30:55125 days 23 hrs ago 0x007f7735baf391e207e3aa380bb53c4bd9a5fed6 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xe53ee47c4390dd6920f6a3625882a76d55da3f3292c9c422ee1e73f7f92cd642203303312023-05-18 10:30:55125 days 23 hrs ago 0x007f7735baf391e207e3aa380bb53c4bd9a5fed6 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xcff57c986ae1d61870627e49c3bc41f3a202cc331ffd77d98181122cd60a102d203291922023-05-18 10:20:25125 days 23 hrs ago 0xf7f9a96cdbfefd70bda14a8f30ec503b16bce9b1 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xf390298bc378c1a38d3e28638c5e5420fb141a227061bb5fbfab4cfc87266e77199027322023-05-15 14:17:18128 days 19 hrs ago 0x91d20a4d57944618500bdce4d94d14c15ef12720 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xf390298bc378c1a38d3e28638c5e5420fb141a227061bb5fbfab4cfc87266e77199027322023-05-15 14:17:18128 days 19 hrs ago 0xfe0fda2acb13249099e5edac64439ac76c7ef4b6 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x0154c76c38da6f227ca2051bd6966cd34353721fe027d134afe62d35c135deae199026202023-05-15 14:16:12128 days 19 hrs ago 0x91d20a4d57944618500bdce4d94d14c15ef12720 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x0154c76c38da6f227ca2051bd6966cd34353721fe027d134afe62d35c135deae199026202023-05-15 14:16:12128 days 19 hrs ago 0xf70fdaae514a8b48b83cada51c0847b46bb698bd 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xfbf8dff15ac9bd991132b5bfae1fb66cd5790f51420a9e3430152c6f954f77b3199024682023-05-15 14:14:49128 days 19 hrs ago 0x91d20a4d57944618500bdce4d94d14c15ef12720 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0xfbf8dff15ac9bd991132b5bfae1fb66cd5790f51420a9e3430152c6f954f77b3199024682023-05-15 14:14:49128 days 19 hrs ago 0xfe05da9fffc72027c26e2327a9e6339670cd1b90 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x22867e25d02c1cc0ec88223fdce1c160ec0ac9a13cc0e00f53b6811736d92e0f199023612023-05-15 14:13:43128 days 19 hrs ago 0x91d20a4d57944618500bdce4d94d14c15ef12720 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x22867e25d02c1cc0ec88223fdce1c160ec0ac9a13cc0e00f53b6811736d92e0f199023612023-05-15 14:13:43128 days 19 hrs ago 0xf705da9476a172408e1b94b2a7b2ef595a91c29b 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x66926ac8b5358f9aa9ee209a380cd3cdaee2179021508bc15c043d9535cd3848199022672023-05-15 14:12:39128 days 19 hrs ago 0xfef9a53aa10ce2c9ab6519aee7df82767f504f55 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x8f59af7c57057cd543f4184ad27ce0e128151cf803d0e8bc6180caac3726a304199021632023-05-15 14:11:30128 days 19 hrs ago 0xf7f9a96cdbfefd70bda14a8f30ec503b16bce9b1 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x78921e90b8be2e2184fe8e280dbb44f3a0faba25c1b256f3ab529b7f62803e75199020772023-05-15 14:10:37128 days 19 hrs ago 0xfe5da6ad5720237d19229e7416791d390255e9aa 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
0x038fcda219eeae680cfe8e590a81ebc919fdc0dff09b795abb31e4bec95807d6199019582023-05-15 14:09:28128 days 19 hrs ago 0xf75dafffaf63f5d935f8a481ee827d68974fd992 0x007a66a2a13415db3613c1a4dd1c942a285902d10 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BondAggregator

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 100000 runs

Other Settings:
default evmVersion
File 1 of 7 : Auth.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
    event OwnerUpdated(address indexed user, address indexed newOwner);

    event AuthorityUpdated(address indexed user, Authority indexed newAuthority);

    address public owner;

    Authority public authority;

    constructor(address _owner, Authority _authority) {
        owner = _owner;
        authority = _authority;

        emit OwnerUpdated(msg.sender, _owner);
        emit AuthorityUpdated(msg.sender, _authority);
    }

    modifier requiresAuth() {
        require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");

        _;
    }

    function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
        Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.

        // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
        // aware that this makes protected functions uncallable even to the owner if the authority is out of order.
        return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
    }

    function setAuthority(Authority newAuthority) public virtual {
        // We check if the caller is the owner first because we want to ensure they can
        // always swap out the authority even if it's reverting or using up a lot of gas.
        require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));

        authority = newAuthority;

        emit AuthorityUpdated(msg.sender, newAuthority);
    }

    function setOwner(address newOwner) public virtual requiresAuth {
        owner = newOwner;

        emit OwnerUpdated(msg.sender, newOwner);
    }
}

/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
    function canCall(
        address user,
        address target,
        bytes4 functionSig
    ) external view returns (bool);
}

File 2 of 7 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*///////////////////////////////////////////////////////////////
                                  EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*///////////////////////////////////////////////////////////////
                             METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*///////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*///////////////////////////////////////////////////////////////
                             EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    bytes32 public constant PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*///////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*///////////////////////////////////////////////////////////////
                              ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*///////////////////////////////////////////////////////////////
                              EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            bytes32 digest = keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    DOMAIN_SEPARATOR(),
                    keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                )
            );

            address recoveredAddress = ecrecover(digest, v, r, s);

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*///////////////////////////////////////////////////////////////
                       INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 3 of 7 : BondAggregator.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.15;

import {ERC20} from "solmate/tokens/ERC20.sol";
import {Auth, Authority} from "solmate/auth/Auth.sol";

import {IBondAggregator} from "./interfaces/IBondAggregator.sol";
import {IBondTeller} from "./interfaces/IBondTeller.sol";
import {IBondAuctioneer} from "./interfaces/IBondAuctioneer.sol";

import {FullMath} from "./lib/FullMath.sol";

/// @title Bond Aggregator
/// @notice Bond Aggregator Contract
/// @dev Bond Protocol is a permissionless system to create Olympus-style bond markets
///      for any token pair. The markets do not require maintenance and will manage
///      bond prices based on activity. Bond issuers create BondMarkets that pay out
///      a Payout Token in exchange for deposited Quote Tokens. Users can purchase
///      future-dated Payout Tokens with Quote Tokens at the current market price and
///      receive Bond Tokens to represent their position while their bond vests.
///      Once the Bond Tokens vest, they can redeem it for the Quote Tokens.
///
/// @dev The Aggregator contract keeps a unique set of market IDs across multiple
///      Tellers and Auctioneers. Additionally, it aggregates market data from
///      multiple Auctioneers in convenient view functions for front-end interfaces.
///      The Aggregator contract should be deployed first since Tellers, Auctioneers, and
///      Callbacks all require it in their constructors.
///
/// @author Oighty, Zeus, Potted Meat, indigo
contract BondAggregator is IBondAggregator, Auth {
    using FullMath for uint256;

    /* ========== ERRORS ========== */
    error Aggregator_OnlyAuctioneer();
    error Aggregator_AlreadyRegistered(address auctioneer_);
    error Aggregator_InvalidParams();

    /* ========== STATE VARIABLES ========== */

    /// @notice Counter for bond markets on approved auctioneers
    uint256 public marketCounter;

    /// @notice Approved auctioneers
    IBondAuctioneer[] public auctioneers;
    mapping(address => bool) internal _whitelist;

    /// @notice Auctioneer for Market ID
    mapping(uint256 => IBondAuctioneer) public marketsToAuctioneers;

    /// @notice Market IDs for payout token
    mapping(address => uint256[]) public marketsForPayout;

    /// @notice Market IDs for quote token
    mapping(address => uint256[]) public marketsForQuote;

    // A 'vesting' param longer than 50 years is considered a timestamp for fixed expiry.
    uint48 private constant MAX_FIXED_TERM = 52 weeks * 50;

    constructor(address guardian_, Authority authority_) Auth(guardian_, authority_) {}

    /// @inheritdoc IBondAggregator
    function registerAuctioneer(IBondAuctioneer auctioneer_) external requiresAuth {
        // Restricted to authorized addresses

        // Check that the auctioneer is not already registered
        if (_whitelist[address(auctioneer_)])
            revert Aggregator_AlreadyRegistered(address(auctioneer_));

        // Add the auctioneer to the whitelist
        auctioneers.push(auctioneer_);
        _whitelist[address(auctioneer_)] = true;
    }

    /// @inheritdoc IBondAggregator
    function registerMarket(ERC20 payoutToken_, ERC20 quoteToken_)
        external
        override
        returns (uint256 marketId)
    {
        if (!_whitelist[msg.sender]) revert Aggregator_OnlyAuctioneer();
        if (address(payoutToken_) == address(0) || address(quoteToken_) == address(0))
            revert Aggregator_InvalidParams();
        marketId = marketCounter;
        marketsToAuctioneers[marketId] = IBondAuctioneer(msg.sender);
        marketsForPayout[address(payoutToken_)].push(marketId);
        marketsForQuote[address(quoteToken_)].push(marketId);
        ++marketCounter;
    }

    /* ========== VIEW FUNCTIONS ========== */

    /// @inheritdoc IBondAggregator
    function getAuctioneer(uint256 id_) external view returns (IBondAuctioneer) {
        return marketsToAuctioneers[id_];
    }

    /// @inheritdoc IBondAggregator
    function marketPrice(uint256 id_) public view override returns (uint256) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.marketPrice(id_);
    }

    /// @inheritdoc IBondAggregator
    function marketScale(uint256 id_) external view override returns (uint256) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.marketScale(id_);
    }

    /// @inheritdoc IBondAggregator
    function payoutFor(
        uint256 amount_,
        uint256 id_,
        address referrer_
    ) public view override returns (uint256) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.payoutFor(amount_, id_, referrer_);
    }

    /// @inheritdoc IBondAggregator
    function maxAmountAccepted(uint256 id_, address referrer_) external view returns (uint256) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.maxAmountAccepted(id_, referrer_);
    }

    /// @inheritdoc IBondAggregator
    function isInstantSwap(uint256 id_) external view returns (bool) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.isInstantSwap(id_);
    }

    /// @inheritdoc IBondAggregator
    function isLive(uint256 id_) public view override returns (bool) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.isLive(id_);
    }

    /// @inheritdoc IBondAggregator
    function liveMarketsBetween(uint256 firstIndex_, uint256 lastIndex_)
        external
        view
        override
        returns (uint256[] memory)
    {
        uint256 count;
        for (uint256 i = firstIndex_; i < lastIndex_; ++i) {
            if (isLive(i)) ++count;
        }

        uint256[] memory ids = new uint256[](count);
        count = 0;
        for (uint256 i = firstIndex_; i < lastIndex_; ++i) {
            if (isLive(i)) {
                ids[count] = i;
                ++count;
            }
        }
        return ids;
    }

    /// @inheritdoc IBondAggregator
    function liveMarketsFor(address token_, bool isPayout_)
        public
        view
        override
        returns (uint256[] memory)
    {
        uint256[] memory mkts;

        mkts = isPayout_ ? marketsForPayout[token_] : marketsForQuote[token_];

        uint256 count;
        uint256 len = mkts.length;

        for (uint256 i; i < len; ++i) {
            if (isLive(mkts[i])) ++count;
        }

        uint256[] memory ids = new uint256[](count);
        count = 0;

        for (uint256 i; i < len; ++i) {
            if (isLive(mkts[i])) {
                ids[count] = mkts[i];
                ++count;
            }
        }

        return ids;
    }

    /// @inheritdoc IBondAggregator
    function marketsFor(address payout_, address quote_) public view returns (uint256[] memory) {
        uint256[] memory forPayout = liveMarketsFor(payout_, true);
        uint256 count;

        ERC20 quoteToken;
        IBondAuctioneer auctioneer;
        uint256 len = forPayout.length;
        for (uint256 i; i < len; ++i) {
            auctioneer = marketsToAuctioneers[forPayout[i]];
            (, , , quoteToken, , ) = auctioneer.getMarketInfoForPurchase(forPayout[i]);
            if (isLive(forPayout[i]) && address(quoteToken) == quote_) ++count;
        }

        uint256[] memory ids = new uint256[](count);
        count = 0;

        for (uint256 i; i < len; ++i) {
            auctioneer = marketsToAuctioneers[forPayout[i]];
            (, , , quoteToken, , ) = auctioneer.getMarketInfoForPurchase(forPayout[i]);
            if (isLive(forPayout[i]) && address(quoteToken) == quote_) {
                ids[count] = forPayout[i];
                ++count;
            }
        }

        return ids;
    }

    /// @inheritdoc IBondAggregator
    function findMarketFor(
        address payout_,
        address quote_,
        uint256 amountIn_,
        uint256 minAmountOut_,
        uint256 maxExpiry_
    ) external view returns (uint256) {
        uint256[] memory ids = marketsFor(payout_, quote_);
        uint256 len = ids.length;
        // uint256[] memory payouts = new uint256[](len);

        uint256 highestOut;
        uint256 id = type(uint256).max; // set to max so an empty set doesn't return 0, the first index
        uint48 vesting;
        uint256 maxPayout;
        IBondAuctioneer auctioneer;
        for (uint256 i; i < len; ++i) {
            auctioneer = marketsToAuctioneers[ids[i]];
            (, , , , vesting, maxPayout) = auctioneer.getMarketInfoForPurchase(ids[i]);

            uint256 expiry = (vesting <= MAX_FIXED_TERM) ? block.timestamp + vesting : vesting;

            if (expiry <= maxExpiry_) {
                if (minAmountOut_ <= maxPayout) {
                    try auctioneer.payoutFor(amountIn_, ids[i], address(0)) returns (
                        uint256 payout
                    ) {
                        if (payout > highestOut && payout >= minAmountOut_) {
                            highestOut = payout;
                            id = ids[i];
                        }
                    } catch {
                        // fail silently and try the next market
                    }
                }
            }
        }

        return id;
    }

    /// @inheritdoc IBondAggregator
    function liveMarketsBy(
        address owner_,
        uint256 firstIndex_,
        uint256 lastIndex_
    ) external view returns (uint256[] memory) {
        uint256 count;
        IBondAuctioneer auctioneer;
        for (uint256 i = firstIndex_; i < lastIndex_; ++i) {
            auctioneer = marketsToAuctioneers[i];
            if (auctioneer.isLive(i) && auctioneer.ownerOf(i) == owner_) {
                ++count;
            }
        }

        uint256[] memory ids = new uint256[](count);
        count = 0;
        for (uint256 j = firstIndex_; j < lastIndex_; ++j) {
            auctioneer = marketsToAuctioneers[j];
            if (auctioneer.isLive(j) && auctioneer.ownerOf(j) == owner_) {
                ids[count] = j;
                ++count;
            }
        }

        return ids;
    }

    /// @inheritdoc IBondAggregator
    function getTeller(uint256 id_) external view returns (IBondTeller) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.getTeller();
    }

    /// @inheritdoc IBondAggregator
    function currentCapacity(uint256 id_) external view returns (uint256) {
        IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
        return auctioneer.currentCapacity(id_);
    }
}

File 4 of 7 : IBondAggregator.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.0;

import {ERC20} from "solmate/tokens/ERC20.sol";
import {IBondAuctioneer} from "../interfaces/IBondAuctioneer.sol";
import {IBondTeller} from "../interfaces/IBondTeller.sol";

interface IBondAggregator {
    /// @notice             Register a auctioneer with the aggregator
    /// @notice             Only Guardian
    /// @param auctioneer_  Address of the Auctioneer to register
    /// @dev                A auctioneer must be registered with an aggregator to create markets
    function registerAuctioneer(IBondAuctioneer auctioneer_) external;

    /// @notice             Register a new market with the aggregator
    /// @notice             Only registered depositories
    /// @param payoutToken_ Token to be paid out by the market
    /// @param quoteToken_  Token to be accepted by the market
    /// @param marketId     ID of the market being created
    function registerMarket(ERC20 payoutToken_, ERC20 quoteToken_)
        external
        returns (uint256 marketId);

    /// @notice     Get the auctioneer for the provided market ID
    /// @param id_  ID of Market
    function getAuctioneer(uint256 id_) external view returns (IBondAuctioneer);

    /// @notice             Calculate current market price of payout token in quote tokens
    /// @dev                Accounts for debt and control variable decay since last deposit (vs _marketPrice())
    /// @param id_          ID of market
    /// @return             Price for market (see the specific auctioneer for units)
    //
    // if price is below minimum price, minimum price is returned
    // this is enforced on deposits by manipulating total debt (see _decay())
    function marketPrice(uint256 id_) external view returns (uint256);

    /// @notice             Scale value to use when converting between quote token and payout token amounts with marketPrice()
    /// @param id_          ID of market
    /// @return             Scaling factor for market in configured decimals
    function marketScale(uint256 id_) external view returns (uint256);

    /// @notice             Payout due for amount of quote tokens
    /// @dev                Accounts for debt and control variable decay so it is up to date
    /// @param amount_      Amount of quote tokens to spend
    /// @param id_          ID of market
    /// @param referrer_    Address of referrer, used to get fees to calculate accurate payout amount.
    ///                     Inputting the zero address will take into account just the protocol fee.
    /// @return             amount of payout tokens to be paid
    function payoutFor(
        uint256 amount_,
        uint256 id_,
        address referrer_
    ) external view returns (uint256);

    /// @notice             Returns maximum amount of quote token accepted by the market
    /// @param id_          ID of market
    /// @param referrer_    Address of referrer, used to get fees to calculate accurate payout amount.
    ///                     Inputting the zero address will take into account just the protocol fee.
    function maxAmountAccepted(uint256 id_, address referrer_) external view returns (uint256);

    /// @notice             Does market send payout immediately
    /// @param id_          Market ID to search for
    function isInstantSwap(uint256 id_) external view returns (bool);

    /// @notice             Is a given market accepting deposits
    /// @param id_          ID of market
    function isLive(uint256 id_) external view returns (bool);

    /// @notice             Returns array of active market IDs within a range
    /// @dev                Should be used if length exceeds max to query entire array
    function liveMarketsBetween(uint256 firstIndex_, uint256 lastIndex_)
        external
        view
        returns (uint256[] memory);

    /// @notice             Returns an array of all active market IDs for a given quote token
    /// @param token_       Address of token to query by
    /// @param isPayout_    If true, search by payout token, else search for quote token
    function liveMarketsFor(address token_, bool isPayout_)
        external
        view
        returns (uint256[] memory);

    /// @notice             Returns an array of all active market IDs for a given owner
    /// @param owner_       Address of owner to query by
    /// @param firstIndex_  Market ID to start at
    /// @param lastIndex_   Market ID to end at (non-inclusive)
    function liveMarketsBy(
        address owner_,
        uint256 firstIndex_,
        uint256 lastIndex_
    ) external view returns (uint256[] memory);

    /// @notice             Returns an array of all active market IDs for a given payout and quote token
    /// @param payout_      Address of payout token
    /// @param quote_       Address of quote token
    function marketsFor(address payout_, address quote_) external view returns (uint256[] memory);

    /// @notice                 Returns the market ID with the highest current payoutToken payout for depositing quoteToken
    /// @param payout_          Address of payout token
    /// @param quote_           Address of quote token
    /// @param amountIn_        Amount of quote tokens to deposit
    /// @param minAmountOut_    Minimum amount of payout tokens to receive as payout
    /// @param maxExpiry_       Latest acceptable vesting timestamp for bond
    ///                         Inputting the zero address will take into account just the protocol fee.
    function findMarketFor(
        address payout_,
        address quote_,
        uint256 amountIn_,
        uint256 minAmountOut_,
        uint256 maxExpiry_
    ) external view returns (uint256 id);

    /// @notice             Returns the Teller that services the market ID
    function getTeller(uint256 id_) external view returns (IBondTeller);

    /// @notice             Returns current capacity of a market
    function currentCapacity(uint256 id_) external view returns (uint256);
}

File 5 of 7 : IBondAuctioneer.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.0;

import {ERC20} from "solmate/tokens/ERC20.sol";
import {IBondTeller} from "../interfaces/IBondTeller.sol";
import {IBondAggregator} from "../interfaces/IBondAggregator.sol";

interface IBondAuctioneer {
    /// @notice                 Creates a new bond market
    /// @param params_          Configuration data needed for market creation, encoded in a bytes array
    /// @dev                    See specific auctioneer implementations for details on encoding the parameters.
    /// @return id              ID of new bond market
    function createMarket(bytes memory params_) external returns (uint256);

    /// @notice                 Disable existing bond market
    /// @notice                 Must be market owner
    /// @param id_              ID of market to close
    function closeMarket(uint256 id_) external;

    /// @notice                 Exchange quote tokens for a bond in a specified market
    /// @notice                 Must be teller
    /// @param id_              ID of the Market the bond is being purchased from
    /// @param amount_          Amount to deposit in exchange for bond (after fee has been deducted)
    /// @param minAmountOut_    Minimum acceptable amount of bond to receive. Prevents frontrunning
    /// @return payout          Amount of payout token to be received from the bond
    function purchaseBond(
        uint256 id_,
        uint256 amount_,
        uint256 minAmountOut_
    ) external returns (uint256 payout);

    /// @notice                         Set market intervals to different values than the defaults
    /// @notice                         Must be market owner
    /// @dev                            Changing the intervals could cause markets to behave in unexpected way
    ///                                 tuneInterval should be greater than tuneAdjustmentDelay
    /// @param id_                      Market ID
    /// @param intervals_               Array of intervals (3)
    ///                                 1. Tune interval - Frequency of tuning
    ///                                 2. Tune adjustment delay - Time to implement downward tuning adjustments
    ///                                 3. Debt decay interval - Interval over which debt should decay completely
    function setIntervals(uint256 id_, uint32[3] calldata intervals_) external;

    /// @notice                      Designate a new owner of a market
    /// @notice                      Must be market owner
    /// @dev                         Doesn't change permissions until newOwner calls pullOwnership
    /// @param id_                   Market ID
    /// @param newOwner_             New address to give ownership to
    function pushOwnership(uint256 id_, address newOwner_) external;

    /// @notice                      Accept ownership of a market
    /// @notice                      Must be market newOwner
    /// @dev                         The existing owner must call pushOwnership prior to the newOwner calling this function
    /// @param id_                   Market ID
    function pullOwnership(uint256 id_) external;

    /// @notice             Set the auctioneer defaults
    /// @notice             Must be policy
    /// @param defaults_    Array of default values
    ///                     1. Tune interval - amount of time between tuning adjustments
    ///                     2. Tune adjustment delay - amount of time to apply downward tuning adjustments
    ///                     3. Minimum debt decay interval - minimum amount of time to let debt decay to zero
    ///                     4. Minimum deposit interval - minimum amount of time to wait between deposits
    ///                     5. Minimum market duration - minimum amount of time a market can be created for
    ///                     6. Minimum debt buffer - the minimum amount of debt over the initial debt to trigger a market shutdown
    /// @dev                The defaults set here are important to avoid edge cases in market behavior, e.g. a very short market reacts doesn't tune well
    /// @dev                Only applies to new markets that are created after the change
    function setDefaults(uint32[6] memory defaults_) external;

    /// @notice             Change the status of the auctioneer to allow creation of new markets
    /// @dev                Setting to false and allowing active markets to end will sunset the auctioneer
    /// @param status_      Allow market creation (true) : Disallow market creation (false)
    function setAllowNewMarkets(bool status_) external;

    /// @notice             Change whether a market creator is allowed to use a callback address in their markets or not
    /// @notice             Must be guardian
    /// @dev                Callback is believed to be safe, but a whitelist is implemented to prevent abuse
    /// @param creator_     Address of market creator
    /// @param status_      Allow callback (true) : Disallow callback (false)
    function setCallbackAuthStatus(address creator_, bool status_) external;

    /* ========== VIEW FUNCTIONS ========== */

    /// @notice                 Provides information for the Teller to execute purchases on a Market
    /// @param id_              Market ID
    /// @return owner           Address of the market owner (tokens transferred from this address if no callback)
    /// @return callbackAddr    Address of the callback contract to get tokens for payouts
    /// @return payoutToken     Payout Token (token paid out) for the Market
    /// @return quoteToken      Quote Token (token received) for the Market
    /// @return vesting         Timestamp or duration for vesting, implementation-dependent
    /// @return maxPayout       Maximum amount of payout tokens you can purchase in one transaction
    function getMarketInfoForPurchase(uint256 id_)
        external
        view
        returns (
            address owner,
            address callbackAddr,
            ERC20 payoutToken,
            ERC20 quoteToken,
            uint48 vesting,
            uint256 maxPayout
        );

    /// @notice             Calculate current market price of payout token in quote tokens
    /// @param id_          ID of market
    /// @return             Price for market in configured decimals
    //
    // if price is below minimum price, minimum price is returned
    function marketPrice(uint256 id_) external view returns (uint256);

    /// @notice             Scale value to use when converting between quote token and payout token amounts with marketPrice()
    /// @param id_          ID of market
    /// @return             Scaling factor for market in configured decimals
    function marketScale(uint256 id_) external view returns (uint256);

    /// @notice             Payout due for amount of quote tokens
    /// @dev                Accounts for debt and control variable decay so it is up to date
    /// @param amount_      Amount of quote tokens to spend
    /// @param id_          ID of market
    /// @param referrer_    Address of referrer, used to get fees to calculate accurate payout amount.
    ///                     Inputting the zero address will take into account just the protocol fee.
    /// @return             amount of payout tokens to be paid
    function payoutFor(
        uint256 amount_,
        uint256 id_,
        address referrer_
    ) external view returns (uint256);

    /// @notice             Returns maximum amount of quote token accepted by the market
    /// @param id_          ID of market
    /// @param referrer_    Address of referrer, used to get fees to calculate accurate payout amount.
    ///                     Inputting the zero address will take into account just the protocol fee.
    function maxAmountAccepted(uint256 id_, address referrer_) external view returns (uint256);

    /// @notice             Does market send payout immediately
    /// @param id_          Market ID to search for
    function isInstantSwap(uint256 id_) external view returns (bool);

    /// @notice             Is a given market accepting deposits
    /// @param id_          ID of market
    function isLive(uint256 id_) external view returns (bool);

    /// @notice             Returns the address of the market owner
    /// @param id_          ID of market
    function ownerOf(uint256 id_) external view returns (address);

    /// @notice             Returns the Teller that services the Auctioneer
    function getTeller() external view returns (IBondTeller);

    /// @notice             Returns the Aggregator that services the Auctioneer
    function getAggregator() external view returns (IBondAggregator);

    /// @notice             Returns current capacity of a market
    function currentCapacity(uint256 id_) external view returns (uint256);
}

File 6 of 7 : IBondTeller.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.0;

import {ERC20} from "solmate/tokens/ERC20.sol";

interface IBondTeller {
    /// @notice                 Exchange quote tokens for a bond in a specified market
    /// @param recipient_       Address of recipient of bond. Allows deposits for other addresses
    /// @param referrer_        Address of referrer who will receive referral fee. For frontends to fill.
    ///                         Direct calls can use the zero address for no referrer fee.
    /// @param id_              ID of the Market the bond is being purchased from
    /// @param amount_          Amount to deposit in exchange for bond
    /// @param minAmountOut_    Minimum acceptable amount of bond to receive. Prevents frontrunning
    /// @return                 Amount of payout token to be received from the bond
    /// @return                 Timestamp at which the bond token can be redeemed for the underlying token
    function purchase(
        address recipient_,
        address referrer_,
        uint256 id_,
        uint256 amount_,
        uint256 minAmountOut_
    ) external returns (uint256, uint48);

    /// @notice          Get current fee charged by the teller based on the combined protocol and referrer fee
    /// @param referrer_ Address of the referrer
    /// @return          Fee in basis points (3 decimal places)
    function getFee(address referrer_) external view returns (uint48);

    /// @notice         Set protocol fee
    /// @notice         Must be guardian
    /// @param fee_     Protocol fee in basis points (3 decimal places)
    function setProtocolFee(uint48 fee_) external;

    /// @notice          Set the discount for creating bond tokens from the base protocol fee
    /// @dev             The discount is subtracted from the protocol fee to determine the fee
    ///                  when using create() to mint bond tokens without using an Auctioneer
    /// @param discount_ Create Fee Discount in basis points (3 decimal places)
    function setCreateFeeDiscount(uint48 discount_) external;

    /// @notice         Set your fee as a referrer to the protocol
    /// @notice         Fee is set for sending address
    /// @param fee_     Referrer fee in basis points (3 decimal places)
    function setReferrerFee(uint48 fee_) external;

    /// @notice         Claim fees accrued by sender in the input tokens and sends them to the provided address
    /// @param tokens_  Array of tokens to claim fees for
    /// @param to_      Address to send fees to
    function claimFees(ERC20[] memory tokens_, address to_) external;
}

File 7 of 7 : FullMath.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
library FullMath {
    /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
    function mulDiv(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = a * b
            // Compute the product mod 2**256 and mod 2**256 - 1
            // then use the Chinese Remainder Theorem to reconstruct
            // the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2**256 + prod0
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(a, b, not(0))
                prod0 := mul(a, b)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division
            if (prod1 == 0) {
                require(denominator > 0);
                assembly {
                    result := div(prod0, denominator)
                }
                return result;
            }

            // Make sure the result is less than 2**256.
            // Also prevents denominator == 0
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0]
            // Compute remainder using mulmod
            uint256 remainder;
            assembly {
                remainder := mulmod(a, b, denominator)
            }
            // Subtract 256 bit number from 512 bit number
            assembly {
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator
            // Compute largest power of two divisor of denominator.
            // Always >= 1.
            uint256 twos = (type(uint256).max - denominator + 1) & denominator;
            // Divide denominator by power of two
            assembly {
                denominator := div(denominator, twos)
            }

            // Divide [prod1 prod0] by the factors of two
            assembly {
                prod0 := div(prod0, twos)
            }
            // Shift in bits from prod1 into prod0. For this we need
            // to flip `twos` such that it is 2**256 / twos.
            // If twos is zero, then it becomes one
            assembly {
                twos := add(div(sub(0, twos), twos), 1)
            }
            prod0 |= prod1 * twos;

            // Invert denominator mod 2**256
            // Now that denominator is an odd number, it has an inverse
            // modulo 2**256 such that denominator * inv = 1 mod 2**256.
            // Compute the inverse by starting with a seed that is correct
            // correct for four bits. That is, denominator * inv = 1 mod 2**4
            uint256 inv = (3 * denominator) ^ 2;
            // Now use Newton-Raphson iteration to improve the precision.
            // Thanks to Hensel's lifting lemma, this also works in modular
            // arithmetic, doubling the correct bits in each step.
            inv *= 2 - denominator * inv; // inverse mod 2**8
            inv *= 2 - denominator * inv; // inverse mod 2**16
            inv *= 2 - denominator * inv; // inverse mod 2**32
            inv *= 2 - denominator * inv; // inverse mod 2**64
            inv *= 2 - denominator * inv; // inverse mod 2**128
            inv *= 2 - denominator * inv; // inverse mod 2**256

            // Because the division is now exact we can divide by multiplying
            // with the modular inverse of denominator. This will give us the
            // correct result modulo 2**256. Since the precoditions guarantee
            // that the outcome is less than 2**256, this is the final result.
            // We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inv;
            return result;
        }
    }

    /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    function mulDivUp(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        result = mulDiv(a, b, denominator);
        unchecked {
            if (mulmod(a, b, denominator) > 0) {
                require(result < type(uint256).max);
                result++;
            }
        }
    }
}

Settings
{
  "remappings": [
    "clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
    "clones/=lib/clones-with-immutable-args/src/",
    "ds-test/=lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "hardhat/=node_modules/hardhat/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "solidity-code-metrics/=node_modules/solidity-code-metrics/",
    "solmate/=lib/solmate/src/",
    "weird-erc20/=lib/solmate/lib/weird-erc20/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 100000
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"guardian_","type":"address"},{"internalType":"contract Authority","name":"authority_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"auctioneer_","type":"address"}],"name":"Aggregator_AlreadyRegistered","type":"error"},{"inputs":[],"name":"Aggregator_InvalidParams","type":"error"},{"inputs":[],"name":"Aggregator_OnlyAuctioneer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctioneers","outputs":[{"internalType":"contract IBondAuctioneer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"currentCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"payout_","type":"address"},{"internalType":"address","name":"quote_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"uint256","name":"minAmountOut_","type":"uint256"},{"internalType":"uint256","name":"maxExpiry_","type":"uint256"}],"name":"findMarketFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"getAuctioneer","outputs":[{"internalType":"contract IBondAuctioneer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"getTeller","outputs":[{"internalType":"contract IBondTeller","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"isInstantSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"isLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"firstIndex_","type":"uint256"},{"internalType":"uint256","name":"lastIndex_","type":"uint256"}],"name":"liveMarketsBetween","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"firstIndex_","type":"uint256"},{"internalType":"uint256","name":"lastIndex_","type":"uint256"}],"name":"liveMarketsBy","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"bool","name":"isPayout_","type":"bool"}],"name":"liveMarketsFor","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"marketPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"marketScale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"payout_","type":"address"},{"internalType":"address","name":"quote_","type":"address"}],"name":"marketsFor","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketsForPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketsForQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketsToAuctioneers","outputs":[{"internalType":"contract IBondAuctioneer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"address","name":"referrer_","type":"address"}],"name":"maxAmountAccepted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"address","name":"referrer_","type":"address"}],"name":"payoutFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IBondAuctioneer","name":"auctioneer_","type":"address"}],"name":"registerAuctioneer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"payoutToken_","type":"address"},{"internalType":"contract ERC20","name":"quoteToken_","type":"address"}],"name":"registerMarket","outputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200216a3803806200216a8339810160408190526200003491620000e8565b600080546001600160a01b03199081166001600160a01b0385811691821784556001805490931690851617909155604051849284929133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7691a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a35050505062000127565b6001600160a01b0381168114620000e557600080fd5b50565b60008060408385031215620000fc57600080fd5b82516200010981620000cf565b60208401519092506200011c81620000cf565b809150509250929050565b61203380620001376000396000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80638da5cb5b116100ee578063bf48582b11610097578063c3b7b13611610071578063c3b7b136146103c1578063c7bf8ca0146103d4578063ea5e0c60146103e7578063f9e709df1461041d57600080fd5b8063bf48582b1461037b578063bf7e214f1461038e578063c0680e20146103ae57600080fd5b8063b4359143116100c8578063b435914314610342578063bb6e75de14610355578063bbfe3a321461036857600080fd5b80638da5cb5b146102fc578063946824cd1461031c5780639a0fae9b1461032f57600080fd5b80634938a3fe1161015057806378b5a87a1161012a57806378b5a87a146102c35780637a9e5e4b146102d65780638b098db3146102e957600080fd5b80634938a3fe14610235578063520479421461025557806366b382ee146102b057600080fd5b8063247608071161018157806324760807146101f657806327507458146101ff5780633adec5a71461022257600080fd5b806306b40ea3146101a857806313af4035146101ce5780631c063a6c146101e3575b600080fd5b6101bb6101b6366004611c24565b610430565b6040519081526020015b60405180910390f35b6101e16101dc366004611c50565b610461565b005b6101bb6101f1366004611c6d565b61056a565b6101bb60025481565b61021261020d366004611c6d565b610613565b60405190151581526020016101c5565b6101bb610230366004611c6d565b6106b5565b610248610243366004611c86565b61071a565b6040516101c59190611cbb565b61028b610263366004611c6d565b60009081526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c5565b6101e16102be366004611c50565b610a96565b61028b6102d1366004611c6d565b610c4c565b6101e16102e4366004611c50565b610cea565b6102126102f7366004611c6d565b610e47565b60005461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101bb61032a366004611c6d565b610eac565b6101bb61033d366004611cff565b610f11565b6101bb610350366004611d50565b6111ba565b610248610363366004611d89565b611317565b610248610376366004611d50565b6113f6565b6101bb610389366004611dab565b61177c565b60015461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101bb6103bc366004611c24565b611835565b61028b6103cf366004611c6d565b611851565b6101bb6103e2366004611de4565b611888565b61028b6103f5366004611c6d565b60056020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61024861042b366004611e17565b611939565b6006602052816000526040600020818154811061044c57600080fd5b90600052602060002001600091509150505481565b61048f336000357fffffffff0000000000000000000000000000000000000000000000000000000016611aee565b6104fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b6000818152600560205260408082205490517f1c063a6c0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190631c063a6c906024015b602060405180830381865afa1580156105e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e45565b9392505050565b6000818152600560205260408082205490517f275074580000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169081906327507458906024015b602060405180830381865afa158015610691573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e5e565b6000818152600560205260408082205490517f3adec5a70000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190633adec5a7906024016105cb565b6060600080845b848110156108a057600081815260056020526040908190205490517f275074580000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff90911692508290632750745890602401602060405180830381865afa1580156107a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cc9190611e5e565b801561087f57506040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8089169190841690636352211e90602401602060405180830381865afa158015610843573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108679190611e7b565b73ffffffffffffffffffffffffffffffffffffffff16145b156108905761088d83611ec7565b92505b61089981611ec7565b9050610721565b5060008267ffffffffffffffff8111156108bc576108bc611eff565b6040519080825280602002602001820160405280156108e5578160200160208202803683370190505b50600093509050855b85811015610a8b57600081815260056020526040908190205490517f275074580000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff90911693508390632750745890602401602060405180830381865afa158015610975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109999190611e5e565b8015610a4c57506040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff808a169190851690636352211e90602401602060405180830381865afa158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a349190611e7b565b73ffffffffffffffffffffffffffffffffffffffff16145b15610a7b5780828581518110610a6457610a64611f2e565b6020908102919091010152610a7884611ec7565b93505b610a8481611ec7565b90506108ee565b509695505050505050565b610ac4336000357fffffffff0000000000000000000000000000000000000000000000000000000016611aee565b610b2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016104f1565b73ffffffffffffffffffffffffffffffffffffffff811660009081526004602052604090205460ff1615610ba2576040517fcba9dee200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104f1565b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff9093167fffffffffffffffffffffffff00000000000000000000000000000000000000009093168317905560009182526004602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055565b60008181526005602090815260408083205481517f9787d107000000000000000000000000000000000000000000000000000000008152915173ffffffffffffffffffffffffffffffffffffffff909116928392639787d10792600480830193928290030181865afa158015610cc6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e7b565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610dcd57506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff0000000000000000000000000000000000000000000000000000000016604482015273ffffffffffffffffffffffffffffffffffffffff9091169063b700961390606401602060405180830381865afa158015610da9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcd9190611e5e565b610dd657600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b6000818152600560205260408082205490517f8b098db30000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190638b098db390602401610674565b6000818152600560205260408082205490517f946824cd0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff90911690819063946824cd906024016105cb565b600080610f1e87876113f6565b805190915060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818080805b868110156111a85760056000898381518110610f6957610f69611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508173ffffffffffffffffffffffffffffffffffffffff1663acc5570c898381518110610fd057610fd0611f2e565b60200260200101516040518263ffffffff1660e01b8152600401610ff691815260200190565b60c060405180830381865afa158015611013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110379190611f5d565b9098509650600093505050635dba240065ffffffffffff871611159050611066578465ffffffffffff16611078565b61107865ffffffffffff861642611fe5565b90508a811161119757838c11611197578273ffffffffffffffffffffffffffffffffffffffff1663bf48582b8e8b85815181106110b7576110b7611f2e565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015260006044820152606401602060405180830381865afa92505050801561115c575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261115991810190611e45565b60015b1561119757878111801561117057508c8110155b156111955780975089838151811061118a5761118a611f2e565b602002602001015196505b505b506111a181611ec7565b9050610f4b565b50929c9b505050505050505050505050565b3360009081526004602052604081205460ff16611203576040517f8feeaaa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316158061123a575073ffffffffffffffffffffffffffffffffffffffff8216155b15611271576040517f018c362a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060028054600081815260056020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905573ffffffffffffffffffffffffffffffffffffffff8781168452600683528184208054600181810183559186528486200186905590871684526007835290832080549182018155835290822001829055825491929161130d90611ec7565b9091555092915050565b60606000835b8381101561134f5761132e81610613565b1561133f5761133c82611ec7565b91505b61134881611ec7565b905061131d565b5060008167ffffffffffffffff81111561136b5761136b611eff565b604051908082528060200260200182016040528015611394578160200160208202803683370190505b50600092509050845b848110156113ed576113ae81610613565b156113dd57808284815181106113c6576113c6611f2e565b60209081029190910101526113da83611ec7565b92505b6113e681611ec7565b905061139d565b50949350505050565b60606000611405846001611939565b90506000806000808451905060005b81811015611585576005600087838151811061143257611432611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692508273ffffffffffffffffffffffffffffffffffffffff1663acc5570c87838151811061149957611499611f2e565b60200260200101516040518263ffffffff1660e01b81526004016114bf91815260200190565b60c060405180830381865afa1580156114dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115009190611f5d565b5050895190975061152d9350899250849150811061152057611520611f2e565b6020026020010151610613565b801561156457508773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b156115755761157285611ec7565b94505b61157e81611ec7565b9050611414565b5060008467ffffffffffffffff8111156115a1576115a1611eff565b6040519080825280602002602001820160405280156115ca578160200160208202803683370190505b5090506000945060005b8281101561176f57600560008883815181106115f2576115f2611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1693508373ffffffffffffffffffffffffffffffffffffffff1663acc5570c88838151811061165957611659611f2e565b60200260200101516040518263ffffffff1660e01b815260040161167f91815260200190565b60c060405180830381865afa15801561169c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c09190611f5d565b50508a519098506116e093508a9250849150811061152057611520611f2e565b801561171757508873ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b1561175f5786818151811061172e5761172e611f2e565b602002602001015182878151811061174857611748611f2e565b602090810291909101015261175c86611ec7565b95505b61176881611ec7565b90506115d4565b5098975050505050505050565b6000828152600560205260408082205490517fbf48582b000000000000000000000000000000000000000000000000000000008152600481018690526024810185905273ffffffffffffffffffffffffffffffffffffffff848116604483015290911690819063bf48582b90606401602060405180830381865afa158015611808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182c9190611e45565b95945050505050565b6007602052816000526040600020818154811061044c57600080fd5b6003818154811061186157600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000828152600560205260408082205490517fc7bf8ca00000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff848116602483015290911690819063c7bf8ca090604401602060405180830381865afa15801561190d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119319190611e45565b949350505050565b6060808261196b5773ffffffffffffffffffffffffffffffffffffffff84166000908152600760205260409020611991565b73ffffffffffffffffffffffffffffffffffffffff841660009081526006602052604090205b8054806020026020016040519081016040528092919081815260200182805480156119db57602002820191906000526020600020905b8154815260200190600101908083116119c7575b505050505090506000808251905060005b81811015611a2a57611a0984828151811061152057611520611f2e565b15611a1a57611a1783611ec7565b92505b611a2381611ec7565b90506119ec565b5060008267ffffffffffffffff811115611a4657611a46611eff565b604051908082528060200260200182016040528015611a6f578160200160208202803683370190505b5090506000925060005b82811015610a8b57611a9685828151811061152057611520611f2e565b15611ade57848181518110611aad57611aad611f2e565b6020026020010151828581518110611ac757611ac7611f2e565b6020908102919091010152611adb84611ec7565b93505b611ae781611ec7565b9050611a79565b60015460009073ffffffffffffffffffffffffffffffffffffffff168015801590611bd257506040517fb700961300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b700961390606401602060405180830381865afa158015611bae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd29190611e5e565b80611931575060005473ffffffffffffffffffffffffffffffffffffffff85811691161491505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c2157600080fd5b50565b60008060408385031215611c3757600080fd5b8235611c4281611bff565b946020939093013593505050565b600060208284031215611c6257600080fd5b813561060c81611bff565b600060208284031215611c7f57600080fd5b5035919050565b600080600060608486031215611c9b57600080fd5b8335611ca681611bff565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611cf357835183529284019291840191600101611cd7565b50909695505050505050565b600080600080600060a08688031215611d1757600080fd5b8535611d2281611bff565b94506020860135611d3281611bff565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215611d6357600080fd5b8235611d6e81611bff565b91506020830135611d7e81611bff565b809150509250929050565b60008060408385031215611d9c57600080fd5b50508035926020909101359150565b600080600060608486031215611dc057600080fd5b83359250602084013591506040840135611dd981611bff565b809150509250925092565b60008060408385031215611df757600080fd5b823591506020830135611d7e81611bff565b8015158114611c2157600080fd5b60008060408385031215611e2a57600080fd5b8235611e3581611bff565b91506020830135611d7e81611e09565b600060208284031215611e5757600080fd5b5051919050565b600060208284031215611e7057600080fd5b815161060c81611e09565b600060208284031215611e8d57600080fd5b815161060c81611bff565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ef857611ef8611e98565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060008060008060c08789031215611f7657600080fd5b8651611f8181611bff565b6020880151909650611f9281611bff565b6040880151909550611fa381611bff565b6060880151909450611fb481611bff565b608088015190935065ffffffffffff81168114611fd057600080fd5b8092505060a087015190509295509295509295565b60008219821115611ff857611ff8611e98565b50019056fea2646970667358221220ba286c6d6ce9c50ea976df0013cb65eb875fdf24af038e02dcb81b114cf03fd864736f6c634300080f0033000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14

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

000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14

-----Decoded View---------------
Arg [0] : guardian_ (address): 0x007bd11fca0daaeadd455b51826f9a015f2f0969
Arg [1] : authority_ (address): 0x007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969
Arg [1] : 000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading