Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Execute Orders | 18466521 | 825 days ago | IN | 0 ETH | 0.01418281 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60a06040 | 18436115 | 830 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
LimitOrders
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 100000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
/// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.15;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {Auth, Authority} from "solmate/auth/Auth.sol";
import {TransferHelper} from "src/lib/TransferHelper.sol";
import {FullMath} from "src/lib/FullMath.sol";
import {IBondAggregator} from "src/interfaces/IBondAggregator.sol";
import {IBondAuctioneer} from "src/interfaces/IBondAuctioneer.sol";
import {IBondTeller} from "src/interfaces/IBondTeller.sol";
contract LimitOrders is Auth {
using TransferHelper for ERC20;
using FullMath for uint256;
/* ========== EVENTS ========== */
event OrderExecuted(bytes32 digest);
event OrderCancelled(bytes32 digest);
event OrderReinstated(bytes32 digest);
/* ========== ERRORS ========== */
error LimitOrders_NotAuthorized();
error LimitOrders_OrderExpired(uint256 deadline);
error LimitOrders_MarketClosed(uint256 marketId);
error LimitOrders_AlreadyExecuted(bytes32 digest);
error LimitOrders_OrderCancelled(bytes32 digest);
error LimitOrders_InvalidUpdate();
error LimitOrders_InvalidFee(uint256 fee, uint256 maxFee);
error LimitOrders_InvalidSignature(bytes signature);
error LimitOrders_InvalidParams();
error LimitOrders_InvalidUser();
/* ========== STATE ========== */
struct Order {
uint256 marketId;
address recipient;
address referrer;
uint256 amount;
uint256 minAmountOut;
uint256 maxFee;
uint256 submitted;
uint256 deadline;
address user;
}
enum Status {
Open,
Executed,
Cancelled
}
IBondAggregator public immutable aggregator;
uint256 public chainId;
bytes32 internal domainSeparator;
bytes32 internal constant ORDER_TYPEHASH =
keccak256(
"Order(uint256 marketId,address recipient,address referrer,uint256 amount,uint256 minAmountOut,uint256 maxFee,uint256 submitted,uint256 deadline,address user)"
);
mapping(bytes32 => Status) public orderStatus;
/* ========== CONSTRUCTOR ========== */
constructor(IBondAggregator aggregator_, Authority authority_) Auth(address(0), authority_) {
aggregator = aggregator_;
chainId = block.chainid;
domainSeparator = computeDomainSeparator();
}
/* ========== ORDER EXECUTION ========== */
function executeOrders(
Order[] calldata orders_,
bytes[] calldata signatures_,
uint256[] calldata fees_
) external requiresAuth {
uint256 len = orders_.length;
if (len != fees_.length || len != signatures_.length) revert LimitOrders_InvalidParams();
for (uint256 i; i < len; ) {
_executeOrder(orders_[i], signatures_[i], fees_[i]);
unchecked {
++i;
}
}
}
function executeOrder(
Order calldata order_,
bytes calldata signature_,
uint256 fee_
) external requiresAuth {
_executeOrder(order_, signature_, fee_);
}
function _executeOrder(
Order calldata order_,
bytes calldata signature_,
uint256 fee_
) internal {
// Validate order
bytes32 digest = _validateOrder(order_, signature_);
// Validate that the order has not expired
if (order_.deadline < block.timestamp) revert LimitOrders_OrderExpired(order_.deadline);
// Validate that the market is still active
if (!aggregator.isLive(order_.marketId)) revert LimitOrders_MarketClosed(order_.marketId);
// Validate that the order has not already been executed
// and that the user has not cancelled the order
Status status = orderStatus[digest];
if (status == Status.Executed) revert LimitOrders_AlreadyExecuted(digest);
if (status == Status.Cancelled) revert LimitOrders_OrderCancelled(digest);
// Confirm that executor fee is within bounds and calculate amount minus fee
if (fee_ > order_.maxFee) revert LimitOrders_InvalidFee(fee_, order_.maxFee);
uint256 amount = order_.amount - fee_;
// Mark the order as executed
orderStatus[digest] = Status.Executed;
// Get max amount accepted for market
uint256 maxAccepted = aggregator.maxAmountAccepted(order_.marketId, order_.referrer);
// Set the amount for the purchase as the lesser of the order amount and the max accepted
uint256 minAmountOut = order_.minAmountOut;
if (amount > maxAccepted) {
// If amount is too large, set to max accepted
amount = maxAccepted;
// We need to convert the new amount to an equivalent payout amount
// The minAmountOut represents the price the user is willing to pay per token
// after the max fee is taken out.
if (minAmountOut != 0) {
uint256 scale = aggregator.marketScale(order_.marketId);
uint256 maxPrice = (order_.amount - order_.maxFee).mulDiv(
scale,
order_.minAmountOut
);
minAmountOut = amount.mulDiv(scale, maxPrice);
}
}
// Transfer tokens from user to this contract for the purchase
IBondAuctioneer auctioneer = aggregator.getAuctioneer(order_.marketId);
(, , , ERC20 quoteToken, , ) = auctioneer.getMarketInfoForPurchase(order_.marketId);
quoteToken.safeTransferFrom(order_.user, address(this), amount + fee_);
// Approve teller to spend token
IBondTeller teller = auctioneer.getTeller();
quoteToken.safeApprove(address(teller), amount);
// Execute purchase
teller.purchase(order_.recipient, order_.referrer, order_.marketId, amount, minAmountOut);
// Transfer fee to executor
quoteToken.safeTransfer(msg.sender, fee_);
// Emit event for off-chain service to pick up
emit OrderExecuted(digest);
}
function _validateOrder(
Order calldata order_,
bytes calldata signature_
) internal view returns (bytes32) {
// Validate the user is not the zero address (must do this to avoid bypassing the signer check)
// Although, transfers from the zero address would later fail in _executeOrder, so it may not be necessary
if (order_.user == address(0)) revert LimitOrders_InvalidUser();
if (signature_.length != 65) revert LimitOrders_InvalidSignature(signature_);
// Get order digest
bytes32 digest = getDigest(order_);
// Validate signature
bytes32 r = bytes32(signature_[0:32]);
bytes32 s = bytes32(signature_[32:64]);
uint8 v = uint8(signature_[64]);
address signer = ecrecover(digest, v, r, s);
if (signer != order_.user) revert LimitOrders_InvalidSignature(signature_);
return digest;
}
function getDigest(Order calldata order_) public view returns (bytes32) {
return
keccak256(
abi.encodePacked(
hex"1901",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
ORDER_TYPEHASH,
order_.marketId,
order_.recipient,
order_.referrer,
order_.amount,
order_.minAmountOut,
order_.maxFee,
order_.submitted,
order_.deadline,
order_.user
)
)
)
);
}
/* ========== USER FUNCTIONS ========== */
function cancelOrder(Order calldata order_) external {
// Validate that the sender is the order "user"
if (msg.sender != order_.user) revert LimitOrders_NotAuthorized();
// Validate that the order has not expired (no need to cancel if so)
if (order_.deadline < block.timestamp) revert LimitOrders_OrderExpired(order_.deadline);
// Get order digest
bytes32 digest = getDigest(order_);
// Validate that the order has not already been executed
// and that the user has not cancelled the order
if (orderStatus[digest] != Status.Open) revert LimitOrders_InvalidUpdate();
// Set order status to cancelled
orderStatus[digest] = Status.Cancelled;
// Emit event to pick up with off-chain service
emit OrderCancelled(digest);
}
function reinstateOrder(Order calldata order_) external {
// Validate that the sender is the order "user"
if (msg.sender != order_.user) revert LimitOrders_NotAuthorized();
// Validate that the order has not expired
if (order_.deadline < block.timestamp) revert LimitOrders_OrderExpired(order_.deadline);
// Get order digest
bytes32 digest = getDigest(order_);
// Validate that the order is currently cancelled
if (orderStatus[digest] != Status.Cancelled) revert LimitOrders_InvalidUpdate();
// Set the order status as open
orderStatus[digest] = Status.Open;
}
/* ========== DOMAIN SEPARATOR ========== */
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == chainId ? domainSeparator : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256("Bond Protocol Limit Orders"),
keccak256("v1.0.0"),
block.chainid,
address(this)
)
);
}
function updateDomainSeparator() external {
require(block.chainid != chainId, "DOMAIN_SEPARATOR_ALREADY_UPDATED");
chainId = block.chainid;
domainSeparator = computeDomainSeparator();
}
}// 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-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;
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");
// }
}// 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
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;
}{
"remappings": [
"ds-test/=lib/ds-test/src/",
"solmate/=lib/solmate/src/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"clones/=lib/clones-with-immutable-args/src/",
"forge-std/=lib/forge-std/src/",
"solidity-code-metrics/=node_modules/solidity-code-metrics/",
"clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
"hardhat/=node_modules/hardhat/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"weird-erc20/=lib/solmate/lib/weird-erc20/src/"
],
"optimizer": {
"enabled": true,
"runs": 100000
},
"metadata": {
"useLiteralContent": false,
"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 IBondAggregator","name":"aggregator_","type":"address"},{"internalType":"contract Authority","name":"authority_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"LimitOrders_AlreadyExecuted","type":"error"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"}],"name":"LimitOrders_InvalidFee","type":"error"},{"inputs":[],"name":"LimitOrders_InvalidParams","type":"error"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"LimitOrders_InvalidSignature","type":"error"},{"inputs":[],"name":"LimitOrders_InvalidUpdate","type":"error"},{"inputs":[],"name":"LimitOrders_InvalidUser","type":"error"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"LimitOrders_MarketClosed","type":"error"},{"inputs":[],"name":"LimitOrders_NotAuthorized","type":"error"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"LimitOrders_OrderCancelled","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"LimitOrders_OrderExpired","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":false,"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"OrderCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"OrderExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"OrderReinstated","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":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aggregator","outputs":[{"internalType":"contract IBondAggregator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"uint256","name":"submitted","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"internalType":"struct LimitOrders.Order","name":"order_","type":"tuple"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"uint256","name":"submitted","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"internalType":"struct LimitOrders.Order","name":"order_","type":"tuple"},{"internalType":"bytes","name":"signature_","type":"bytes"},{"internalType":"uint256","name":"fee_","type":"uint256"}],"name":"executeOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"uint256","name":"submitted","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"internalType":"struct LimitOrders.Order[]","name":"orders_","type":"tuple[]"},{"internalType":"bytes[]","name":"signatures_","type":"bytes[]"},{"internalType":"uint256[]","name":"fees_","type":"uint256[]"}],"name":"executeOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"uint256","name":"submitted","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"internalType":"struct LimitOrders.Order","name":"order_","type":"tuple"}],"name":"getDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"orderStatus","outputs":[{"internalType":"enum LimitOrders.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"uint256","name":"submitted","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"internalType":"struct LimitOrders.Order","name":"order_","type":"tuple"}],"name":"reinstateOrder","outputs":[],"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"},{"inputs":[],"name":"updateDomainSeparator","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b50604051620025193803806200251983398101604081905262000034916200019f565b600080546001600160a01b03199081168255600180549091166001600160a01b0384161790556040518290829033907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908390a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350506001600160a01b038216608052466002556200017a604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f9718f7897be4857a1c4db401bfbda0cdc8360f3aa819b459203ddc8a51bf046d918101919091527f15124d26d1272f8d4d5266a24ca397811f414b8cd05a53b26b745f63af5ae2fc60608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60035550620001de9050565b6001600160a01b03811681146200019c57600080fd5b50565b60008060408385031215620001b357600080fd5b8251620001c08162000186565b6020840151909250620001d38162000186565b809150509250929050565b608051612303620002166000396000818161010901528181610e6b015281816110850152818161119b015261128701526123036000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063816fae771161008c5780639a8a0592116100665780639a8a05921461020f578063bf7e214f14610218578063dc9cde9014610238578063ef734c881461024b57600080fd5b8063816fae77146101d457806389ccfe89146101e75780638da5cb5b146101ef57600080fd5b80633644e515116100c85780633644e51514610185578063501724001461019b5780636dfdff1a146101ae5780637a9e5e4b146101c157600080fd5b806313af4035146100ef578063245a7bfc146101045780632dff692d14610155575b600080fd5b6101026100fd366004611d58565b61025e565b005b61012b7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610178610163366004611d75565b60046020526000908152604090205460ff1681565b60405161014c9190611dbd565b61018d610367565b60405190815260200161014c565b6101026101a9366004611e17565b610426565b6101026101bc366004611e34565b610580565b6101026101cf366004611d58565b610626565b61018d6101e2366004611e17565b610783565b6101026108d3565b60005461012b9073ffffffffffffffffffffffffffffffffffffffff1681565b61018d60025481565b60015461012b9073ffffffffffffffffffffffffffffffffffffffff1681565b610102610246366004611f0d565b6109ef565b610102610259366004611e17565b610b45565b61028c336000357fffffffff0000000000000000000000000000000000000000000000000000000016610cd6565b6102f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b6000600254461461041f5761041a604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f9718f7897be4857a1c4db401bfbda0cdc8360f3aa819b459203ddc8a51bf046d918101919091527f15124d26d1272f8d4d5266a24ca397811f414b8cd05a53b26b745f63af5ae2fc60608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b5060035490565b61043861012082016101008301611d58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461049c576040517fd269887400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428160e0013510156104e0576040517f15deed9500000000000000000000000000000000000000000000000000000000815260e082013560048201526024016102ee565b60006104eb82610783565b9050600260008281526004602052604090205460ff16600281111561051257610512611d8e565b14610549576040517fcc4da24c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600090815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b6105ae336000357fffffffff0000000000000000000000000000000000000000000000000000000016610cd6565b610614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102ee565b61062084848484610de9565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061070957506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff0000000000000000000000000000000000000000000000000000000016604482015273ffffffffffffffffffffffffffffffffffffffff9091169063b700961390606401602060405180830381865afa1580156106e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107099190611fd6565b61071257600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b600061078d610367565b7fee6d67b4f9cc8f0b2d8f722a450a03cc8283e7395eb38633d51e03342081899d83356107c06040860160208701611d58565b6107d06060870160408801611d58565b6060870135608088013560a089013560c08a013560e08b01356107fb6101208d016101008e01611d58565b60408051602081019b909b528a019890985273ffffffffffffffffffffffffffffffffffffffff96871660608a0152948616608089015260a088019390935260c087019190915260e08601526101008501526101208401521661014082015261016001604051602081830303815290604052805190602001206040516020016108b69291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b600254460361093e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f444f4d41494e5f534550415241544f525f414c52454144595f5550444154454460448201526064016102ee565b466002556109ea604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f9718f7897be4857a1c4db401bfbda0cdc8360f3aa819b459203ddc8a51bf046d918101919091527f15124d26d1272f8d4d5266a24ca397811f414b8cd05a53b26b745f63af5ae2fc60608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600355565b610a1d336000357fffffffff0000000000000000000000000000000000000000000000000000000016610cd6565b610a83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102ee565b848181141580610a935750808414155b15610aca576040517f84853dcc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610b3b57610b33888883818110610aea57610aea611ff8565b90506101200201878784818110610b0357610b03611ff8565b9050602002810190610b159190612027565b878786818110610b2757610b27611ff8565b90506020020135610de9565b600101610acd565b5050505050505050565b610b5761012082016101008301611d58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bbb576040517fd269887400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428160e001351015610bff576040517f15deed9500000000000000000000000000000000000000000000000000000000815260e082013560048201526024016102ee565b6000610c0a82610783565b90506000808281526004602052604090205460ff166002811115610c3057610c30611d8e565b14610c67576040517fcc4da24c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600217905590518281527f5152abf959f6564662358c2e52b702259b78bac5ee7842a0f01937e670efcc7d910160405180910390a15050565b60015460009073ffffffffffffffffffffffffffffffffffffffff168015801590610dba57506040517fb700961300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b700961390606401602060405180830381865afa158015610d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dba9190611fd6565b80610ddf575060005473ffffffffffffffffffffffffffffffffffffffff8581169116145b9150505b92915050565b6000610df68585856115c9565b9050428560e001351015610e3c576040517f15deed9500000000000000000000000000000000000000000000000000000000815260e086013560048201526024016102ee565b6040517f27507458000000000000000000000000000000000000000000000000000000008152853560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632750745890602401602060405180830381865afa158015610ec7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eeb9190611fd6565b610f24576040517f08c51810000000000000000000000000000000000000000000000000000000008152853560048201526024016102ee565b60008181526004602052604090205460ff166001816002811115610f4a57610f4a611d8e565b03610f84576040517f9396c312000000000000000000000000000000000000000000000000000000008152600481018390526024016102ee565b6002816002811115610f9857610f98611d8e565b03610fd2576040517f1616126a000000000000000000000000000000000000000000000000000000008152600481018390526024016102ee565b8560a0013583111561101d576040517f8776a2030000000000000000000000000000000000000000000000000000000081526004810184905260a087013560248201526044016102ee565b600061102d8460608901356120bb565b600084815260046020526040902080549192506001917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682800217905550600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663c7bf8ca089356110bc60608c0160408d01611d58565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925273ffffffffffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa15801561112b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114f91906120d2565b90506080880135818311156112555781925080600014611255576040517f946824cd000000000000000000000000000000000000000000000000000000008152893560048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063946824cd90602401602060405180830381865afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b91906120d2565b90506000611243828c608001358d60a001358e6060013561123c91906120bb565b91906117cf565b90506112508583836117cf565b925050505b6040517f52047942000000000000000000000000000000000000000000000000000000008152893560048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690635204794290602401602060405180830381865afa1580156112e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130791906120eb565b6040517facc5570c0000000000000000000000000000000000000000000000000000000081528b35600482015290915060009073ffffffffffffffffffffffffffffffffffffffff83169063acc5570c9060240160c060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190612123565b505093505050506113e48b6101000160208101906113ba9190611d58565b306113c58b8961219b565b73ffffffffffffffffffffffffffffffffffffffff851692919061189b565b60008273ffffffffffffffffffffffffffffffffffffffff16639787d1076040518163ffffffff1660e01b8152600401602060405180830381865afa158015611431573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145591906120eb565b905061147873ffffffffffffffffffffffffffffffffffffffff83168288611a37565b8073ffffffffffffffffffffffffffffffffffffffff16636de5b4cd8d60200160208101906114a79190611d58565b8e60400160208101906114ba9190611d58565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9283166004820152911660248201528e356044820152606481018990526084810187905260a40160408051808303816000875af1158015611540573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156491906121b3565b50611588905073ffffffffffffffffffffffffffffffffffffffff8316338b611ba7565b6040518881527fc0688adab4193f84179a2fda51c33be35f0be04eda978b688bb1a41ce2c7e8469060200160405180910390a1505050505050505050505050565b6000806115de61012086016101008701611d58565b73ffffffffffffffffffffffffffffffffffffffff160361162b576040517fd697e28f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604182146116695782826040517f256d83e50000000000000000000000000000000000000000000000000000000081526004016102ee9291906121df565b600061167485610783565b90506000611685602082868861222c565b61168e91612256565b905060006116a060406020878961222c565b6116a991612256565b90506000868660408181106116c0576116c0611ff8565b604080516000808252602082018084528a9052949092013560f81c908201819052606082018790526080820186905293506001915060a0016020604051602081039080840390855afa15801561171a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151915061175890506101208a016101008b01611d58565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146117c05787876040517f256d83e50000000000000000000000000000000000000000000000000000000081526004016102ee9291906121df565b509293505050505b9392505050565b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870985870292508281108382030391505080600003611826576000841161181b57600080fd5b5082900490506117c8565b80841161183257600080fd5b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161193a9190612292565b6000604051808303816000865af19150503d8060008114611977576040519150601f19603f3d011682016040523d82523d6000602084013e61197c565b606091505b50915091508180156119a65750805115806119a65750808060200190518101906119a69190611fd6565b80156119c9575060008673ffffffffffffffffffffffffffffffffffffffff163b115b611a2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064016102ee565b505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691611ace9190612292565b6000604051808303816000865af19150503d8060008114611b0b576040519150601f19603f3d011682016040523d82523d6000602084013e611b10565b606091505b5091509150818015611b3a575080511580611b3a575080806020019051810190611b3a9190611fd6565b611ba0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c454400000000000000000000000000000000000060448201526064016102ee565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691611c3e9190612292565b6000604051808303816000865af19150503d8060008114611c7b576040519150601f19603f3d011682016040523d82523d6000602084013e611c80565b606091505b5091509150818015611caa575080511580611caa575080806020019051810190611caa9190611fd6565b8015611ccd575060008573ffffffffffffffffffffffffffffffffffffffff163b115b611ba0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016102ee565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5557600080fd5b50565b600060208284031215611d6a57600080fd5b81356117c881611d33565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310611df8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006101208284031215611e1157600080fd5b50919050565b60006101208284031215611e2a57600080fd5b6117c88383611dfe565b6000806000806101608587031215611e4b57600080fd5b611e558686611dfe565b935061012085013567ffffffffffffffff80821115611e7357600080fd5b818701915087601f830112611e8757600080fd5b813581811115611e9657600080fd5b886020828501011115611ea857600080fd5b9598602092909201975094956101400135945092505050565b60008083601f840112611ed357600080fd5b50813567ffffffffffffffff811115611eeb57600080fd5b6020830191508360208260051b8501011115611f0657600080fd5b9250929050565b60008060008060008060608789031215611f2657600080fd5b863567ffffffffffffffff80821115611f3e57600080fd5b818901915089601f830112611f5257600080fd5b813581811115611f6157600080fd5b8a602061012083028501011115611f7757600080fd5b602092830198509650908801359080821115611f9257600080fd5b611f9e8a838b01611ec1565b90965094506040890135915080821115611fb757600080fd5b50611fc489828a01611ec1565b979a9699509497509295939492505050565b600060208284031215611fe857600080fd5b815180151581146117c857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261205c57600080fd5b83018035915067ffffffffffffffff82111561207757600080fd5b602001915036819003821315611f0657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156120cd576120cd61208c565b500390565b6000602082840312156120e457600080fd5b5051919050565b6000602082840312156120fd57600080fd5b81516117c881611d33565b805165ffffffffffff8116811461211e57600080fd5b919050565b60008060008060008060c0878903121561213c57600080fd5b865161214781611d33565b602088015190965061215881611d33565b604088015190955061216981611d33565b606088015190945061217a81611d33565b925061218860808801612108565b915060a087015190509295509295509295565b600082198211156121ae576121ae61208c565b500190565b600080604083850312156121c657600080fd5b825191506121d660208401612108565b90509250929050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000808585111561223c57600080fd5b8386111561224957600080fd5b5050820193919092039150565b80356020831015610de3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b6000825160005b818110156122b35760208186018101518583015201612299565b818111156122c2576000828501525b50919091019291505056fea26469706673582212206cfa9ee5c0c9e78600b4353963d93432999c234b193d9347ce01a434b75153b864736f6c634300080f0033000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d1000000000000000000000000007a2f0a16bd0874ca2e1fffafc2d6b0b876aa8e
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063816fae771161008c5780639a8a0592116100665780639a8a05921461020f578063bf7e214f14610218578063dc9cde9014610238578063ef734c881461024b57600080fd5b8063816fae77146101d457806389ccfe89146101e75780638da5cb5b146101ef57600080fd5b80633644e515116100c85780633644e51514610185578063501724001461019b5780636dfdff1a146101ae5780637a9e5e4b146101c157600080fd5b806313af4035146100ef578063245a7bfc146101045780632dff692d14610155575b600080fd5b6101026100fd366004611d58565b61025e565b005b61012b7f000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610178610163366004611d75565b60046020526000908152604090205460ff1681565b60405161014c9190611dbd565b61018d610367565b60405190815260200161014c565b6101026101a9366004611e17565b610426565b6101026101bc366004611e34565b610580565b6101026101cf366004611d58565b610626565b61018d6101e2366004611e17565b610783565b6101026108d3565b60005461012b9073ffffffffffffffffffffffffffffffffffffffff1681565b61018d60025481565b60015461012b9073ffffffffffffffffffffffffffffffffffffffff1681565b610102610246366004611f0d565b6109ef565b610102610259366004611e17565b610b45565b61028c336000357fffffffff0000000000000000000000000000000000000000000000000000000016610cd6565b6102f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b6000600254461461041f5761041a604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f9718f7897be4857a1c4db401bfbda0cdc8360f3aa819b459203ddc8a51bf046d918101919091527f15124d26d1272f8d4d5266a24ca397811f414b8cd05a53b26b745f63af5ae2fc60608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b5060035490565b61043861012082016101008301611d58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461049c576040517fd269887400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428160e0013510156104e0576040517f15deed9500000000000000000000000000000000000000000000000000000000815260e082013560048201526024016102ee565b60006104eb82610783565b9050600260008281526004602052604090205460ff16600281111561051257610512611d8e565b14610549576040517fcc4da24c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600090815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b6105ae336000357fffffffff0000000000000000000000000000000000000000000000000000000016610cd6565b610614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102ee565b61062084848484610de9565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061070957506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff0000000000000000000000000000000000000000000000000000000016604482015273ffffffffffffffffffffffffffffffffffffffff9091169063b700961390606401602060405180830381865afa1580156106e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107099190611fd6565b61071257600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b600061078d610367565b7fee6d67b4f9cc8f0b2d8f722a450a03cc8283e7395eb38633d51e03342081899d83356107c06040860160208701611d58565b6107d06060870160408801611d58565b6060870135608088013560a089013560c08a013560e08b01356107fb6101208d016101008e01611d58565b60408051602081019b909b528a019890985273ffffffffffffffffffffffffffffffffffffffff96871660608a0152948616608089015260a088019390935260c087019190915260e08601526101008501526101208401521661014082015261016001604051602081830303815290604052805190602001206040516020016108b69291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b600254460361093e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f444f4d41494e5f534550415241544f525f414c52454144595f5550444154454460448201526064016102ee565b466002556109ea604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f9718f7897be4857a1c4db401bfbda0cdc8360f3aa819b459203ddc8a51bf046d918101919091527f15124d26d1272f8d4d5266a24ca397811f414b8cd05a53b26b745f63af5ae2fc60608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600355565b610a1d336000357fffffffff0000000000000000000000000000000000000000000000000000000016610cd6565b610a83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102ee565b848181141580610a935750808414155b15610aca576040517f84853dcc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610b3b57610b33888883818110610aea57610aea611ff8565b90506101200201878784818110610b0357610b03611ff8565b9050602002810190610b159190612027565b878786818110610b2757610b27611ff8565b90506020020135610de9565b600101610acd565b5050505050505050565b610b5761012082016101008301611d58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bbb576040517fd269887400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428160e001351015610bff576040517f15deed9500000000000000000000000000000000000000000000000000000000815260e082013560048201526024016102ee565b6000610c0a82610783565b90506000808281526004602052604090205460ff166002811115610c3057610c30611d8e565b14610c67576040517fcc4da24c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600217905590518281527f5152abf959f6564662358c2e52b702259b78bac5ee7842a0f01937e670efcc7d910160405180910390a15050565b60015460009073ffffffffffffffffffffffffffffffffffffffff168015801590610dba57506040517fb700961300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b700961390606401602060405180830381865afa158015610d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dba9190611fd6565b80610ddf575060005473ffffffffffffffffffffffffffffffffffffffff8581169116145b9150505b92915050565b6000610df68585856115c9565b9050428560e001351015610e3c576040517f15deed9500000000000000000000000000000000000000000000000000000000815260e086013560048201526024016102ee565b6040517f27507458000000000000000000000000000000000000000000000000000000008152853560048201527f000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d173ffffffffffffffffffffffffffffffffffffffff1690632750745890602401602060405180830381865afa158015610ec7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eeb9190611fd6565b610f24576040517f08c51810000000000000000000000000000000000000000000000000000000008152853560048201526024016102ee565b60008181526004602052604090205460ff166001816002811115610f4a57610f4a611d8e565b03610f84576040517f9396c312000000000000000000000000000000000000000000000000000000008152600481018390526024016102ee565b6002816002811115610f9857610f98611d8e565b03610fd2576040517f1616126a000000000000000000000000000000000000000000000000000000008152600481018390526024016102ee565b8560a0013583111561101d576040517f8776a2030000000000000000000000000000000000000000000000000000000081526004810184905260a087013560248201526044016102ee565b600061102d8460608901356120bb565b600084815260046020526040902080549192506001917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682800217905550600073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d11663c7bf8ca089356110bc60608c0160408d01611d58565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925273ffffffffffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa15801561112b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114f91906120d2565b90506080880135818311156112555781925080600014611255576040517f946824cd000000000000000000000000000000000000000000000000000000008152893560048201526000907f000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d173ffffffffffffffffffffffffffffffffffffffff169063946824cd90602401602060405180830381865afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b91906120d2565b90506000611243828c608001358d60a001358e6060013561123c91906120bb565b91906117cf565b90506112508583836117cf565b925050505b6040517f52047942000000000000000000000000000000000000000000000000000000008152893560048201526000907f000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d173ffffffffffffffffffffffffffffffffffffffff1690635204794290602401602060405180830381865afa1580156112e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130791906120eb565b6040517facc5570c0000000000000000000000000000000000000000000000000000000081528b35600482015290915060009073ffffffffffffffffffffffffffffffffffffffff83169063acc5570c9060240160c060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190612123565b505093505050506113e48b6101000160208101906113ba9190611d58565b306113c58b8961219b565b73ffffffffffffffffffffffffffffffffffffffff851692919061189b565b60008273ffffffffffffffffffffffffffffffffffffffff16639787d1076040518163ffffffff1660e01b8152600401602060405180830381865afa158015611431573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145591906120eb565b905061147873ffffffffffffffffffffffffffffffffffffffff83168288611a37565b8073ffffffffffffffffffffffffffffffffffffffff16636de5b4cd8d60200160208101906114a79190611d58565b8e60400160208101906114ba9190611d58565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9283166004820152911660248201528e356044820152606481018990526084810187905260a40160408051808303816000875af1158015611540573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156491906121b3565b50611588905073ffffffffffffffffffffffffffffffffffffffff8316338b611ba7565b6040518881527fc0688adab4193f84179a2fda51c33be35f0be04eda978b688bb1a41ce2c7e8469060200160405180910390a1505050505050505050505050565b6000806115de61012086016101008701611d58565b73ffffffffffffffffffffffffffffffffffffffff160361162b576040517fd697e28f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604182146116695782826040517f256d83e50000000000000000000000000000000000000000000000000000000081526004016102ee9291906121df565b600061167485610783565b90506000611685602082868861222c565b61168e91612256565b905060006116a060406020878961222c565b6116a991612256565b90506000868660408181106116c0576116c0611ff8565b604080516000808252602082018084528a9052949092013560f81c908201819052606082018790526080820186905293506001915060a0016020604051602081039080840390855afa15801561171a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151915061175890506101208a016101008b01611d58565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146117c05787876040517f256d83e50000000000000000000000000000000000000000000000000000000081526004016102ee9291906121df565b509293505050505b9392505050565b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85870985870292508281108382030391505080600003611826576000841161181b57600080fd5b5082900490506117c8565b80841161183257600080fd5b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161193a9190612292565b6000604051808303816000865af19150503d8060008114611977576040519150601f19603f3d011682016040523d82523d6000602084013e61197c565b606091505b50915091508180156119a65750805115806119a65750808060200190518101906119a69190611fd6565b80156119c9575060008673ffffffffffffffffffffffffffffffffffffffff163b115b611a2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064016102ee565b505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691611ace9190612292565b6000604051808303816000865af19150503d8060008114611b0b576040519150601f19603f3d011682016040523d82523d6000602084013e611b10565b606091505b5091509150818015611b3a575080511580611b3a575080806020019051810190611b3a9190611fd6565b611ba0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c454400000000000000000000000000000000000060448201526064016102ee565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691611c3e9190612292565b6000604051808303816000865af19150503d8060008114611c7b576040519150601f19603f3d011682016040523d82523d6000602084013e611c80565b606091505b5091509150818015611caa575080511580611caa575080806020019051810190611caa9190611fd6565b8015611ccd575060008573ffffffffffffffffffffffffffffffffffffffff163b115b611ba0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016102ee565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5557600080fd5b50565b600060208284031215611d6a57600080fd5b81356117c881611d33565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310611df8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006101208284031215611e1157600080fd5b50919050565b60006101208284031215611e2a57600080fd5b6117c88383611dfe565b6000806000806101608587031215611e4b57600080fd5b611e558686611dfe565b935061012085013567ffffffffffffffff80821115611e7357600080fd5b818701915087601f830112611e8757600080fd5b813581811115611e9657600080fd5b886020828501011115611ea857600080fd5b9598602092909201975094956101400135945092505050565b60008083601f840112611ed357600080fd5b50813567ffffffffffffffff811115611eeb57600080fd5b6020830191508360208260051b8501011115611f0657600080fd5b9250929050565b60008060008060008060608789031215611f2657600080fd5b863567ffffffffffffffff80821115611f3e57600080fd5b818901915089601f830112611f5257600080fd5b813581811115611f6157600080fd5b8a602061012083028501011115611f7757600080fd5b602092830198509650908801359080821115611f9257600080fd5b611f9e8a838b01611ec1565b90965094506040890135915080821115611fb757600080fd5b50611fc489828a01611ec1565b979a9699509497509295939492505050565b600060208284031215611fe857600080fd5b815180151581146117c857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261205c57600080fd5b83018035915067ffffffffffffffff82111561207757600080fd5b602001915036819003821315611f0657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156120cd576120cd61208c565b500390565b6000602082840312156120e457600080fd5b5051919050565b6000602082840312156120fd57600080fd5b81516117c881611d33565b805165ffffffffffff8116811461211e57600080fd5b919050565b60008060008060008060c0878903121561213c57600080fd5b865161214781611d33565b602088015190965061215881611d33565b604088015190955061216981611d33565b606088015190945061217a81611d33565b925061218860808801612108565b915060a087015190509295509295509295565b600082198211156121ae576121ae61208c565b500190565b600080604083850312156121c657600080fd5b825191506121d660208401612108565b90509250929050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000808585111561223c57600080fd5b8386111561224957600080fd5b5050820193919092039150565b80356020831015610de3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b6000825160005b818110156122b35760208186018101518583015201612299565b818111156122c2576000828501525b50919091019291505056fea26469706673582212206cfa9ee5c0c9e78600b4353963d93432999c234b193d9347ce01a434b75153b864736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d1000000000000000000000000007a2f0a16bd0874ca2e1fffafc2d6b0b876aa8e
-----Decoded View---------------
Arg [0] : aggregator_ (address): 0x007A66A2a13415DB3613C1a4dd1C942A285902d1
Arg [1] : authority_ (address): 0x007A2F0A16bd0874CA2e1FFfAfc2d6B0b876aA8E
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000007a66a2a13415db3613c1a4dd1c942a285902d1
Arg [1] : 000000000000000000000000007a2f0a16bd0874ca2e1fffafc2d6b0b876aa8e
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.