Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Create Market | 18582059 | 797 days ago | IN | 0 ETH | 0.01002808 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60c06040 | 16997485 | 1019 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BondFixedTermFPA
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 100000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.15;
import {BondBaseFPA, IBondAggregator, Authority} from "./bases/BondBaseFPA.sol";
import {IBondTeller} from "./interfaces/IBondTeller.sol";
/// @title Bond Fixed-Term Fixed Price Auctioneer
/// @notice Bond Fixed-Term Fixed Price Auctioneer Contract
/// @dev Bond Protocol is a permissionless system to create bond markets
/// for any token pair. 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 An Auctioneer contract allows users to create and manage bond markets.
/// All bond pricing logic and market data is stored in the Auctioneer.
/// An Auctioneer is dependent on a Teller to serve external users and
/// an Aggregator to register new markets. The Fixed Price Auctioneer
/// lets issuers set a Fixed Price to buy a target amount of quote tokens or sell
/// a target amount of payout tokens over the duration of a market.
/// See IBondFPA.sol for price format details.
///
/// @dev The Fixed-Term Fixed Price Auctioneer is an implementation of the
/// Bond Base Auctioneer contract specific to creating bond markets where
/// purchases vest in a fixed amount of time after purchased (rounded to the day).
///
/// @author Oighty
contract BondFixedTermFPA is BondBaseFPA {
/* ========== CONSTRUCTOR ========== */
constructor(
IBondTeller teller_,
IBondAggregator aggregator_,
address guardian_,
Authority authority_
) BondBaseFPA(teller_, aggregator_, guardian_, authority_) {}
/* ========== MARKET FUNCTIONS ========== */
/// @inheritdoc BondBaseFPA
function createMarket(bytes calldata params_) external override returns (uint256) {
// Decode params into the struct type expected by this auctioneer
MarketParams memory params = abi.decode(params_, (MarketParams));
// Check that the vesting parameter is valid for a fixed-term market
if (params.vesting != 0 && (params.vesting < 1 days || params.vesting > MAX_FIXED_TERM))
revert Auctioneer_InvalidParams();
// Create market and return market ID
return _createMarket(params);
}
}// 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);
}// 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);
}
}/// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.15;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {Auth, Authority} from "solmate/auth/Auth.sol";
import {IBondFPA, IBondAuctioneer} from "../interfaces/IBondFPA.sol";
import {IBondTeller} from "../interfaces/IBondTeller.sol";
import {IBondCallback} from "../interfaces/IBondCallback.sol";
import {IBondAggregator} from "../interfaces/IBondAggregator.sol";
import {TransferHelper} from "../lib/TransferHelper.sol";
import {FullMath} from "../lib/FullMath.sol";
/// @title Bond Fixed Price Auctioneer
/// @notice Bond Fixed Price Auctioneer Base Contract
/// @dev Bond Protocol is a system to create markets for any token pair.
/// 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. Alternatively, markets can be
/// instant swap and payouts are made immediately to the user.
///
/// @dev An Auctioneer contract allows users to create and manage bond markets.
/// All bond pricing logic and market data is stored in the Auctioneer.
/// An Auctioneer is dependent on a Teller to serve external users and
/// an Aggregator to register new markets. The Fixed Price Auctioneer
/// lets issuers set a Fixed Price to buy a target amount of quote tokens or sell
/// a target amount of payout tokens over the duration of a market.
/// See IBondFPA.sol for price format details.
///
/// @author Oighty
abstract contract BondBaseFPA is IBondFPA, Auth {
using TransferHelper for ERC20;
using FullMath for uint256;
/* ========== ERRORS ========== */
error Auctioneer_OnlyMarketOwner();
error Auctioneer_MarketNotActive();
error Auctioneer_MaxPayoutExceeded();
error Auctioneer_AmountLessThanMinimum();
error Auctioneer_NotEnoughCapacity();
error Auctioneer_InvalidCallback();
error Auctioneer_BadExpiry();
error Auctioneer_InvalidParams();
error Auctioneer_NotAuthorized();
error Auctioneer_NewMarketsNotAllowed();
/* ========== EVENTS ========== */
event MarketCreated(
uint256 indexed id,
address indexed payoutToken,
address indexed quoteToken,
uint48 vesting,
uint256 fixedPrice
);
event MarketClosed(uint256 indexed id);
/* ========== STATE VARIABLES ========== */
/// @notice Information pertaining to bond markets
mapping(uint256 => BondMarket) public markets;
/// @notice Information pertaining to market vesting and duration
mapping(uint256 => BondTerms) public terms;
/// @notice New address to designate as market owner. They must accept ownership to transfer permissions.
mapping(uint256 => address) public newOwners;
/// @notice Whether or not the auctioneer allows new markets to be created
/// @dev Changing to false will sunset the auctioneer after all active markets end
bool public allowNewMarkets;
// Minimum time parameter values. Can be updated by admin.
/// @notice Minimum deposit interval for a market
uint48 public minDepositInterval;
/// @notice Minimum market duration in seconds
uint48 public minMarketDuration;
/// @notice Whether or not the market creator is authorized to use a callback address
mapping(address => bool) public callbackAuthorized;
// A 'vesting' param longer than 50 years is considered a timestamp for fixed expiry.
uint48 internal constant MAX_FIXED_TERM = 52 weeks * 50;
uint48 internal constant ONE_HUNDRED_PERCENT = 1e5; // one percent equals 1000.
// BondAggregator contract with utility functions
IBondAggregator internal immutable _aggregator;
// BondTeller contract that handles interactions with users and issues tokens
IBondTeller internal immutable _teller;
constructor(
IBondTeller teller_,
IBondAggregator aggregator_,
address guardian_,
Authority authority_
) Auth(guardian_, authority_) {
_aggregator = aggregator_;
_teller = teller_;
minDepositInterval = 1 hours;
minMarketDuration = 1 days;
allowNewMarkets = true;
}
/* ========== MARKET FUNCTIONS ========== */
/// @inheritdoc IBondAuctioneer
function createMarket(bytes calldata params_) external virtual returns (uint256);
/// @notice core market creation logic, see IBondFPA.MarketParams documentation
function _createMarket(MarketParams memory params_) internal returns (uint256) {
{
// Check that the auctioneer is allowing new markets to be created
if (!allowNewMarkets) revert Auctioneer_NewMarketsNotAllowed();
// Ensure params are in bounds
uint8 payoutTokenDecimals = params_.payoutToken.decimals();
uint8 quoteTokenDecimals = params_.quoteToken.decimals();
if (payoutTokenDecimals < 6 || payoutTokenDecimals > 18)
revert Auctioneer_InvalidParams();
if (quoteTokenDecimals < 6 || quoteTokenDecimals > 18)
revert Auctioneer_InvalidParams();
if (params_.scaleAdjustment < -24 || params_.scaleAdjustment > 24)
revert Auctioneer_InvalidParams();
// Restrict the use of a callback address unless allowed
if (!callbackAuthorized[msg.sender] && params_.callbackAddr != address(0))
revert Auctioneer_NotAuthorized();
// Start time must be zero or in the future
if (params_.start > 0 && params_.start < block.timestamp)
revert Auctioneer_InvalidParams();
}
// Unit to scale calculation for this market by to ensure reasonable values.
// See IBondFPA for more details.
//
// scaleAdjustment should be equal to (payoutDecimals - quoteDecimals) - ((payoutPriceDecimals - quotePriceDecimals) / 2)
uint256 scale;
unchecked {
scale = 10**uint8(36 + params_.scaleAdjustment);
}
// Check that price is not zero
if (params_.formattedPrice == 0) revert Auctioneer_InvalidParams();
// Check time bounds
if (
params_.duration < minMarketDuration ||
params_.depositInterval < minDepositInterval ||
params_.depositInterval > params_.duration
) revert Auctioneer_InvalidParams();
// Calculate the maximum payout amount for this market
uint256 _maxPayout = (
params_.capacityInQuote
? params_.capacity.mulDiv(scale, params_.formattedPrice)
: params_.capacity
).mulDiv(uint256(params_.depositInterval), uint256(params_.duration));
// Register new market on aggregator and get marketId
uint256 marketId = _aggregator.registerMarket(params_.payoutToken, params_.quoteToken);
markets[marketId] = BondMarket({
owner: msg.sender,
payoutToken: params_.payoutToken,
quoteToken: params_.quoteToken,
callbackAddr: params_.callbackAddr,
capacityInQuote: params_.capacityInQuote,
capacity: params_.capacity,
maxPayout: _maxPayout,
price: params_.formattedPrice,
scale: scale,
purchased: 0,
sold: 0
});
// Calculate and store time terms
uint48 start = params_.start == 0 ? uint48(block.timestamp) : params_.start;
terms[marketId] = BondTerms({
start: start,
conclusion: start + params_.duration,
vesting: params_.vesting
});
emit MarketCreated(
marketId,
address(params_.payoutToken),
address(params_.quoteToken),
params_.vesting,
params_.formattedPrice
);
return marketId;
}
/// @inheritdoc IBondAuctioneer
function pushOwnership(uint256 id_, address newOwner_) external override {
if (msg.sender != markets[id_].owner) revert Auctioneer_OnlyMarketOwner();
newOwners[id_] = newOwner_;
}
/// @inheritdoc IBondAuctioneer
function pullOwnership(uint256 id_) external override {
if (msg.sender != newOwners[id_]) revert Auctioneer_NotAuthorized();
markets[id_].owner = newOwners[id_];
}
/// @inheritdoc IBondFPA
function setMinMarketDuration(uint48 duration_) external override requiresAuth {
// Restricted to authorized addresses
// Require duration to be greater than minimum deposit interval and at least 1 day
if (duration_ < minDepositInterval || duration_ < 1 days) revert Auctioneer_InvalidParams();
minMarketDuration = duration_;
}
/// @inheritdoc IBondFPA
function setMinDepositInterval(uint48 depositInterval_) external override requiresAuth {
// Restricted to authorized addresses
// Require min deposit interval to be less than minimum market duration and at least 1 hour
if (depositInterval_ > minMarketDuration || depositInterval_ < 1 hours)
revert Auctioneer_InvalidParams();
minDepositInterval = depositInterval_;
}
// Unused, but required by interface
function setIntervals(uint256 id_, uint32[3] calldata intervals_) external override {}
// Unused, but required by interface
function setDefaults(uint32[6] memory defaults_) external override {}
/// @inheritdoc IBondAuctioneer
function setAllowNewMarkets(bool status_) external override requiresAuth {
// Restricted to authorized addresses
allowNewMarkets = status_;
}
/// @inheritdoc IBondAuctioneer
function setCallbackAuthStatus(address creator_, bool status_) external override requiresAuth {
// Restricted to authorized addresses
callbackAuthorized[creator_] = status_;
}
/// @inheritdoc IBondAuctioneer
function closeMarket(uint256 id_) external override {
if (msg.sender != markets[id_].owner) revert Auctioneer_OnlyMarketOwner();
terms[id_].conclusion = uint48(block.timestamp);
markets[id_].capacity = 0;
emit MarketClosed(id_);
}
/* ========== TELLER FUNCTIONS ========== */
/// @inheritdoc IBondAuctioneer
function purchaseBond(
uint256 id_,
uint256 amount_,
uint256 minAmountOut_
) external override returns (uint256 payout) {
if (msg.sender != address(_teller)) revert Auctioneer_NotAuthorized();
BondMarket storage market = markets[id_];
// If market uses a callback, check that owner is still callback authorized
if (market.callbackAddr != address(0) && !callbackAuthorized[market.owner])
revert Auctioneer_NotAuthorized();
// Check if market is live, if not revert
if (!isLive(id_)) revert Auctioneer_MarketNotActive();
// Calculate payout amount from fixed price
payout = amount_.mulDiv(market.scale, market.price);
// Payout must be greater than user inputted minimum
if (payout < minAmountOut_) revert Auctioneer_AmountLessThanMinimum();
// Markets have a max payout amount per transaction
if (payout > market.maxPayout) revert Auctioneer_MaxPayoutExceeded();
// Update Capacity
// Capacity is either the number of payout tokens that the market can sell
// (if capacity in quote is false),
//
// or the number of quote tokens that the market can buy
// (if capacity in quote is true)
// If amount/payout is greater than capacity remaining, revert
if (market.capacityInQuote ? amount_ > market.capacity : payout > market.capacity)
revert Auctioneer_NotEnoughCapacity();
// Capacity is decreased by the deposited or paid amount
market.capacity -= market.capacityInQuote ? amount_ : payout;
// Markets keep track of how many quote tokens have been
// purchased, and how many payout tokens have been sold
market.purchased += amount_;
market.sold += payout;
}
/* ========== VIEW FUNCTIONS ========== */
/* ========== EXTERNAL VIEW FUNCTIONS ========== */
/// @inheritdoc IBondAuctioneer
function getMarketInfoForPurchase(uint256 id_)
external
view
returns (
address owner,
address callbackAddr,
ERC20 payoutToken,
ERC20 quoteToken,
uint48 vesting,
uint256 maxPayout_
)
{
BondMarket memory market = markets[id_];
return (
market.owner,
market.callbackAddr,
market.payoutToken,
market.quoteToken,
terms[id_].vesting,
maxPayout(id_)
);
}
/// @inheritdoc IBondAuctioneer
function marketPrice(uint256 id_) public view override returns (uint256) {
return markets[id_].price;
}
/// @inheritdoc IBondAuctioneer
function marketScale(uint256 id_) external view override returns (uint256) {
return markets[id_].scale;
}
/// @inheritdoc IBondAuctioneer
function payoutFor(
uint256 amount_,
uint256 id_,
address referrer_
) public view override returns (uint256) {
// Calculate the payout for the given amount of tokens
uint256 fee = amount_.mulDiv(_teller.getFee(referrer_), ONE_HUNDRED_PERCENT);
uint256 payout = (amount_ - fee).mulDiv(markets[id_].scale, marketPrice(id_));
// Check that the payout is less than or equal to the maximum payout,
// Revert if not, otherwise return the payout
if (payout > maxPayout(id_)) {
revert Auctioneer_MaxPayoutExceeded();
} else {
return payout;
}
}
/// @inheritdoc IBondAuctioneer
function maxAmountAccepted(uint256 id_, address referrer_) external view returns (uint256) {
// Calculate maximum amount of quote tokens that correspond to max bond size
// Maximum of the maxPayout and the remaining capacity converted to quote tokens
BondMarket memory market = markets[id_];
uint256 price = marketPrice(id_);
uint256 quoteCapacity = market.capacityInQuote
? market.capacity
: market.capacity.mulDiv(price, market.scale);
uint256 maxQuote = market.maxPayout.mulDiv(price, market.scale);
uint256 amountAccepted = quoteCapacity < maxQuote ? quoteCapacity : maxQuote;
// Take into account teller fees and return
// Estimate fee based on amountAccepted. Fee taken will be slightly larger than
// this given it will be taken off the larger amount, but this avoids rounding
// errors with trying to calculate the exact amount.
// Therefore, the maxAmountAccepted is slightly conservative.
uint256 estimatedFee = amountAccepted.mulDiv(
_teller.getFee(referrer_),
ONE_HUNDRED_PERCENT
);
return amountAccepted + estimatedFee;
}
/// @inheritdoc IBondFPA
function maxPayout(uint256 id_) public view override returns (uint256) {
// Get current price
uint256 price = marketPrice(id_);
BondMarket memory market = markets[id_];
// Convert capacity to payout token units for comparison with max payout
uint256 capacity = market.capacityInQuote
? market.capacity.mulDiv(market.scale, price)
: market.capacity;
// Cap max payout at the remaining capacity
return market.maxPayout > capacity ? capacity : market.maxPayout;
}
/// @inheritdoc IBondAuctioneer
function isInstantSwap(uint256 id_) public view returns (bool) {
uint256 vesting = terms[id_].vesting;
return (vesting <= MAX_FIXED_TERM) ? vesting == 0 : vesting <= block.timestamp;
}
/// @inheritdoc IBondAuctioneer
function isLive(uint256 id_) public view override returns (bool) {
return (markets[id_].capacity != 0 &&
terms[id_].conclusion > uint48(block.timestamp) &&
terms[id_].start <= uint48(block.timestamp));
}
/// @inheritdoc IBondAuctioneer
function ownerOf(uint256 id_) external view override returns (address) {
return markets[id_].owner;
}
/// @inheritdoc IBondAuctioneer
function getTeller() external view override returns (IBondTeller) {
return _teller;
}
/// @inheritdoc IBondAuctioneer
function getAggregator() external view override returns (IBondAggregator) {
return _aggregator;
}
/// @inheritdoc IBondAuctioneer
function currentCapacity(uint256 id_) external view override returns (uint256) {
return markets[id_].capacity;
}
}// 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);
}// 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);
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.0;
import {ERC20} from "solmate/tokens/ERC20.sol";
interface IBondCallback {
/// @notice Send payout tokens to Teller while allowing market owners to perform custom logic on received or paid out tokens
/// @notice Market ID on Teller must be whitelisted
/// @param id_ ID of the market
/// @param inputAmount_ Amount of quote tokens bonded to the market
/// @param outputAmount_ Amount of payout tokens to be paid out to the market
/// @dev Must transfer the output amount of payout tokens back to the Teller
/// @dev Should check that the quote tokens have been transferred to the contract in the _callback function
function callback(
uint256 id_,
uint256 inputAmount_,
uint256 outputAmount_
) external;
/// @notice Returns the number of quote tokens received and payout tokens paid out for a market
/// @param id_ ID of the market
/// @return in_ Amount of quote tokens bonded to the market
/// @return out_ Amount of payout tokens paid out to the market
function amountsForMarket(uint256 id_) external view returns (uint256 in_, uint256 out_);
/// @notice Whitelist a teller and market ID combination
/// @notice Must be callback owner
/// @param teller_ Address of the Teller contract which serves the market
/// @param id_ ID of the market
function whitelist(address teller_, uint256 id_) external;
/// @notice Remove a market ID on a teller from the whitelist
/// @dev Shutdown function in case there's an issue with the teller
/// @param teller_ Address of the Teller contract which serves the market
/// @param id_ ID of the market to remove from whitelist
function blacklist(address teller_, uint256 id_) external;
/// @notice Withdraw tokens from the callback and update balances
/// @notice Only callback owner
/// @param to_ Address of the recipient
/// @param token_ Address of the token to withdraw
/// @param amount_ Amount of tokens to withdraw
function withdraw(
address to_,
ERC20 token_,
uint256 amount_
) external;
/// @notice Deposit tokens to the callback and update balances
/// @notice Only callback owner
/// @param token_ Address of the token to deposit
/// @param amount_ Amount of tokens to deposit
function deposit(ERC20 token_, uint256 amount_) external;
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.0;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {IBondAuctioneer} from "../interfaces/IBondAuctioneer.sol";
interface IBondFPA is IBondAuctioneer {
/// @notice Information pertaining to bond market
struct BondMarket {
address owner; // market owner. sends payout tokens, receives quote tokens (defaults to creator)
ERC20 payoutToken; // token to pay depositors with
ERC20 quoteToken; // token to accept as payment
address callbackAddr; // address to call for any operations on bond purchase. Must inherit to IBondCallback.
bool capacityInQuote; // capacity limit is in payment token (true) or in payout (false, default)
uint256 capacity; // capacity remaining
uint256 maxPayout; // max payout tokens out in one order
uint256 price; // fixed price of the market (see MarketParams struct)
uint256 scale; // scaling factor for the market (see MarketParams struct)
uint256 sold; // payout tokens out
uint256 purchased; // quote tokens in
}
/// @notice Information pertaining to market duration and vesting
struct BondTerms {
uint48 start; // timestamp when market starts
uint48 conclusion; // timestamp when market no longer offered
uint48 vesting; // length of time from deposit to expiry if fixed-term, vesting timestamp if fixed-expiry
}
/// @notice Parameters to create a new bond market
/// @dev Note price should be passed in a specific format:
/// formatted price = (payoutPriceCoefficient / quotePriceCoefficient)
/// * 10**(36 + scaleAdjustment + quoteDecimals - payoutDecimals + payoutPriceDecimals - quotePriceDecimals)
/// where:
/// payoutDecimals - Number of decimals defined for the payoutToken in its ERC20 contract
/// quoteDecimals - Number of decimals defined for the quoteToken in its ERC20 contract
/// payoutPriceCoefficient - The coefficient of the payoutToken price in scientific notation (also known as the significant digits)
/// payoutPriceDecimals - The significand of the payoutToken price in scientific notation (also known as the base ten exponent)
/// quotePriceCoefficient - The coefficient of the quoteToken price in scientific notation (also known as the significant digits)
/// quotePriceDecimals - The significand of the quoteToken price in scientific notation (also known as the base ten exponent)
/// scaleAdjustment - see below
/// * In the above definitions, the "prices" need to have the same unit of account (i.e. both in OHM, $, ETH, etc.)
/// If price is not provided in this format, the market will not behave as intended.
/// @param params_ Encoded bytes array, with the following elements
/// @dev 0. Payout Token (token paid out)
/// @dev 1. Quote Token (token to be received)
/// @dev 2. Callback contract address, should conform to IBondCallback. If 0x00, tokens will be transferred from market.owner
/// @dev 3. Is Capacity in Quote Token?
/// @dev 4. Capacity (amount in quoteDecimals or amount in payoutDecimals)
/// @dev 5. Formatted price (see note above)
/// @dev 6. Deposit interval (seconds). Desired frequency of bonds. Used to calculate max payout of market (maxPayout = length / depositInterval * capacity).
/// @dev 7. Is fixed term ? Vesting length (seconds) : Vesting expiry (timestamp).
/// @dev A 'vesting' param longer than 50 years is considered a timestamp for fixed expiry.
/// @dev 8. Start Time of the Market (timestamp) - Allows starting a market in the future.
/// @dev If a start time is provided, the txn must be sent prior to the start time (functions as a deadline).
/// @dev If start time is not provided (i.e. 0), the market will start immediately.
/// @dev 9. Market Duration (seconds) - Duration of the market in seconds.
/// @dev 10. Market scaling factor adjustment, ranges from -24 to +24 within the configured market bounds.
/// @dev Should be calculated as: (payoutDecimals - quoteDecimals) - ((payoutPriceDecimals - quotePriceDecimals) / 2)
/// @dev Providing a scaling factor adjustment that doesn't follow this formula could lead to under or overflow errors in the market.
/// @return ID of new bond market
struct MarketParams {
ERC20 payoutToken;
ERC20 quoteToken;
address callbackAddr;
bool capacityInQuote;
uint256 capacity;
uint256 formattedPrice;
uint48 depositInterval;
uint48 vesting;
uint48 start;
uint48 duration;
int8 scaleAdjustment;
}
/// @notice Set the minimum market duration
/// @notice Access controlled
/// @param duration_ Minimum market duration in seconds
function setMinMarketDuration(uint48 duration_) external;
/// @notice Set the minimum deposit interval
/// @notice Access controlled
/// @param depositInterval_ Minimum deposit interval in seconds
function setMinDepositInterval(uint48 depositInterval_) external;
/* ========== VIEW FUNCTIONS ========== */
/// @notice Calculate current market price of payout token in quote tokens
/// @param id_ ID of market
/// @return Price for market in configured decimals (see MarketParams)
/// @dev price is derived from the equation:
//
// p = f_p
//
// where
// p = price
// f_p = fixed price provided on creation
//
function marketPrice(uint256 id_) external view override returns (uint256);
/// @notice Calculate max payout of the market in payout tokens
/// @dev Returns a dynamically calculated payout or the maximum set by the creator, whichever is less.
/// @param id_ ID of market
/// @return Current max payout for the market in payout tokens
function maxPayout(uint256 id_) external view returns (uint256);
}// 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;
}// 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++;
}
}
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "solmate/tokens/ERC20.sol";
/// @notice Safe ERC20 and ETH transfer library that safely handles missing return values.
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/libraries/TransferHelper.sol)
/// @author Taken from Solmate.
library TransferHelper {
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(ERC20.transferFrom.selector, from, to, amount)
);
require(
success &&
(data.length == 0 || abi.decode(data, (bool))) &&
address(token).code.length > 0,
"TRANSFER_FROM_FAILED"
);
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(ERC20.transfer.selector, to, amount)
);
require(
success &&
(data.length == 0 || abi.decode(data, (bool))) &&
address(token).code.length > 0,
"TRANSFER_FAILED"
);
}
// function safeApprove(
// ERC20 token,
// address to,
// uint256 amount
// ) internal {
// (bool success, bytes memory data) = address(token).call(
// abi.encodeWithSelector(ERC20.approve.selector, to, amount)
// );
// require(success && (data.length == 0 || abi.decode(data, (bool))), "APPROVE_FAILED");
// }
// function safeTransferETH(address to, uint256 amount) internal {
// (bool success, ) = to.call{value: amount}(new bytes(0));
// require(success, "ETH_TRANSFER_FAILED");
// }
}{
"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/",
"prb-math/=lib/prb-math/src/'/",
"solmate/=lib/solmate/src/",
"src/=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 Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IBondTeller","name":"teller_","type":"address"},{"internalType":"contract IBondAggregator","name":"aggregator_","type":"address"},{"internalType":"address","name":"guardian_","type":"address"},{"internalType":"contract Authority","name":"authority_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Auctioneer_AmountLessThanMinimum","type":"error"},{"inputs":[],"name":"Auctioneer_BadExpiry","type":"error"},{"inputs":[],"name":"Auctioneer_InvalidCallback","type":"error"},{"inputs":[],"name":"Auctioneer_InvalidParams","type":"error"},{"inputs":[],"name":"Auctioneer_MarketNotActive","type":"error"},{"inputs":[],"name":"Auctioneer_MaxPayoutExceeded","type":"error"},{"inputs":[],"name":"Auctioneer_NewMarketsNotAllowed","type":"error"},{"inputs":[],"name":"Auctioneer_NotAuthorized","type":"error"},{"inputs":[],"name":"Auctioneer_NotEnoughCapacity","type":"error"},{"inputs":[],"name":"Auctioneer_OnlyMarketOwner","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":"uint256","name":"id","type":"uint256"}],"name":"MarketClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"payoutToken","type":"address"},{"indexed":true,"internalType":"address","name":"quoteToken","type":"address"},{"indexed":false,"internalType":"uint48","name":"vesting","type":"uint48"},{"indexed":false,"internalType":"uint256","name":"fixedPrice","type":"uint256"}],"name":"MarketCreated","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":[],"name":"allowNewMarkets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"callbackAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"closeMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"params_","type":"bytes"}],"name":"createMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"currentCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAggregator","outputs":[{"internalType":"contract IBondAggregator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"getMarketInfoForPurchase","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"callbackAddr","type":"address"},{"internalType":"contract ERC20","name":"payoutToken","type":"address"},{"internalType":"contract ERC20","name":"quoteToken","type":"address"},{"internalType":"uint48","name":"vesting","type":"uint48"},{"internalType":"uint256","name":"maxPayout_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"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":"uint256","name":"","type":"uint256"}],"name":"markets","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"contract ERC20","name":"payoutToken","type":"address"},{"internalType":"contract ERC20","name":"quoteToken","type":"address"},{"internalType":"address","name":"callbackAddr","type":"address"},{"internalType":"bool","name":"capacityInQuote","type":"bool"},{"internalType":"uint256","name":"capacity","type":"uint256"},{"internalType":"uint256","name":"maxPayout","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"scale","type":"uint256"},{"internalType":"uint256","name":"sold","type":"uint256"},{"internalType":"uint256","name":"purchased","type":"uint256"}],"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":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"maxPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepositInterval","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minMarketDuration","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"newOwners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"ownerOf","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":"uint256","name":"id_","type":"uint256"}],"name":"pullOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"minAmountOut_","type":"uint256"}],"name":"purchaseBond","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"address","name":"newOwner_","type":"address"}],"name":"pushOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status_","type":"bool"}],"name":"setAllowNewMarkets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creator_","type":"address"},{"internalType":"bool","name":"status_","type":"bool"}],"name":"setCallbackAuthStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[6]","name":"defaults_","type":"uint32[6]"}],"name":"setDefaults","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"uint32[3]","name":"intervals_","type":"uint32[3]"}],"name":"setIntervals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"depositInterval_","type":"uint48"}],"name":"setMinDepositInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"duration_","type":"uint48"}],"name":"setMinMarketDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"terms","outputs":[{"internalType":"uint48","name":"start","type":"uint48"},{"internalType":"uint48","name":"conclusion","type":"uint48"},{"internalType":"uint48","name":"vesting","type":"uint48"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162002bba38038062002bba833981016040819052620000349162000125565b600080546001600160a01b03199081166001600160a01b0385811691821784556001805490931690851617909155604051869286928692869284928492909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a3505050506001600160a01b039081166080521660a0525050600580546001600160681b03191669015180000000000e1001179055506200018d9050565b6001600160a01b03811681146200012257600080fd5b50565b600080600080608085870312156200013c57600080fd5b845162000149816200010c565b60208601519094506200015c816200010c565b60408601519093506200016f816200010c565b606086015190925062000182816200010c565b939692955090935050565b60805160a0516129eb620001cf6000396000818161046e015281816112e10152818161155a015261160d0152600081816102ae0152611f8e01526129eb6000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c8063946824cd1161012a578063bd1f3a5e116100bd578063c7bf8ca01161008c578063d2bee32311610071578063d2bee3231461073f578063e007fa971461075c578063f61338f61461076f57600080fd5b8063c7bf8ca0146106fe578063d20406871461071157600080fd5b8063bd1f3a5e14610647578063bf48582b14610658578063bf7e214f1461066b578063c0aa0e8a1461068b57600080fd5b8063afa9d3b0116100f9578063afa9d3b01461050e578063b1283e771461051b578063bbbdd95a14610621578063bcf6cde81461063457600080fd5b8063946824cd146104495780639787d1071461046c578063acc5570c14610492578063ae418095146104fb57600080fd5b806357e333ba116101bd5780636729a41e1161018c5780637a9e5e4b116101715780637a9e5e4b146104035780638b098db3146104165780638da5cb5b1461042957600080fd5b80636729a41e146103bb578063699e17d9146103f157600080fd5b806357e333ba1461033c5780635dc4d16b1461034f5780635f77274e146103725780636352211e1461038557600080fd5b80633ad59dbc116101f95780633ad59dbc146102ac5780633adec5a7146102f357806344ee01721461031657806353c7f8e01461032957600080fd5b806310b053171461022b57806313af4035146102405780631c063a6c146102535780632750745814610289575b600080fd5b61023e6102393660046124ad565b610782565b005b61023e61024e3660046124f8565b61083d565b6102766102613660046124ad565b60009081526002602052604090206004015490565b6040519081526020015b60405180910390f35b61029c6102973660046124ad565b610946565b6040519015158152602001610280565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610280565b6102766103013660046124ad565b60009081526002602052604090206006015490565b61023e610324366004612534565b6109b3565b610276610337366004612551565b610aed565b61027661034a3660046124ad565b610b92565b61029c61035d3660046124f8565b60066020526000908152604090205460ff1681565b61023e6103803660046125dc565b610ca0565b6102ce6103933660046124ad565b60009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6102ce6103c93660046124ad565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61023e6103ff3660046125f9565b5050565b61023e6104113660046124f8565b610d65565b61029c6104243660046124ad565b610ec2565b6000546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b6102766104573660046124ad565b60009081526002602052604090206007015490565b7f00000000000000000000000000000000000000000000000000000000000000006102ce565b6104a56104a03660046124ad565b610f08565b6040805173ffffffffffffffffffffffffffffffffffffffff97881681529587166020870152938616938501939093529316606083015265ffffffffffff909216608082015260a081019190915260c001610280565b61023e6105093660046124ad565b61101b565b60055461029c9060ff1681565b6105ad6105293660046124ad565b6002602081905260009182526040909120805460018201549282015460038301546004840154600585015460068601546007870154600888015460099098015473ffffffffffffffffffffffffffffffffffffffff97881699881698968816978616967401000000000000000000000000000000000000000090960460ff1695908b565b6040805173ffffffffffffffffffffffffffffffffffffffff9c8d1681529a8c1660208c0152988b16988a0198909852989095166060880152921515608087015260a086019190915260c085015260e084015261010083015261012082019290925261014081019190915261016001610280565b61023e61062f36600461262c565b6110f9565b61023e610642366004612665565b6111e3565b61023e6106553660046126e3565b50565b610276610666366004612774565b611293565b6001546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b6106d56106993660046124ad565b60036020526000908152604090205465ffffffffffff80821691660100000000000081048216916c010000000000000000000000009091041683565b6040805165ffffffffffff94851681529284166020840152921691810191909152606001610280565b61027661070c366004612665565b6113e2565b60055461072890610100900465ffffffffffff1681565b60405165ffffffffffff9091168152602001610280565b60055461072890670100000000000000900465ffffffffffff1681565b61027661076a3660046127ad565b6115f3565b61023e61077d366004612534565b6118b9565b60008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146107df576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600090815260046020908152604080832054600290925290912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b61086b336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b6108d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60008181526002602052604081206004015415801590610988575060008281526003602052604090205465ffffffffffff428116660100000000000090920416115b80156109ad575060008281526003602052604090205465ffffffffffff428116911611155b92915050565b6109e1336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b610a47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b60055465ffffffffffff61010090910481169082161080610a725750620151808165ffffffffffff16105b15610aa9576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805465ffffffffffff909216670100000000000000027fffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffff909216919091179055565b600080610afc838501856127eb565b90508060e0015165ffffffffffff16600014158015610b4a5750620151808160e0015165ffffffffffff161080610b4a5750635dba240065ffffffffffff168160e0015165ffffffffffff16115b15610b81576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b8a81611b03565b949350505050565b60008181526002602081815260408084206006810154825161016081018452825473ffffffffffffffffffffffffffffffffffffffff9081168252600184015481169582019590955294820154841692850192909252600381015492831660608501527401000000000000000000000000000000000000000090920460ff16151560808401819052600483015460a0850152600583015460c085015260e084018290526007830154610100850152600883015461012085015260099092015461014084015291908390610c69578160a00151610c7e565b61010082015160a0830151610c7e91856123e1565b9050808260c0015111610c95578160c00151610c97565b805b95945050505050565b610cce336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b610d34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610e4857506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff0000000000000000000000000000000000000000000000000000000016604482015273ffffffffffffffffffffffffffffffffffffffff9091169063b700961390606401602060405180830381865afa158015610e24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4891906128b7565b610e5157600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b6000818152600360205260408120546c01000000000000000000000000900465ffffffffffff16635dba2400811115610efe5742811115610f01565b80155b9392505050565b6000818152600260208181526040808420815161016081018352815473ffffffffffffffffffffffffffffffffffffffff90811680835260018401548216838701819052968401548216838601819052600380860154938416606086018190527401000000000000000000000000000000000000000090940460ff1615156080860152600486015460a0860152600586015460c0860152600686015460e08601526007860154610100860152600886015461012086015260099095015461014085015289895293909552928620548695869586958695869594929391926c01000000000000000000000000900465ffffffffffff166110068d610b92565b949d939c50919a509850965090945092505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611078576040517f4e1c8b5d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260036020908152604080832080547fffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff1666010000000000004265ffffffffffff160217905560029091528082206004018290555182917f9dc30b8eda31a6a144e092e5de600955523a6a925cc15cc1d1b9b4872cfa615591a250565b611127336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b61118d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60008281526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611240576040517f4e1c8b5d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60009182526004602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6040517fb88c914800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000918291611361917f00000000000000000000000000000000000000000000000000000000000000009091169063b88c914890602401602060405180830381865afa15801561132a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134e91906128d4565b869065ffffffffffff16620186a06123e1565b600085815260026020526040812060078101546006909101549293509091611395919061138e858a612920565b91906123e1565b90506113a085610b92565b8111156113d9576040517f5c430eae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9150610f019050565b6000828152600260208181526040808420815161016081018352815473ffffffffffffffffffffffffffffffffffffffff9081168252600183015481168286015282860154811693820193909352600382015492831660608201527401000000000000000000000000000000000000000090920460ff1615156080830152600481015460a0830152600581015460c0830152600681015460e08301819052600782015461010084015260088201546101208401526009909101546101408301528685529290915290600082608001516114d05761010083015160a08401516114cb9184906123e1565b6114d6565b8260a001515b905060006114f8838561010001518660c001516123e19092919063ffffffff16565b90506000818310611509578161150b565b825b6040517fb88c914800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301529192506000916115da917f00000000000000000000000000000000000000000000000000000000000000009091169063b88c914890602401602060405180830381865afa1580156115a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c791906128d4565b839065ffffffffffff16620186a06123e1565b90506115e68183612937565b9998505050505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611664576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600260205260409020600381015473ffffffffffffffffffffffffffffffffffffffff16158015906116c25750805473ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205460ff16155b156116f9576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61170285610946565b611738576040517fa24c407400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007810154600682015461174d9186916123e1565b915082821015611789576040517f74ec9d5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600501548211156117c7576040517f5c430eae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600381015474010000000000000000000000000000000000000000900460ff166117f757806004015482116117ff565b806004015484115b15611836576040517ff3383dc900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600381015474010000000000000000000000000000000000000000900460ff166118605781611862565b835b8160040160008282546118759190612920565b92505081905550838160090160008282546118909190612937565b92505081905550818160080160008282546118ab9190612937565b909155509195945050505050565b6118e7336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b61194d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b60055465ffffffffffff6701000000000000009091048116908216118061197d5750610e108165ffffffffffff16105b156119b4576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805465ffffffffffff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ff909216919091179055565b60015460009073ffffffffffffffffffffffffffffffffffffffff168015801590611ad657506040517fb700961300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b700961390606401602060405180830381865afa158015611ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad691906128b7565b80610b8a575060005473ffffffffffffffffffffffffffffffffffffffff85811691161491505092915050565b60055460009060ff16611b42576040517f64be3ffa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826000015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb7919061294f565b90506000836020015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2e919061294f565b905060068260ff161080611c45575060128260ff16115b15611c7c576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60068160ff161080611c91575060128160ff16115b15611cc8576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe884610140015160000b1280611d065750601884610140015160000b135b15611d3d576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526006602052604090205460ff16158015611d765750604084015173ffffffffffffffffffffffffffffffffffffffff1615155b15611dad576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084610100015165ffffffffffff16118015611dd657504284610100015165ffffffffffff16105b15611e0d576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600082610140015160240160ff16600a0a90508260a00151600003611e60576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055461012084015165ffffffffffff670100000000000000909204821691161080611ea2575060055460c084015165ffffffffffff61010090920482169116105b80611ec5575082610120015165ffffffffffff168360c0015165ffffffffffff16115b15611efc576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611f448460c0015165ffffffffffff1685610120015165ffffffffffff168660600151611f2f57866080015161138e565b60a0870151608088015161138e9187906123e1565b845160208601516040517fb435914300000000000000000000000000000000000000000000000000000000815292935060009273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263b435914392611fe39260040173ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b6020604051808303816000875af1158015612002573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120269190612972565b90506040518061016001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001866000015173ffffffffffffffffffffffffffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152602001866040015173ffffffffffffffffffffffffffffffffffffffff168152602001866060015115158152602001866080015181526020018381526020018660a0015181526020018481526020016000815260200160008152506002600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060808201518160030160146101000a81548160ff02191690831515021790555060a0820151816004015560c0820151816005015560e08201518160060155610100820151816007015561012082015181600801556101408201518160090155905050600085610100015165ffffffffffff1660001461229b5785610100015161229d565b425b905060405180606001604052808265ffffffffffff168152602001876101200151836122c9919061298b565b65ffffffffffff908116825260e089018051821660209384015260008681526003845260409081902085518154878701519784015186166c01000000000000000000000000027fffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff9887166601000000000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090921692871692909217179690961695909517909455828a01518a51915160a08c015186519190941681529384019290925273ffffffffffffffffffffffffffffffffffffffff9182169391169185917f8235b14cd272b4e791960fe1118559bb7fed86934fcffeeae9b1175103b0756d910160405180910390a450949350505050565b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870985870292508281108382030391505080600003612438576000841161242d57600080fd5b508290049050610f01565b80841161244457600080fd5b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b6000602082840312156124bf57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461065557600080fd5b80356124f3816124c6565b919050565b60006020828403121561250a57600080fd5b8135610f01816124c6565b65ffffffffffff8116811461065557600080fd5b80356124f381612515565b60006020828403121561254657600080fd5b8135610f0181612515565b6000806020838503121561256457600080fd5b823567ffffffffffffffff8082111561257c57600080fd5b818501915085601f83011261259057600080fd5b81358181111561259f57600080fd5b8660208285010111156125b157600080fd5b60209290920196919550909350505050565b801515811461065557600080fd5b80356124f3816125c3565b6000602082840312156125ee57600080fd5b8135610f01816125c3565b6000806080838503121561260c57600080fd5b823591508360808401111561262057600080fd5b50926020919091019150565b6000806040838503121561263f57600080fd5b823561264a816124c6565b9150602083013561265a816125c3565b809150509250929050565b6000806040838503121561267857600080fd5b82359150602083013561265a816124c6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156126dd576126dd61268a565b60405290565b600060c082840312156126f557600080fd5b82601f83011261270457600080fd5b60405160c0810181811067ffffffffffffffff821117156127275761272761268a565b6040528060c084018581111561273c57600080fd5b845b8181101561276957803563ffffffff8116811461275b5760008081fd5b83526020928301920161273e565b509195945050505050565b60008060006060848603121561278957600080fd5b833592506020840135915060408401356127a2816124c6565b809150509250925092565b6000806000606084860312156127c257600080fd5b505081359360208301359350604090920135919050565b8035600081900b81146124f357600080fd5b600061016082840312156127fe57600080fd5b6128066126b9565b61280f836124e8565b815261281d602084016124e8565b602082015261282e604084016124e8565b604082015261283f606084016125d1565b60608201526080830135608082015260a083013560a082015261286460c08401612529565b60c082015261287560e08401612529565b60e0820152610100612888818501612529565b9082015261012061289a848201612529565b908201526101406128ac8482016127d9565b908201529392505050565b6000602082840312156128c957600080fd5b8151610f01816125c3565b6000602082840312156128e657600080fd5b8151610f0181612515565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612932576129326128f1565b500390565b6000821982111561294a5761294a6128f1565b500190565b60006020828403121561296157600080fd5b815160ff81168114610f0157600080fd5b60006020828403121561298457600080fd5b5051919050565b600065ffffffffffff8083168185168083038211156129ac576129ac6128f1565b0194935050505056fea26469706673582212200ed42efdf3a6fd5d906af04cc9375e8010d03a61d8e3525f88a223b73dc92db964736f6c634300080f0033000000000000000000000000007f7735baf391e207e3aa380bb53c4bd9a5fed6000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d1000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102265760003560e01c8063946824cd1161012a578063bd1f3a5e116100bd578063c7bf8ca01161008c578063d2bee32311610071578063d2bee3231461073f578063e007fa971461075c578063f61338f61461076f57600080fd5b8063c7bf8ca0146106fe578063d20406871461071157600080fd5b8063bd1f3a5e14610647578063bf48582b14610658578063bf7e214f1461066b578063c0aa0e8a1461068b57600080fd5b8063afa9d3b0116100f9578063afa9d3b01461050e578063b1283e771461051b578063bbbdd95a14610621578063bcf6cde81461063457600080fd5b8063946824cd146104495780639787d1071461046c578063acc5570c14610492578063ae418095146104fb57600080fd5b806357e333ba116101bd5780636729a41e1161018c5780637a9e5e4b116101715780637a9e5e4b146104035780638b098db3146104165780638da5cb5b1461042957600080fd5b80636729a41e146103bb578063699e17d9146103f157600080fd5b806357e333ba1461033c5780635dc4d16b1461034f5780635f77274e146103725780636352211e1461038557600080fd5b80633ad59dbc116101f95780633ad59dbc146102ac5780633adec5a7146102f357806344ee01721461031657806353c7f8e01461032957600080fd5b806310b053171461022b57806313af4035146102405780631c063a6c146102535780632750745814610289575b600080fd5b61023e6102393660046124ad565b610782565b005b61023e61024e3660046124f8565b61083d565b6102766102613660046124ad565b60009081526002602052604090206004015490565b6040519081526020015b60405180910390f35b61029c6102973660046124ad565b610946565b6040519015158152602001610280565b7f000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d15b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610280565b6102766103013660046124ad565b60009081526002602052604090206006015490565b61023e610324366004612534565b6109b3565b610276610337366004612551565b610aed565b61027661034a3660046124ad565b610b92565b61029c61035d3660046124f8565b60066020526000908152604090205460ff1681565b61023e6103803660046125dc565b610ca0565b6102ce6103933660046124ad565b60009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6102ce6103c93660046124ad565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61023e6103ff3660046125f9565b5050565b61023e6104113660046124f8565b610d65565b61029c6104243660046124ad565b610ec2565b6000546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b6102766104573660046124ad565b60009081526002602052604090206007015490565b7f000000000000000000000000007f7735baf391e207e3aa380bb53c4bd9a5fed66102ce565b6104a56104a03660046124ad565b610f08565b6040805173ffffffffffffffffffffffffffffffffffffffff97881681529587166020870152938616938501939093529316606083015265ffffffffffff909216608082015260a081019190915260c001610280565b61023e6105093660046124ad565b61101b565b60055461029c9060ff1681565b6105ad6105293660046124ad565b6002602081905260009182526040909120805460018201549282015460038301546004840154600585015460068601546007870154600888015460099098015473ffffffffffffffffffffffffffffffffffffffff97881699881698968816978616967401000000000000000000000000000000000000000090960460ff1695908b565b6040805173ffffffffffffffffffffffffffffffffffffffff9c8d1681529a8c1660208c0152988b16988a0198909852989095166060880152921515608087015260a086019190915260c085015260e084015261010083015261012082019290925261014081019190915261016001610280565b61023e61062f36600461262c565b6110f9565b61023e610642366004612665565b6111e3565b61023e6106553660046126e3565b50565b610276610666366004612774565b611293565b6001546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b6106d56106993660046124ad565b60036020526000908152604090205465ffffffffffff80821691660100000000000081048216916c010000000000000000000000009091041683565b6040805165ffffffffffff94851681529284166020840152921691810191909152606001610280565b61027661070c366004612665565b6113e2565b60055461072890610100900465ffffffffffff1681565b60405165ffffffffffff9091168152602001610280565b60055461072890670100000000000000900465ffffffffffff1681565b61027661076a3660046127ad565b6115f3565b61023e61077d366004612534565b6118b9565b60008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146107df576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600090815260046020908152604080832054600290925290912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b61086b336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b6108d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60008181526002602052604081206004015415801590610988575060008281526003602052604090205465ffffffffffff428116660100000000000090920416115b80156109ad575060008281526003602052604090205465ffffffffffff428116911611155b92915050565b6109e1336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b610a47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b60055465ffffffffffff61010090910481169082161080610a725750620151808165ffffffffffff16105b15610aa9576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805465ffffffffffff909216670100000000000000027fffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffff909216919091179055565b600080610afc838501856127eb565b90508060e0015165ffffffffffff16600014158015610b4a5750620151808160e0015165ffffffffffff161080610b4a5750635dba240065ffffffffffff168160e0015165ffffffffffff16115b15610b81576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b8a81611b03565b949350505050565b60008181526002602081815260408084206006810154825161016081018452825473ffffffffffffffffffffffffffffffffffffffff9081168252600184015481169582019590955294820154841692850192909252600381015492831660608501527401000000000000000000000000000000000000000090920460ff16151560808401819052600483015460a0850152600583015460c085015260e084018290526007830154610100850152600883015461012085015260099092015461014084015291908390610c69578160a00151610c7e565b61010082015160a0830151610c7e91856123e1565b9050808260c0015111610c95578160c00151610c97565b805b95945050505050565b610cce336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b610d34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610e4857506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff0000000000000000000000000000000000000000000000000000000016604482015273ffffffffffffffffffffffffffffffffffffffff9091169063b700961390606401602060405180830381865afa158015610e24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4891906128b7565b610e5157600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b6000818152600360205260408120546c01000000000000000000000000900465ffffffffffff16635dba2400811115610efe5742811115610f01565b80155b9392505050565b6000818152600260208181526040808420815161016081018352815473ffffffffffffffffffffffffffffffffffffffff90811680835260018401548216838701819052968401548216838601819052600380860154938416606086018190527401000000000000000000000000000000000000000090940460ff1615156080860152600486015460a0860152600586015460c0860152600686015460e08601526007860154610100860152600886015461012086015260099095015461014085015289895293909552928620548695869586958695869594929391926c01000000000000000000000000900465ffffffffffff166110068d610b92565b949d939c50919a509850965090945092505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611078576040517f4e1c8b5d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260036020908152604080832080547fffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff1666010000000000004265ffffffffffff160217905560029091528082206004018290555182917f9dc30b8eda31a6a144e092e5de600955523a6a925cc15cc1d1b9b4872cfa615591a250565b611127336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b61118d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60008281526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611240576040517f4e1c8b5d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60009182526004602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6040517fb88c914800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000918291611361917f000000000000000000000000007f7735baf391e207e3aa380bb53c4bd9a5fed69091169063b88c914890602401602060405180830381865afa15801561132a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134e91906128d4565b869065ffffffffffff16620186a06123e1565b600085815260026020526040812060078101546006909101549293509091611395919061138e858a612920565b91906123e1565b90506113a085610b92565b8111156113d9576040517f5c430eae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9150610f019050565b6000828152600260208181526040808420815161016081018352815473ffffffffffffffffffffffffffffffffffffffff9081168252600183015481168286015282860154811693820193909352600382015492831660608201527401000000000000000000000000000000000000000090920460ff1615156080830152600481015460a0830152600581015460c0830152600681015460e08301819052600782015461010084015260088201546101208401526009909101546101408301528685529290915290600082608001516114d05761010083015160a08401516114cb9184906123e1565b6114d6565b8260a001515b905060006114f8838561010001518660c001516123e19092919063ffffffff16565b90506000818310611509578161150b565b825b6040517fb88c914800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301529192506000916115da917f000000000000000000000000007f7735baf391e207e3aa380bb53c4bd9a5fed69091169063b88c914890602401602060405180830381865afa1580156115a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c791906128d4565b839065ffffffffffff16620186a06123e1565b90506115e68183612937565b9998505050505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000007f7735baf391e207e3aa380bb53c4bd9a5fed61614611664576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600260205260409020600381015473ffffffffffffffffffffffffffffffffffffffff16158015906116c25750805473ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205460ff16155b156116f9576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61170285610946565b611738576040517fa24c407400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007810154600682015461174d9186916123e1565b915082821015611789576040517f74ec9d5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600501548211156117c7576040517f5c430eae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600381015474010000000000000000000000000000000000000000900460ff166117f757806004015482116117ff565b806004015484115b15611836576040517ff3383dc900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600381015474010000000000000000000000000000000000000000900460ff166118605781611862565b835b8160040160008282546118759190612920565b92505081905550838160090160008282546118909190612937565b92505081905550818160080160008282546118ab9190612937565b909155509195945050505050565b6118e7336000357fffffffff00000000000000000000000000000000000000000000000000000000166119f2565b61194d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016108cd565b60055465ffffffffffff6701000000000000009091048116908216118061197d5750610e108165ffffffffffff16105b156119b4576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805465ffffffffffff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ff909216919091179055565b60015460009073ffffffffffffffffffffffffffffffffffffffff168015801590611ad657506040517fb700961300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b700961390606401602060405180830381865afa158015611ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad691906128b7565b80610b8a575060005473ffffffffffffffffffffffffffffffffffffffff85811691161491505092915050565b60055460009060ff16611b42576040517f64be3ffa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826000015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb7919061294f565b90506000836020015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2e919061294f565b905060068260ff161080611c45575060128260ff16115b15611c7c576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60068160ff161080611c91575060128160ff16115b15611cc8576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe884610140015160000b1280611d065750601884610140015160000b135b15611d3d576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526006602052604090205460ff16158015611d765750604084015173ffffffffffffffffffffffffffffffffffffffff1615155b15611dad576040517f2c47703200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084610100015165ffffffffffff16118015611dd657504284610100015165ffffffffffff16105b15611e0d576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600082610140015160240160ff16600a0a90508260a00151600003611e60576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055461012084015165ffffffffffff670100000000000000909204821691161080611ea2575060055460c084015165ffffffffffff61010090920482169116105b80611ec5575082610120015165ffffffffffff168360c0015165ffffffffffff16115b15611efc576040517f3b596f5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611f448460c0015165ffffffffffff1685610120015165ffffffffffff168660600151611f2f57866080015161138e565b60a0870151608088015161138e9187906123e1565b845160208601516040517fb435914300000000000000000000000000000000000000000000000000000000815292935060009273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d1169263b435914392611fe39260040173ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b6020604051808303816000875af1158015612002573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120269190612972565b90506040518061016001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001866000015173ffffffffffffffffffffffffffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152602001866040015173ffffffffffffffffffffffffffffffffffffffff168152602001866060015115158152602001866080015181526020018381526020018660a0015181526020018481526020016000815260200160008152506002600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060808201518160030160146101000a81548160ff02191690831515021790555060a0820151816004015560c0820151816005015560e08201518160060155610100820151816007015561012082015181600801556101408201518160090155905050600085610100015165ffffffffffff1660001461229b5785610100015161229d565b425b905060405180606001604052808265ffffffffffff168152602001876101200151836122c9919061298b565b65ffffffffffff908116825260e089018051821660209384015260008681526003845260409081902085518154878701519784015186166c01000000000000000000000000027fffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff9887166601000000000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090921692871692909217179690961695909517909455828a01518a51915160a08c015186519190941681529384019290925273ffffffffffffffffffffffffffffffffffffffff9182169391169185917f8235b14cd272b4e791960fe1118559bb7fed86934fcffeeae9b1175103b0756d910160405180910390a450949350505050565b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870985870292508281108382030391505080600003612438576000841161242d57600080fd5b508290049050610f01565b80841161244457600080fd5b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b6000602082840312156124bf57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461065557600080fd5b80356124f3816124c6565b919050565b60006020828403121561250a57600080fd5b8135610f01816124c6565b65ffffffffffff8116811461065557600080fd5b80356124f381612515565b60006020828403121561254657600080fd5b8135610f0181612515565b6000806020838503121561256457600080fd5b823567ffffffffffffffff8082111561257c57600080fd5b818501915085601f83011261259057600080fd5b81358181111561259f57600080fd5b8660208285010111156125b157600080fd5b60209290920196919550909350505050565b801515811461065557600080fd5b80356124f3816125c3565b6000602082840312156125ee57600080fd5b8135610f01816125c3565b6000806080838503121561260c57600080fd5b823591508360808401111561262057600080fd5b50926020919091019150565b6000806040838503121561263f57600080fd5b823561264a816124c6565b9150602083013561265a816125c3565b809150509250929050565b6000806040838503121561267857600080fd5b82359150602083013561265a816124c6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156126dd576126dd61268a565b60405290565b600060c082840312156126f557600080fd5b82601f83011261270457600080fd5b60405160c0810181811067ffffffffffffffff821117156127275761272761268a565b6040528060c084018581111561273c57600080fd5b845b8181101561276957803563ffffffff8116811461275b5760008081fd5b83526020928301920161273e565b509195945050505050565b60008060006060848603121561278957600080fd5b833592506020840135915060408401356127a2816124c6565b809150509250925092565b6000806000606084860312156127c257600080fd5b505081359360208301359350604090920135919050565b8035600081900b81146124f357600080fd5b600061016082840312156127fe57600080fd5b6128066126b9565b61280f836124e8565b815261281d602084016124e8565b602082015261282e604084016124e8565b604082015261283f606084016125d1565b60608201526080830135608082015260a083013560a082015261286460c08401612529565b60c082015261287560e08401612529565b60e0820152610100612888818501612529565b9082015261012061289a848201612529565b908201526101406128ac8482016127d9565b908201529392505050565b6000602082840312156128c957600080fd5b8151610f01816125c3565b6000602082840312156128e657600080fd5b8151610f0181612515565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612932576129326128f1565b500390565b6000821982111561294a5761294a6128f1565b500190565b60006020828403121561296157600080fd5b815160ff81168114610f0157600080fd5b60006020828403121561298457600080fd5b5051919050565b600065ffffffffffff8083168185168083038211156129ac576129ac6128f1565b0194935050505056fea26469706673582212200ed42efdf3a6fd5d906af04cc9375e8010d03a61d8e3525f88a223b73dc92db964736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000007f7735baf391e207e3aa380bb53c4bd9a5fed6000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d1000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14
-----Decoded View---------------
Arg [0] : teller_ (address): 0x007F7735baF391e207E3aA380bb53c4Bd9a5Fed6
Arg [1] : aggregator_ (address): 0x007A66A2a13415DB3613C1a4dd1C942A285902d1
Arg [2] : guardian_ (address): 0x007BD11FCa0dAaeaDD455b51826F9a015f2f0969
Arg [3] : authority_ (address): 0x007A0F48A4e3d74Ab4234adf9eA9EB32f87b4b14
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000007f7735baf391e207e3aa380bb53c4bd9a5fed6
Arg [1] : 000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d1
Arg [2] : 000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969
Arg [3] : 000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.