Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 15998036 | 1159 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BondAggregator
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 {ERC20} from "solmate/tokens/ERC20.sol";
import {Auth, Authority} from "solmate/auth/Auth.sol";
import {IBondAggregator} from "./interfaces/IBondAggregator.sol";
import {IBondTeller} from "./interfaces/IBondTeller.sol";
import {IBondAuctioneer} from "./interfaces/IBondAuctioneer.sol";
import {FullMath} from "./lib/FullMath.sol";
/// @title Bond Aggregator
/// @notice Bond Aggregator Contract
/// @dev Bond Protocol is a permissionless system to create Olympus-style bond markets
/// for any token pair. The markets do not require maintenance and will manage
/// bond prices based on activity. Bond issuers create BondMarkets that pay out
/// a Payout Token in exchange for deposited Quote Tokens. Users can purchase
/// future-dated Payout Tokens with Quote Tokens at the current market price and
/// receive Bond Tokens to represent their position while their bond vests.
/// Once the Bond Tokens vest, they can redeem it for the Quote Tokens.
///
/// @dev The Aggregator contract keeps a unique set of market IDs across multiple
/// Tellers and Auctioneers. Additionally, it aggregates market data from
/// multiple Auctioneers in convenient view functions for front-end interfaces.
/// The Aggregator contract should be deployed first since Tellers, Auctioneers, and
/// Callbacks all require it in their constructors.
///
/// @author Oighty, Zeus, Potted Meat, indigo
contract BondAggregator is IBondAggregator, Auth {
using FullMath for uint256;
/* ========== ERRORS ========== */
error Aggregator_OnlyAuctioneer();
error Aggregator_AlreadyRegistered(address auctioneer_);
error Aggregator_InvalidParams();
/* ========== STATE VARIABLES ========== */
/// @notice Counter for bond markets on approved auctioneers
uint256 public marketCounter;
/// @notice Approved auctioneers
IBondAuctioneer[] public auctioneers;
mapping(address => bool) internal _whitelist;
/// @notice Auctioneer for Market ID
mapping(uint256 => IBondAuctioneer) public marketsToAuctioneers;
/// @notice Market IDs for payout token
mapping(address => uint256[]) public marketsForPayout;
/// @notice Market IDs for quote token
mapping(address => uint256[]) public marketsForQuote;
// A 'vesting' param longer than 50 years is considered a timestamp for fixed expiry.
uint48 private constant MAX_FIXED_TERM = 52 weeks * 50;
constructor(address guardian_, Authority authority_) Auth(guardian_, authority_) {}
/// @inheritdoc IBondAggregator
function registerAuctioneer(IBondAuctioneer auctioneer_) external requiresAuth {
// Restricted to authorized addresses
// Check that the auctioneer is not already registered
if (_whitelist[address(auctioneer_)])
revert Aggregator_AlreadyRegistered(address(auctioneer_));
// Add the auctioneer to the whitelist
auctioneers.push(auctioneer_);
_whitelist[address(auctioneer_)] = true;
}
/// @inheritdoc IBondAggregator
function registerMarket(ERC20 payoutToken_, ERC20 quoteToken_)
external
override
returns (uint256 marketId)
{
if (!_whitelist[msg.sender]) revert Aggregator_OnlyAuctioneer();
if (address(payoutToken_) == address(0) || address(quoteToken_) == address(0))
revert Aggregator_InvalidParams();
marketId = marketCounter;
marketsToAuctioneers[marketId] = IBondAuctioneer(msg.sender);
marketsForPayout[address(payoutToken_)].push(marketId);
marketsForQuote[address(quoteToken_)].push(marketId);
++marketCounter;
}
/* ========== VIEW FUNCTIONS ========== */
/// @inheritdoc IBondAggregator
function getAuctioneer(uint256 id_) external view returns (IBondAuctioneer) {
return marketsToAuctioneers[id_];
}
/// @inheritdoc IBondAggregator
function marketPrice(uint256 id_) public view override returns (uint256) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.marketPrice(id_);
}
/// @inheritdoc IBondAggregator
function marketScale(uint256 id_) external view override returns (uint256) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.marketScale(id_);
}
/// @inheritdoc IBondAggregator
function payoutFor(
uint256 amount_,
uint256 id_,
address referrer_
) public view override returns (uint256) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.payoutFor(amount_, id_, referrer_);
}
/// @inheritdoc IBondAggregator
function maxAmountAccepted(uint256 id_, address referrer_) external view returns (uint256) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.maxAmountAccepted(id_, referrer_);
}
/// @inheritdoc IBondAggregator
function isInstantSwap(uint256 id_) external view returns (bool) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.isInstantSwap(id_);
}
/// @inheritdoc IBondAggregator
function isLive(uint256 id_) public view override returns (bool) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.isLive(id_);
}
/// @inheritdoc IBondAggregator
function liveMarketsBetween(uint256 firstIndex_, uint256 lastIndex_)
external
view
override
returns (uint256[] memory)
{
uint256 count;
for (uint256 i = firstIndex_; i < lastIndex_; ++i) {
if (isLive(i)) ++count;
}
uint256[] memory ids = new uint256[](count);
count = 0;
for (uint256 i = firstIndex_; i < lastIndex_; ++i) {
if (isLive(i)) {
ids[count] = i;
++count;
}
}
return ids;
}
/// @inheritdoc IBondAggregator
function liveMarketsFor(address token_, bool isPayout_)
public
view
override
returns (uint256[] memory)
{
uint256[] memory mkts;
mkts = isPayout_ ? marketsForPayout[token_] : marketsForQuote[token_];
uint256 count;
uint256 len = mkts.length;
for (uint256 i; i < len; ++i) {
if (isLive(mkts[i])) ++count;
}
uint256[] memory ids = new uint256[](count);
count = 0;
for (uint256 i; i < len; ++i) {
if (isLive(mkts[i])) {
ids[count] = mkts[i];
++count;
}
}
return ids;
}
/// @inheritdoc IBondAggregator
function marketsFor(address payout_, address quote_) public view returns (uint256[] memory) {
uint256[] memory forPayout = liveMarketsFor(payout_, true);
uint256 count;
ERC20 quoteToken;
IBondAuctioneer auctioneer;
uint256 len = forPayout.length;
for (uint256 i; i < len; ++i) {
auctioneer = marketsToAuctioneers[forPayout[i]];
(, , , quoteToken, , ) = auctioneer.getMarketInfoForPurchase(forPayout[i]);
if (isLive(forPayout[i]) && address(quoteToken) == quote_) ++count;
}
uint256[] memory ids = new uint256[](count);
count = 0;
for (uint256 i; i < len; ++i) {
auctioneer = marketsToAuctioneers[forPayout[i]];
(, , , quoteToken, , ) = auctioneer.getMarketInfoForPurchase(forPayout[i]);
if (isLive(forPayout[i]) && address(quoteToken) == quote_) {
ids[count] = forPayout[i];
++count;
}
}
return ids;
}
/// @inheritdoc IBondAggregator
function findMarketFor(
address payout_,
address quote_,
uint256 amountIn_,
uint256 minAmountOut_,
uint256 maxExpiry_
) external view returns (uint256) {
uint256[] memory ids = marketsFor(payout_, quote_);
uint256 len = ids.length;
// uint256[] memory payouts = new uint256[](len);
uint256 highestOut;
uint256 id = type(uint256).max; // set to max so an empty set doesn't return 0, the first index
uint48 vesting;
uint256 maxPayout;
IBondAuctioneer auctioneer;
for (uint256 i; i < len; ++i) {
auctioneer = marketsToAuctioneers[ids[i]];
(, , , , vesting, maxPayout) = auctioneer.getMarketInfoForPurchase(ids[i]);
uint256 expiry = (vesting <= MAX_FIXED_TERM) ? block.timestamp + vesting : vesting;
if (expiry <= maxExpiry_) {
if (minAmountOut_ <= maxPayout) {
try auctioneer.payoutFor(amountIn_, ids[i], address(0)) returns (
uint256 payout
) {
if (payout > highestOut && payout >= minAmountOut_) {
highestOut = payout;
id = ids[i];
}
} catch {
// fail silently and try the next market
}
}
}
}
return id;
}
/// @inheritdoc IBondAggregator
function liveMarketsBy(
address owner_,
uint256 firstIndex_,
uint256 lastIndex_
) external view returns (uint256[] memory) {
uint256 count;
IBondAuctioneer auctioneer;
for (uint256 i = firstIndex_; i < lastIndex_; ++i) {
auctioneer = marketsToAuctioneers[i];
if (auctioneer.isLive(i) && auctioneer.ownerOf(i) == owner_) {
++count;
}
}
uint256[] memory ids = new uint256[](count);
count = 0;
for (uint256 j = firstIndex_; j < lastIndex_; ++j) {
auctioneer = marketsToAuctioneers[j];
if (auctioneer.isLive(j) && auctioneer.ownerOf(j) == owner_) {
ids[count] = j;
++count;
}
}
return ids;
}
/// @inheritdoc IBondAggregator
function getTeller(uint256 id_) external view returns (IBondTeller) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.getTeller();
}
/// @inheritdoc IBondAggregator
function currentCapacity(uint256 id_) external view returns (uint256) {
IBondAuctioneer auctioneer = marketsToAuctioneers[id_];
return auctioneer.currentCapacity(id_);
}
}// 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.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 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++;
}
}
}
}{
"remappings": [
"clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
"clones/=lib/clones-with-immutable-args/src/",
"ds-test/=lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"hardhat/=node_modules/hardhat/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"solidity-code-metrics/=node_modules/solidity-code-metrics/",
"solmate/=lib/solmate/src/",
"weird-erc20/=lib/solmate/lib/weird-erc20/src/"
],
"optimizer": {
"enabled": true,
"runs": 100000
},
"metadata": {
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"guardian_","type":"address"},{"internalType":"contract Authority","name":"authority_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"auctioneer_","type":"address"}],"name":"Aggregator_AlreadyRegistered","type":"error"},{"inputs":[],"name":"Aggregator_InvalidParams","type":"error"},{"inputs":[],"name":"Aggregator_OnlyAuctioneer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctioneers","outputs":[{"internalType":"contract IBondAuctioneer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"currentCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"payout_","type":"address"},{"internalType":"address","name":"quote_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"uint256","name":"minAmountOut_","type":"uint256"},{"internalType":"uint256","name":"maxExpiry_","type":"uint256"}],"name":"findMarketFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"getAuctioneer","outputs":[{"internalType":"contract IBondAuctioneer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"getTeller","outputs":[{"internalType":"contract IBondTeller","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"isInstantSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"isLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"firstIndex_","type":"uint256"},{"internalType":"uint256","name":"lastIndex_","type":"uint256"}],"name":"liveMarketsBetween","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"firstIndex_","type":"uint256"},{"internalType":"uint256","name":"lastIndex_","type":"uint256"}],"name":"liveMarketsBy","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"bool","name":"isPayout_","type":"bool"}],"name":"liveMarketsFor","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"marketPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"marketScale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"payout_","type":"address"},{"internalType":"address","name":"quote_","type":"address"}],"name":"marketsFor","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketsForPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketsForQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketsToAuctioneers","outputs":[{"internalType":"contract IBondAuctioneer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"address","name":"referrer_","type":"address"}],"name":"maxAmountAccepted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"address","name":"referrer_","type":"address"}],"name":"payoutFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IBondAuctioneer","name":"auctioneer_","type":"address"}],"name":"registerAuctioneer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"payoutToken_","type":"address"},{"internalType":"contract ERC20","name":"quoteToken_","type":"address"}],"name":"registerMarket","outputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200216a3803806200216a8339810160408190526200003491620000e8565b600080546001600160a01b03199081166001600160a01b0385811691821784556001805490931690851617909155604051849284929133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7691a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a35050505062000127565b6001600160a01b0381168114620000e557600080fd5b50565b60008060408385031215620000fc57600080fd5b82516200010981620000cf565b60208401519092506200011c81620000cf565b809150509250929050565b61203380620001376000396000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80638da5cb5b116100ee578063bf48582b11610097578063c3b7b13611610071578063c3b7b136146103c1578063c7bf8ca0146103d4578063ea5e0c60146103e7578063f9e709df1461041d57600080fd5b8063bf48582b1461037b578063bf7e214f1461038e578063c0680e20146103ae57600080fd5b8063b4359143116100c8578063b435914314610342578063bb6e75de14610355578063bbfe3a321461036857600080fd5b80638da5cb5b146102fc578063946824cd1461031c5780639a0fae9b1461032f57600080fd5b80634938a3fe1161015057806378b5a87a1161012a57806378b5a87a146102c35780637a9e5e4b146102d65780638b098db3146102e957600080fd5b80634938a3fe14610235578063520479421461025557806366b382ee146102b057600080fd5b8063247608071161018157806324760807146101f657806327507458146101ff5780633adec5a71461022257600080fd5b806306b40ea3146101a857806313af4035146101ce5780631c063a6c146101e3575b600080fd5b6101bb6101b6366004611c24565b610430565b6040519081526020015b60405180910390f35b6101e16101dc366004611c50565b610461565b005b6101bb6101f1366004611c6d565b61056a565b6101bb60025481565b61021261020d366004611c6d565b610613565b60405190151581526020016101c5565b6101bb610230366004611c6d565b6106b5565b610248610243366004611c86565b61071a565b6040516101c59190611cbb565b61028b610263366004611c6d565b60009081526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c5565b6101e16102be366004611c50565b610a96565b61028b6102d1366004611c6d565b610c4c565b6101e16102e4366004611c50565b610cea565b6102126102f7366004611c6d565b610e47565b60005461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101bb61032a366004611c6d565b610eac565b6101bb61033d366004611cff565b610f11565b6101bb610350366004611d50565b6111ba565b610248610363366004611d89565b611317565b610248610376366004611d50565b6113f6565b6101bb610389366004611dab565b61177c565b60015461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101bb6103bc366004611c24565b611835565b61028b6103cf366004611c6d565b611851565b6101bb6103e2366004611de4565b611888565b61028b6103f5366004611c6d565b60056020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61024861042b366004611e17565b611939565b6006602052816000526040600020818154811061044c57600080fd5b90600052602060002001600091509150505481565b61048f336000357fffffffff0000000000000000000000000000000000000000000000000000000016611aee565b6104fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b6000818152600560205260408082205490517f1c063a6c0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190631c063a6c906024015b602060405180830381865afa1580156105e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e45565b9392505050565b6000818152600560205260408082205490517f275074580000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169081906327507458906024015b602060405180830381865afa158015610691573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e5e565b6000818152600560205260408082205490517f3adec5a70000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190633adec5a7906024016105cb565b6060600080845b848110156108a057600081815260056020526040908190205490517f275074580000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff90911692508290632750745890602401602060405180830381865afa1580156107a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cc9190611e5e565b801561087f57506040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8089169190841690636352211e90602401602060405180830381865afa158015610843573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108679190611e7b565b73ffffffffffffffffffffffffffffffffffffffff16145b156108905761088d83611ec7565b92505b61089981611ec7565b9050610721565b5060008267ffffffffffffffff8111156108bc576108bc611eff565b6040519080825280602002602001820160405280156108e5578160200160208202803683370190505b50600093509050855b85811015610a8b57600081815260056020526040908190205490517f275074580000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff90911693508390632750745890602401602060405180830381865afa158015610975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109999190611e5e565b8015610a4c57506040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff808a169190851690636352211e90602401602060405180830381865afa158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a349190611e7b565b73ffffffffffffffffffffffffffffffffffffffff16145b15610a7b5780828581518110610a6457610a64611f2e565b6020908102919091010152610a7884611ec7565b93505b610a8481611ec7565b90506108ee565b509695505050505050565b610ac4336000357fffffffff0000000000000000000000000000000000000000000000000000000016611aee565b610b2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016104f1565b73ffffffffffffffffffffffffffffffffffffffff811660009081526004602052604090205460ff1615610ba2576040517fcba9dee200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104f1565b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff9093167fffffffffffffffffffffffff00000000000000000000000000000000000000009093168317905560009182526004602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055565b60008181526005602090815260408083205481517f9787d107000000000000000000000000000000000000000000000000000000008152915173ffffffffffffffffffffffffffffffffffffffff909116928392639787d10792600480830193928290030181865afa158015610cc6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e7b565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610dcd57506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff0000000000000000000000000000000000000000000000000000000016604482015273ffffffffffffffffffffffffffffffffffffffff9091169063b700961390606401602060405180830381865afa158015610da9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcd9190611e5e565b610dd657600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b6000818152600560205260408082205490517f8b098db30000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190638b098db390602401610674565b6000818152600560205260408082205490517f946824cd0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff90911690819063946824cd906024016105cb565b600080610f1e87876113f6565b805190915060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818080805b868110156111a85760056000898381518110610f6957610f69611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508173ffffffffffffffffffffffffffffffffffffffff1663acc5570c898381518110610fd057610fd0611f2e565b60200260200101516040518263ffffffff1660e01b8152600401610ff691815260200190565b60c060405180830381865afa158015611013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110379190611f5d565b9098509650600093505050635dba240065ffffffffffff871611159050611066578465ffffffffffff16611078565b61107865ffffffffffff861642611fe5565b90508a811161119757838c11611197578273ffffffffffffffffffffffffffffffffffffffff1663bf48582b8e8b85815181106110b7576110b7611f2e565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015260006044820152606401602060405180830381865afa92505050801561115c575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261115991810190611e45565b60015b1561119757878111801561117057508c8110155b156111955780975089838151811061118a5761118a611f2e565b602002602001015196505b505b506111a181611ec7565b9050610f4b565b50929c9b505050505050505050505050565b3360009081526004602052604081205460ff16611203576040517f8feeaaa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316158061123a575073ffffffffffffffffffffffffffffffffffffffff8216155b15611271576040517f018c362a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060028054600081815260056020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905573ffffffffffffffffffffffffffffffffffffffff8781168452600683528184208054600181810183559186528486200186905590871684526007835290832080549182018155835290822001829055825491929161130d90611ec7565b9091555092915050565b60606000835b8381101561134f5761132e81610613565b1561133f5761133c82611ec7565b91505b61134881611ec7565b905061131d565b5060008167ffffffffffffffff81111561136b5761136b611eff565b604051908082528060200260200182016040528015611394578160200160208202803683370190505b50600092509050845b848110156113ed576113ae81610613565b156113dd57808284815181106113c6576113c6611f2e565b60209081029190910101526113da83611ec7565b92505b6113e681611ec7565b905061139d565b50949350505050565b60606000611405846001611939565b90506000806000808451905060005b81811015611585576005600087838151811061143257611432611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692508273ffffffffffffffffffffffffffffffffffffffff1663acc5570c87838151811061149957611499611f2e565b60200260200101516040518263ffffffff1660e01b81526004016114bf91815260200190565b60c060405180830381865afa1580156114dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115009190611f5d565b5050895190975061152d9350899250849150811061152057611520611f2e565b6020026020010151610613565b801561156457508773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b156115755761157285611ec7565b94505b61157e81611ec7565b9050611414565b5060008467ffffffffffffffff8111156115a1576115a1611eff565b6040519080825280602002602001820160405280156115ca578160200160208202803683370190505b5090506000945060005b8281101561176f57600560008883815181106115f2576115f2611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1693508373ffffffffffffffffffffffffffffffffffffffff1663acc5570c88838151811061165957611659611f2e565b60200260200101516040518263ffffffff1660e01b815260040161167f91815260200190565b60c060405180830381865afa15801561169c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c09190611f5d565b50508a519098506116e093508a9250849150811061152057611520611f2e565b801561171757508873ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b1561175f5786818151811061172e5761172e611f2e565b602002602001015182878151811061174857611748611f2e565b602090810291909101015261175c86611ec7565b95505b61176881611ec7565b90506115d4565b5098975050505050505050565b6000828152600560205260408082205490517fbf48582b000000000000000000000000000000000000000000000000000000008152600481018690526024810185905273ffffffffffffffffffffffffffffffffffffffff848116604483015290911690819063bf48582b90606401602060405180830381865afa158015611808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182c9190611e45565b95945050505050565b6007602052816000526040600020818154811061044c57600080fd5b6003818154811061186157600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000828152600560205260408082205490517fc7bf8ca00000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff848116602483015290911690819063c7bf8ca090604401602060405180830381865afa15801561190d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119319190611e45565b949350505050565b6060808261196b5773ffffffffffffffffffffffffffffffffffffffff84166000908152600760205260409020611991565b73ffffffffffffffffffffffffffffffffffffffff841660009081526006602052604090205b8054806020026020016040519081016040528092919081815260200182805480156119db57602002820191906000526020600020905b8154815260200190600101908083116119c7575b505050505090506000808251905060005b81811015611a2a57611a0984828151811061152057611520611f2e565b15611a1a57611a1783611ec7565b92505b611a2381611ec7565b90506119ec565b5060008267ffffffffffffffff811115611a4657611a46611eff565b604051908082528060200260200182016040528015611a6f578160200160208202803683370190505b5090506000925060005b82811015610a8b57611a9685828151811061152057611520611f2e565b15611ade57848181518110611aad57611aad611f2e565b6020026020010151828581518110611ac757611ac7611f2e565b6020908102919091010152611adb84611ec7565b93505b611ae781611ec7565b9050611a79565b60015460009073ffffffffffffffffffffffffffffffffffffffff168015801590611bd257506040517fb700961300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b700961390606401602060405180830381865afa158015611bae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd29190611e5e565b80611931575060005473ffffffffffffffffffffffffffffffffffffffff85811691161491505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c2157600080fd5b50565b60008060408385031215611c3757600080fd5b8235611c4281611bff565b946020939093013593505050565b600060208284031215611c6257600080fd5b813561060c81611bff565b600060208284031215611c7f57600080fd5b5035919050565b600080600060608486031215611c9b57600080fd5b8335611ca681611bff565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611cf357835183529284019291840191600101611cd7565b50909695505050505050565b600080600080600060a08688031215611d1757600080fd5b8535611d2281611bff565b94506020860135611d3281611bff565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215611d6357600080fd5b8235611d6e81611bff565b91506020830135611d7e81611bff565b809150509250929050565b60008060408385031215611d9c57600080fd5b50508035926020909101359150565b600080600060608486031215611dc057600080fd5b83359250602084013591506040840135611dd981611bff565b809150509250925092565b60008060408385031215611df757600080fd5b823591506020830135611d7e81611bff565b8015158114611c2157600080fd5b60008060408385031215611e2a57600080fd5b8235611e3581611bff565b91506020830135611d7e81611e09565b600060208284031215611e5757600080fd5b5051919050565b600060208284031215611e7057600080fd5b815161060c81611e09565b600060208284031215611e8d57600080fd5b815161060c81611bff565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ef857611ef8611e98565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060008060008060c08789031215611f7657600080fd5b8651611f8181611bff565b6020880151909650611f9281611bff565b6040880151909550611fa381611bff565b6060880151909450611fb481611bff565b608088015190935065ffffffffffff81168114611fd057600080fd5b8092505060a087015190509295509295509295565b60008219821115611ff857611ff8611e98565b50019056fea2646970667358221220ba286c6d6ce9c50ea976df0013cb65eb875fdf24af038e02dcb81b114cf03fd864736f6c634300080f0033000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101a35760003560e01c80638da5cb5b116100ee578063bf48582b11610097578063c3b7b13611610071578063c3b7b136146103c1578063c7bf8ca0146103d4578063ea5e0c60146103e7578063f9e709df1461041d57600080fd5b8063bf48582b1461037b578063bf7e214f1461038e578063c0680e20146103ae57600080fd5b8063b4359143116100c8578063b435914314610342578063bb6e75de14610355578063bbfe3a321461036857600080fd5b80638da5cb5b146102fc578063946824cd1461031c5780639a0fae9b1461032f57600080fd5b80634938a3fe1161015057806378b5a87a1161012a57806378b5a87a146102c35780637a9e5e4b146102d65780638b098db3146102e957600080fd5b80634938a3fe14610235578063520479421461025557806366b382ee146102b057600080fd5b8063247608071161018157806324760807146101f657806327507458146101ff5780633adec5a71461022257600080fd5b806306b40ea3146101a857806313af4035146101ce5780631c063a6c146101e3575b600080fd5b6101bb6101b6366004611c24565b610430565b6040519081526020015b60405180910390f35b6101e16101dc366004611c50565b610461565b005b6101bb6101f1366004611c6d565b61056a565b6101bb60025481565b61021261020d366004611c6d565b610613565b60405190151581526020016101c5565b6101bb610230366004611c6d565b6106b5565b610248610243366004611c86565b61071a565b6040516101c59190611cbb565b61028b610263366004611c6d565b60009081526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c5565b6101e16102be366004611c50565b610a96565b61028b6102d1366004611c6d565b610c4c565b6101e16102e4366004611c50565b610cea565b6102126102f7366004611c6d565b610e47565b60005461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101bb61032a366004611c6d565b610eac565b6101bb61033d366004611cff565b610f11565b6101bb610350366004611d50565b6111ba565b610248610363366004611d89565b611317565b610248610376366004611d50565b6113f6565b6101bb610389366004611dab565b61177c565b60015461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101bb6103bc366004611c24565b611835565b61028b6103cf366004611c6d565b611851565b6101bb6103e2366004611de4565b611888565b61028b6103f5366004611c6d565b60056020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61024861042b366004611e17565b611939565b6006602052816000526040600020818154811061044c57600080fd5b90600052602060002001600091509150505481565b61048f336000357fffffffff0000000000000000000000000000000000000000000000000000000016611aee565b6104fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b6000818152600560205260408082205490517f1c063a6c0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190631c063a6c906024015b602060405180830381865afa1580156105e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e45565b9392505050565b6000818152600560205260408082205490517f275074580000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169081906327507458906024015b602060405180830381865afa158015610691573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e5e565b6000818152600560205260408082205490517f3adec5a70000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190633adec5a7906024016105cb565b6060600080845b848110156108a057600081815260056020526040908190205490517f275074580000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff90911692508290632750745890602401602060405180830381865afa1580156107a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cc9190611e5e565b801561087f57506040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8089169190841690636352211e90602401602060405180830381865afa158015610843573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108679190611e7b565b73ffffffffffffffffffffffffffffffffffffffff16145b156108905761088d83611ec7565b92505b61089981611ec7565b9050610721565b5060008267ffffffffffffffff8111156108bc576108bc611eff565b6040519080825280602002602001820160405280156108e5578160200160208202803683370190505b50600093509050855b85811015610a8b57600081815260056020526040908190205490517f275074580000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff90911693508390632750745890602401602060405180830381865afa158015610975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109999190611e5e565b8015610a4c57506040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff808a169190851690636352211e90602401602060405180830381865afa158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a349190611e7b565b73ffffffffffffffffffffffffffffffffffffffff16145b15610a7b5780828581518110610a6457610a64611f2e565b6020908102919091010152610a7884611ec7565b93505b610a8481611ec7565b90506108ee565b509695505050505050565b610ac4336000357fffffffff0000000000000000000000000000000000000000000000000000000016611aee565b610b2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016104f1565b73ffffffffffffffffffffffffffffffffffffffff811660009081526004602052604090205460ff1615610ba2576040517fcba9dee200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104f1565b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff9093167fffffffffffffffffffffffff00000000000000000000000000000000000000009093168317905560009182526004602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055565b60008181526005602090815260408083205481517f9787d107000000000000000000000000000000000000000000000000000000008152915173ffffffffffffffffffffffffffffffffffffffff909116928392639787d10792600480830193928290030181865afa158015610cc6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190611e7b565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610dcd57506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff0000000000000000000000000000000000000000000000000000000016604482015273ffffffffffffffffffffffffffffffffffffffff9091169063b700961390606401602060405180830381865afa158015610da9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcd9190611e5e565b610dd657600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b6000818152600560205260408082205490517f8b098db30000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116908190638b098db390602401610674565b6000818152600560205260408082205490517f946824cd0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff90911690819063946824cd906024016105cb565b600080610f1e87876113f6565b805190915060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818080805b868110156111a85760056000898381518110610f6957610f69611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508173ffffffffffffffffffffffffffffffffffffffff1663acc5570c898381518110610fd057610fd0611f2e565b60200260200101516040518263ffffffff1660e01b8152600401610ff691815260200190565b60c060405180830381865afa158015611013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110379190611f5d565b9098509650600093505050635dba240065ffffffffffff871611159050611066578465ffffffffffff16611078565b61107865ffffffffffff861642611fe5565b90508a811161119757838c11611197578273ffffffffffffffffffffffffffffffffffffffff1663bf48582b8e8b85815181106110b7576110b7611f2e565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015260006044820152606401602060405180830381865afa92505050801561115c575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261115991810190611e45565b60015b1561119757878111801561117057508c8110155b156111955780975089838151811061118a5761118a611f2e565b602002602001015196505b505b506111a181611ec7565b9050610f4b565b50929c9b505050505050505050505050565b3360009081526004602052604081205460ff16611203576040517f8feeaaa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316158061123a575073ffffffffffffffffffffffffffffffffffffffff8216155b15611271576040517f018c362a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060028054600081815260056020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905573ffffffffffffffffffffffffffffffffffffffff8781168452600683528184208054600181810183559186528486200186905590871684526007835290832080549182018155835290822001829055825491929161130d90611ec7565b9091555092915050565b60606000835b8381101561134f5761132e81610613565b1561133f5761133c82611ec7565b91505b61134881611ec7565b905061131d565b5060008167ffffffffffffffff81111561136b5761136b611eff565b604051908082528060200260200182016040528015611394578160200160208202803683370190505b50600092509050845b848110156113ed576113ae81610613565b156113dd57808284815181106113c6576113c6611f2e565b60209081029190910101526113da83611ec7565b92505b6113e681611ec7565b905061139d565b50949350505050565b60606000611405846001611939565b90506000806000808451905060005b81811015611585576005600087838151811061143257611432611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692508273ffffffffffffffffffffffffffffffffffffffff1663acc5570c87838151811061149957611499611f2e565b60200260200101516040518263ffffffff1660e01b81526004016114bf91815260200190565b60c060405180830381865afa1580156114dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115009190611f5d565b5050895190975061152d9350899250849150811061152057611520611f2e565b6020026020010151610613565b801561156457508773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b156115755761157285611ec7565b94505b61157e81611ec7565b9050611414565b5060008467ffffffffffffffff8111156115a1576115a1611eff565b6040519080825280602002602001820160405280156115ca578160200160208202803683370190505b5090506000945060005b8281101561176f57600560008883815181106115f2576115f2611f2e565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1693508373ffffffffffffffffffffffffffffffffffffffff1663acc5570c88838151811061165957611659611f2e565b60200260200101516040518263ffffffff1660e01b815260040161167f91815260200190565b60c060405180830381865afa15801561169c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c09190611f5d565b50508a519098506116e093508a9250849150811061152057611520611f2e565b801561171757508873ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b1561175f5786818151811061172e5761172e611f2e565b602002602001015182878151811061174857611748611f2e565b602090810291909101015261175c86611ec7565b95505b61176881611ec7565b90506115d4565b5098975050505050505050565b6000828152600560205260408082205490517fbf48582b000000000000000000000000000000000000000000000000000000008152600481018690526024810185905273ffffffffffffffffffffffffffffffffffffffff848116604483015290911690819063bf48582b90606401602060405180830381865afa158015611808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182c9190611e45565b95945050505050565b6007602052816000526040600020818154811061044c57600080fd5b6003818154811061186157600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000828152600560205260408082205490517fc7bf8ca00000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff848116602483015290911690819063c7bf8ca090604401602060405180830381865afa15801561190d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119319190611e45565b949350505050565b6060808261196b5773ffffffffffffffffffffffffffffffffffffffff84166000908152600760205260409020611991565b73ffffffffffffffffffffffffffffffffffffffff841660009081526006602052604090205b8054806020026020016040519081016040528092919081815260200182805480156119db57602002820191906000526020600020905b8154815260200190600101908083116119c7575b505050505090506000808251905060005b81811015611a2a57611a0984828151811061152057611520611f2e565b15611a1a57611a1783611ec7565b92505b611a2381611ec7565b90506119ec565b5060008267ffffffffffffffff811115611a4657611a46611eff565b604051908082528060200260200182016040528015611a6f578160200160208202803683370190505b5090506000925060005b82811015610a8b57611a9685828151811061152057611520611f2e565b15611ade57848181518110611aad57611aad611f2e565b6020026020010151828581518110611ac757611ac7611f2e565b6020908102919091010152611adb84611ec7565b93505b611ae781611ec7565b9050611a79565b60015460009073ffffffffffffffffffffffffffffffffffffffff168015801590611bd257506040517fb700961300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b700961390606401602060405180830381865afa158015611bae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd29190611e5e565b80611931575060005473ffffffffffffffffffffffffffffffffffffffff85811691161491505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c2157600080fd5b50565b60008060408385031215611c3757600080fd5b8235611c4281611bff565b946020939093013593505050565b600060208284031215611c6257600080fd5b813561060c81611bff565b600060208284031215611c7f57600080fd5b5035919050565b600080600060608486031215611c9b57600080fd5b8335611ca681611bff565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611cf357835183529284019291840191600101611cd7565b50909695505050505050565b600080600080600060a08688031215611d1757600080fd5b8535611d2281611bff565b94506020860135611d3281611bff565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215611d6357600080fd5b8235611d6e81611bff565b91506020830135611d7e81611bff565b809150509250929050565b60008060408385031215611d9c57600080fd5b50508035926020909101359150565b600080600060608486031215611dc057600080fd5b83359250602084013591506040840135611dd981611bff565b809150509250925092565b60008060408385031215611df757600080fd5b823591506020830135611d7e81611bff565b8015158114611c2157600080fd5b60008060408385031215611e2a57600080fd5b8235611e3581611bff565b91506020830135611d7e81611e09565b600060208284031215611e5757600080fd5b5051919050565b600060208284031215611e7057600080fd5b815161060c81611e09565b600060208284031215611e8d57600080fd5b815161060c81611bff565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ef857611ef8611e98565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060008060008060c08789031215611f7657600080fd5b8651611f8181611bff565b6020880151909650611f9281611bff565b6040880151909550611fa381611bff565b6060880151909450611fb481611bff565b608088015190935065ffffffffffff81168114611fd057600080fd5b8092505060a087015190509295509295509295565b60008219821115611ff857611ff8611e98565b50019056fea2646970667358221220ba286c6d6ce9c50ea976df0013cb65eb875fdf24af038e02dcb81b114cf03fd864736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14
-----Decoded View---------------
Arg [0] : guardian_ (address): 0x007BD11FCa0dAaeaDD455b51826F9a015f2f0969
Arg [1] : authority_ (address): 0x007A0F48A4e3d74Ab4234adf9eA9EB32f87b4b14
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000007bd11fca0daaeadd455b51826f9a015f2f0969
Arg [1] : 000000000000000000000000007a0f48a4e3d74ab4234adf9ea9eb32f87b4b14
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.